I am challenged (on so many levels! :-)). I write code in C# and C++ on PCs running Windows. This makes it easy to practice TDD and write unit tests for my new code.
The large legacy code-base is something else entirely, but we’re making (slow) progress. Life is good…on windows.

I also happen to write code for embedded 8-bit micro-controllers, hence my challenge. How does one write unit tests for the embedded code?

Some of the code is all in assembly, so clearly it does not lend itself to unit tests. Some of the programs are really small and do a simple job, but others are significant in size (over 5,000 LOC). The only way I have come up to perform unit testing is to create a windows unit testing application and suck in the embedded code. This works reasonably well, but there are a few stumbling blocks:

Hardware Specific Libraries

Micro-controllers are somewat different from your regular run of the mill Pentium. In addition to the processor core, they have a number of “peripherals”: integrated serial interface, Analog-to-Digital converters, Input-Output pins, etc… Compiler vendors often provide libraries which allow you to interface with the peripherals without having to resort to using assembly code. For example, input(PIN_A2) would return the logic state (1 or 0) of pin A2. If we simply attempt to compile such code on windows, the compiler will complain loudly. At a minimum, you need to provide stubs; ideally you would want to emulate some of the hardware (e.g. serial port)

Assembly & non-standard compilers

Sometimes, you simply need to set a specific register to control something. The easiest way to do this is a single line of assembly code: IOE spo, 0x2E. All compilers targeting embedded systems provide a way to generate inline assembly (yes, even GCC). The problem is, Visual C++ does not like that! Unfortunately, in those cases, you are usually relegated to using conditional compiles. Sometimes life is just like that.

A related problem is the compiler vendors who have a “mostly” C compiler, but make it replete with non-standard extensions. The best (worst?) example of this is Z-World’s Dynamic C. It does not have #include statements, they are #use. Functions are declared with a special type of comment. The C compiler has been exended to use “costate” (a simple form of multi-tasking). This can make it just about impossible to include the normal code in a windows application. If you are serious about testing your code, you might just have to resort to cut & paste. Not something pleasant!

I’d like your opinion on this. Is there a better way to unit test embedded code? Am I going off the deep end wanting to unit test embedded code?

P.S.

If you are an embedded engineer, and have no idea what I’m bleating about, visit the following:

Test Driven Development

  • James Newkirks’ blog (Creator of NUnit)
  • Steve Eichert’s blog
  • Roy Osherove’s blog(I’m not stalking you Roy! I won’t write about you in my next post, I promise!)

Actually, go see Darrell Norton’s blog entry on TDD resource. It’s all there!

One thing you must realize is that a lot of the TDD & Unit Testing material on the web is rooted in a Java heritage, and as such assumes the language provides certain facilities (reflexion, object orientation, etc…). This does not hold true (very often) in an embedded environment. Such is the plight of the embedded engineer…we truly are the Sons of Martha.