Channels ▼

Al Williams

Dr. Dobb's Bloggers

In Command

November 18, 2014

I've been using UNIX (and Linux) for many years as a desktop and server operating system. But the recent trend to small Linux-based computers like the Raspberry Pi, the Beagleboard, and other similar offerings have made me rethink how I deploy some of my systems. Granted, the real-time projects haven't changed much, but a lot of systems I work with fall more into the physical computing realm than the real-time realm.

If you've used UNIX or Linux from the command line, the idea is pretty smart. Instead of making big complex tools, you make small tools that you can string together using the shell to do powerful things. This idea has resurfaced in recent years as "service orchestration," but it is an old idea that has worked well for UNIX (at least at the command-line level; similar methods for the GUI world like Dbus have not been as ubiquitous).

This approach has lots of advantages. Simple tools are — well — simple. It is much easier to debug a program that's sole purpose is to sort its input, for example, than a giant program that tries to do many things. Another advantage is that simple tools can be combined in many ways to do things you were not even thinking about when you wrote the tools. Making simple changes isn't a big problem as long as you provided enough flexibility in the tools or the changes can be made in the script.

I've been taking this approach in some of my recent embedded projects. I develop a few tools to handle the complex parts and then orchestrate them with the shell script to do the actual task.

I've even gone a step further in some cases. The shell is really just a programming language with an interactive mode. With some fancy scripting, you make a custom command prompt that "understands" your custom system.

The plan is simple:

  1. Create a start up script that is used to launch the new custom shell mode.
  2. In the script, set up a custom path that points to the system's tool scripts and programs.
  3. Set up a custom prompt.
  4. Initialize anything necessary for system operations. This could be external resources or things like aliases or shell functions.
  5. Execute a subshell to provide a command prompt.

To illustrate, I picked up a GP-3 serial board with a USB port. This just provides some simple analog and digital I/O over a common serial port. It has an efficient protocol that is hard to get out of sync. Normally, I would use a library and some C code and just write all the input and output steps that I wanted. But to illustrate the custom shell technique, I wrote a series of shell scripts.

Although I could have managed all the different commands for the board, I only scripted a few. In particular, the commands provided are:

  • help — Print some help text for the other commands
  • high — Set an output high
  • low — set and output low
  • inp — Return 0 or 1 based on selected input
  • toggle — Set high output low or vice versa
  • ledon — Turn on onboard LED
  • ledoff — Turn off onboard LED

Here's the startup script:

#!/bin/bash
export PORT=/dev/ttyUSB0   # could make this a param
DIR=~/projects/gp3sh        # could deduce this
stty -F $PORT clocal -crtscts raw 57600 cs8 -cstopb
export PS1="GP3>"
PATH="$DIR/bin:$PATH"
unset PROMPT_COMMAND # stop things like autojump and fasd
bash norc -i

That's it. The tools all expect PORT to be set (and set up). Here's the ledon script:

#!/bin/bash
echo -en '\xd' >$PORT

That's all. I even considered making it a shell function. Once the startup script executes, you'll see a GP3> prompt and issuing an ledon command will light the LED. You could even write something like the following to give you the canonical blinking light.

while true
do
   ledon
   sleep 1
   ledoff
   sleep 1
done

The only tricky part is how to handle commands like inp that need to read from the port. I'll show you that next time, along with a caveat about why the serial port tools probably ought not to be shell scripts (even though using them for orchestration is still a good idea).

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.