Channels ▼

Al Williams

Dr. Dobb's Bloggers

Stupid Beagle Tricks, Part 1

June 12, 2012

In my last post, I discussed how you can light LEDs and work with I/O on many different flavors of embedded Linux boards, including the BeagleBone. If you are like me, you find it strange to shift gears and think of applying Linux paradigms to embedded systems, but as the price of these types of systems drops, it is going to be more and more common to attack problems with small Linux computers instead of tiny microcontrollers. Naturally, when speed, power, or cost are super important, you might have to program down to the bare metal. But then you are less likely to be using Linux anyway.

Beagle, by the way, ships with the Cloud9 IDE and lets you write JavaScript and several other languages in a web browser. I never got that to work very reliably, although it did work some of the time. It is still a good example of what I mean, though. You'd never think of building a JavaScript IDE in a host-based browser if you were building what I usually think of as an embedded system. But on Linux, why not?

Consider a common enough task: controlling a remote output over the network. For example, you might have a valve that you'd like to turn on and off from anywhere. To make it interesting, my goal is to flash an output to send CQ via Morse code (if you don't know Morse code, you can consider it just some pattern of flashing lights).

If I didn't have Linux, I'd have to think about getting the board on the network to start with. There are many options for that, of course, and plenty of TCP/IP stacks to choose from. Then I'd probably write a simple socket program that listened on some port and would accept some kind of protocol to control the I/O.

If I change my mindset to think about Linux, I can do a lot better than that. Since I talked about LEDs last time, I'm going to stick with those, but the same principles apply to any sort of I/O device (like the GPIO I talked about before, a serial device, or an analog input).

Of course, you could do exactly the same thing in Linux. You can certainly write a C program, handle a socket, and do whatever you want to do. It is much easier, of course, because you already have a network stack and a well-understood set of calls. You could even get about 99% of it working on a desktop Linux PC and then just do the BeagleBone-specific parts on the board.

My point, though, is that unless you have some special reason for going through all that work, why not make it simpler by leveraging the Linux tools that are already present? Probably the simplest idea would be to use the versatile nc (netcat) program to listen to the socket. This isn't much different from just writing a simple server, but most of the work is already done and you just need a script.

If you haven't used netcat, it is billed as the "Swiss army knife of network tools" and that is a pretty apt description. A full version can listen or send data on a tcp or udp port. The only problem is the Angstrom distribution I'm using has a version from BusyBox and that version does not support network listening. Oops. You can rebuild it with the NC_SERVER flag set, of course. But I was so hoping to keep it simple, and using nc is really not much different from the C version I mentioned.

Here's a simple bash script that would do what I want:

#!/bin/bash
LED=/sys/class/leds/beaglebone::usr0
DOTDELAY=0.1
DASHDELAY=0.3

# Turn off LED automation just in case
echo none >$LED/trigger


function dot {
# Note: The space after 255 (or 0) is important!
echo 255 >$LED/brightness
# Note: GNU Core utilis sleep allows floating point
sleep $DOTDELAY
echo 0 >$LED/brightness
sleep $DOTDELAY

}


function dash {
# Note: The space after 255 (or 0) is important!
echo 255 >$LED/brightness
# Note: GNU Core utilis sleep allows floating point
sleep $DASHDELAY
echo 0 >$LED/brightness
sleep $DOTDELAY
}

function space {
sleep $DASHDELAY
}

function sendC {
dash
dot
dash
dot
}

function sendQ {
dash
dash
dot
dash
}


# Send CQ CQ CQ 
for I in 1 2 3 
do
  sendC
  space
  sendQ
  space
  space
  space
done

That's easy enough, but how do you trigger it over the network? Since it's Linux, you can actually start this with an ssh command (assuming you used the chmod command to set the executable bit on the script). Unless you have fixed the LED permissions, you'll need to be root on the BeagleBone. From the remote computer try:

ssh root@192.168.1.226 /home/alw/morse

Obviously, replace the IP address and file path to suit your setup. You will get a prompt for the root password. It is easy enough to set up the board to use certificates if you were doing this for real (there's plenty of documentation about this on the Web, including http://www.ece.uci.edu/~chou/ssh-key.html).

That's it. Zero software on the remote computer and a simple script on the BeagleBone. Could it be simpler? Actually, yes.

Since I'm not using the built-in IDE, I was stuck using the vi editor on the BeagleBone. Not to start a flame war, but I prefer emacs (and, yes, I know how to use vi). I used sshfs (which is based on FUSE) to map the BeagleBone to an empty directory on my workstation:

mkdir /tmp/beagle
sshfs root@192.168.1.226:/ /tmp/beagle

Now the BeagleBone's filesystem shows up in /tmp/beagle. I can use emacs or any other tool on my workstation to work with the files on the board. If you recall the last set of examples, the LEDs (and all the other I/O) look like files so from the remote computer you could just as easily say:

echo 255 >/tmp/beagle/sys/class/leds/beaglebone\:\:usr0/brightness

Then the whole script could run on the remote computer and there would be no custom code at all on the Beagle.

After years of slinging assembly and C code, I find it a bit breezy to write bash scripts for an embedded system. I'm not done yet, though. Soon I want to talk about device drivers in bash (it is possible, if you'll let me be liberal in my definitions) and how to hide the fact that you are using shell scripts. After all, you don't want to make your job look too easy, do you?

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video