Channels ▼

Al Williams

Dr. Dobb's Bloggers

Embedded Goes to Shell

November 27, 2014

Last time I showed you how I have been using shell scripts to orchestrate some simple embedded systems on small Linux platforms like the Raspberry Pi. By manipulating the PATH, the prompt, and providing some custom scripts, I converted the standard Linux shell (bash) into a specialized programming language that can control a serial I/O board.

The reality is, I should have made at least some of the custom scripts actual C programs. I wanted to try to do it all in bash script just to see if I could. The shell isn't all that great at handling the serial port. In particular, you can have trouble receiving data. You might also have trouble sending or receiving a character with a value of 0 (a NULL byte). However, for the purposes of what I wanted to do, these limitations weren't a problem.

The simplest case is when the script sends some characters to the board with no feedback. Remember, the startup script used sty to set the serial port's baud rate and other parameters. So the only issue is sending a very specific sequence of hex bytes to the serial port. Here's the ledon script:

echo –en '\xd' >$PORT

The echo command is a common fixture in scripts. However, normally the echo command issues a new line at the end of what you want to send. In this case, though, you don't want anything except exactly the bytes you specify. That's what the –n option does. It suppresses the normal newline. The PORT variable is set by the startup script and all the command scripts assume it is set.

The -e option causes echo to interpret special escape characters. There are several recognized (you can look them up), but the one we care about is the \x escape character, which allows you to specify a hex byte. In this case, 0D hex is the command to turn the board's built-in LED on.

Many of the other scripts look about the same, but have different bytes to send. But what about data coming the other way? The board accepts a command to read one of 8 input bits and — conveniently — returns an ASCII 0 or 1 based on the input's state.

The trick is that you have to have the port open for reading before you send the command or else the system will toss the input to the closed port. That takes a bit of bizarre scripting:

BITS=$(( (16+$1)*2+1))      # compute command
HBITS=$(printf %x $BITS)  # convert to hex
# Here's the tricky part
( sleep .2 ; printf \\x $HBITS >$PORT ) &
read –rn 1 <$PORT IBTYE
echo $IBYTE

This is a bit of a hack. The script detaches a subshell (the & at the end of the tricky line) and makes it wait 200 milliseconds. By then the read on the next line should be running and waiting for input. If you had a very slow computer, you might need to adjust that time. The read is waiting for a single byte and the printf (an alternative to echo) sends out the hex byte to the port. When the board responds, the read completes and IBYTE should have an ASCII 0 or 1 in it.

Truthfully, I don't mean to suggest resorting to this kind of a hack. But it does demonstrate that the shell can do a lot of things you might not guess. If you aren't convinced, take a look on GitHub. However, many (or all) of the commands could have been C programs. There's still plenty of value in using the shell to orchestrate those commands into their final task.

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.