Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Channels ▼

Al Williams

Dr. Dobb's Bloggers

Take It From The Top

June 23, 2014

Embedded systems aren't what they used to be. It wasn't long ago that a developer had to watch every instruction to make the most out of the tiny program storage and relatively low speeds of most processors. Today, even inexpensive processors outstrip a typical PC from a decade ago. You can afford to be a little sloppier unless you are really pushing the envelope.

I think it is more than just the increase in hardware capability, though. The accessibility of large embedded processors with high-level languages has brought a whole new breed of programmers into the embedded arena. Programmers that have a different background and experience.

Java-based processors haven't made the impact I thought they might, but if you count Android as a kind of Java, the impact was far in excess of my expectations. Small boards like the Raspberry Pi and Beagle Board are making it possible to write embedded applications in JavaScript or Python.

If you look at embedded software, it is usually pretty easy to guess if the developer had a hardware background or a "big" software background. I've seen embedded systems over the last few years that use 128-bit Globally Unique Identifiers (GUIDs) and big databases — things you normally see on workstation and server software.

I'm not saying that these are necessarily bad things. It all depends on the problem at hand. But when I see a PIC with a temperature sensor and a heater controller using 14 C++ classes backed up with six pages of UML charts, I have to wonder.

For simple programs, I often turn to a simple top-down design method that Forth was well suited for (even though I rarely use Forth anymore). The idea is to write your top-level program in the form of your high-level requirements (or your use cases, if you prefer). Then you decompose each of the functions into lower and lower level functions until you have something simple enough to just bang out and test.

For example, suppose I need a data logger that will read a few analog inputs every 5 minutes, write the results to EEPROM, and then when a modem carrier detect appears, empty the EEPROM data over a serial port. My main might look like this:

#include "datalog.h"

#define NRCHAN 4    // number of channels to read/store
#define CYCLETIME 300  // cycle time in seconds 

void main()
   while (true)
          if (time_to_acq())
               if (!eeprom_full())
          }  // if (time_to_acq(CYCLETIME)
          if (carrier_detect())
// send until caller acknowledges or hangs up
	  while (!send_receipt() && carrier_detect());
  if (send_receipt())
	  while (carrier_detect());  // after success, wait
          }  // if (carrier_detect())
    }  // while (true)
}  // main

Your tastes in decomposition might be different from mine, but this is reasonably clean and self-documenting (more or less). At this stage, any call to a library function should be off limits. These functions are purely manifestations of your requirements. It is OK to reuse functions (like carrier_detect) where you need the same function in more than one place.

The next step, of course, is to write all the functions you just made up. In some simple cases, these might actually do the task. Or you may decide to just decompose into more made up functions:

void clear_eeprom()

Library calls would be fair game at this level or below. Depending on what you are writing this can be a very productive way to develop. If you need more efficiency, you can always debug using this structure and then simply reduce the number of functions late in the development process.

This is hardly a new idea. You can consider it top-down design. It also has a lot in common with an idea in robotics called subsumption architecture. In Forth, you'd often go the opposite way: Figure out what little primitive operations you needed and then build them up into more complex words (similar to a function) until you had one word "datalog" (or whatever).

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.