Embedded System Design Library: Simplicity

(C) 2009 Hank Wallace

PREVIOUS – Embedded System Design Library: Fate
NEXT – Embedded System Design Library: Agile Methods

This series of articles concerns embedded systems design and programming, and how to do it with excellence, whether you are new to the discipline or a veteran. This article is about keeping designs simple.

I’ve written some large programs, and programs that live within networks of devices sometimes separated by hundreds of miles where it’s costly to upgrade anything or even retrieve a unit for failure analysis. This makes it very important to keep everything as simple as possible because complexity breeds error.

There are products that are loaded with so much functionality that they are for all purposes muscle bound. Every time a program crashes on my Windows PC, the OS calls the modern incarnation of that Dr. Watson abomination. Not only does the program crash, but the CPU wastes several minutes copying a 500MB memory image to disk. I finally found the Dr. Watson executable (or whatever it’s called these days) and deleted it. The information it provides is useless, as if Microsoft would actually take that and fix their OS!

Embedded programs get loaded with as much junk, such as bootloaders and test routines. The architecture of some systems gives us no choice at times, but most of the time we have a choice for a simpler solution.

Does your system have some spare memory? Instead of writing a full blown bootloader, the application can accept a new firmware image, write it into memory, then invoke a simpler programming routine that copies the image from memory to flash. There is no communications capability in the programming routine, simplifying it considerably. There may be no need at all for a separate bootloader application.

The trend these days is to use canned operating systems to do the most basic tasks. One does not need Windows CE or a full RTOS to do simple data collection. In fact, you likely do not need an OS at all! Instead of starting with the assumption that your embedded system will have a web server, why not start with a blank sheet of paper and write down the things your system actually does need? Ethernet is nice, but if you can do the job for half the money and time, why not?

Products and development processes have become very much overcomplicated in the past decade. The very notion of “embedded Windows” is a total oxymoron. Use of Windows in an embedded system totally negates the benefits of economy and reliability we associate with the word ’embedded’. How many CE installations are there under the hood of a vehicle? How many in medical devices? How many in critical military gear? Let’s pray not many.

If you don’t need all that junk, don’t install it!

Keeping things simple also acts to stem the tide of feature creep. Say you have a product with a USB port for communications. If there is an unused Ethernet port, and a Bluetooth module, and another USB port, and a couple spare serial ports, before you know it you’ll have everything accessible on every port. The cost and complexity of that does not rise linearly, but exponentially!

Resist the urge to over-design. For any given function, simpler is always better.

Another issue in simplification concerns documentation. An undocumented software or hardware design is instantly and impossibly complex. A properly documented design is a joy to work with.

Do you document your work as you go, or put that off until all the fires are out at the end of the project (as if that ever happens)? If you do your abstract thinking up front, and write the details down, then a load of your documentation will be complete when you release the product to production. Always write to an imagined engineer or technician who is only basically familiar with the product, so he or she does not have to dig for hours to understand why, for example, you added those two NOPs to each function call (which I actually had to do on a PIC/Hi-Tech project once).

But please, PLEASE, do not overdo it! (Warning: Economics rant ahead.) I inherited one program recently where the programmer recreated diagrams from the data book using ASCII character blocks. There are hundreds of lines of register diagrams with little X’s showing how the bits were set in each register. Why on earth would I refer to that, which certainly has typos beyond the typos in the typical data sheet, and certainly does not currently reflect the state of the registers?

* And it frustrates me when I read a program which I have paid *  
* a subcontractor to write that contains comments of this form,*   
* with elaborately constructed banners, tables and graphs, all *  
* done in ASCII! If you are writing C, just use one of these:  *  
* "/*", type your comment, then use one of these: "*/". Nobody *  
* ever won a Pulitzer Prize by coding comments.                *  
* Economics RULES!                                             *  

When writing a program, you might create functions that are later deleted from the product specification. Do you leave that code in the product? You should not. Every line of code can be a field problem. Even if you #if it out, the next programmer in your chair will wonder, “what was that for?” I ask my programmers to remove any extraneous code from the final program. If you have test routines, stuff them into a separate file and archive them, with a note in the source. Nothing is more maddening than reading a program that is loaded with “#if EXTENDED_CODE_BASE” types of conditionals. Extended from what? Who needed that? What did it do? Is it tested? Why was it removed?

Don’t be stupid. Keep it simple!

Author Biography

Hank Wallace is the owner of Atlantic Quality Design, Inc., a consulting firm located in Fincastle, Virginia. He has experience in many areas of embedded software and hardware development, and system design. See www.aqdi.com for more information.