views:

598

answers:

4

Although there are plenty of unit test frameworks that support C, I'm a little stumped on how to write unit tests for micro controller code (PIC in my case, but I think the question is more general than that).

Much of the code written for micro controllers revolves around Writing configuration and data values to registers, reading incoming data from registers and responding to interrupt events. I'm wondering if anyone can provide some pointers on the most effective way to this.

A: 

Is there perhaps any kind of loopback mode so that you can use the controller itself to generate events that you can test against?

jerryjvl
+2  A: 

One approach to this might be to use an emulator. I've been working on an AVR emulator and one of the ideas for using it is indeed to unit test code. The emulator implements the CPU and registers, interrupts and various peripherals, and (in my case) bytes written to the emulated UART go to the regular stdout of the emulator. In this way, unit test code can run in the emulator and write its test results to the console.

Of course, one must also ensure that the emulator is correctly implementing the behaviour of the real CPU, otherwise the unit tests on top of that can't be trusted.

Greg Hewgill
+1  A: 
bk1e
+15  A: 

You write;

"Much of the code written for micro controllers revolves around Writing configuration and data values to registers, reading incoming data from registers and responding to interrupt events".

I agree that this is often the case in practice, but I don't actually think this is a good thing, and I think rethinking things a little will help you with your test goals.

Perhaps because microcontroller programmers can reach out and touch the hardware any time they like, many (most?) of them have got into the habit of doing just that, throughout their code. Often this habit is followed unquestioningly, maybe because so many people doing this sort of work are EEs not computer scientists by training and inclination. I know, I started out that way myself.

The point I am trying to make, is that microcontroller projects can and should be well designed like any other software project. A really important part of good design is to restrict the hardware access to hardware drivers! Partition off all the code that writes registers, responds to interrupts etc. into modules that provide the rest of your software with nice, clean, abstracted access to the hardware. Test those driver modules on the target using logic analyzers, oscilloscopes, custom test rigs or whatever else makes sense.

A really important point is that now the rest of your software, hopefully the great majority of it, is now just C code that you can run and test on a host system. On the host system the hardware modules are stubbed out in a way that provides visibility into what the code under test is doing. You can use mainstream unit testing approaches on this code. This needs some preparations and work, but if you are well organized you can create a reusable system that can apply to all your projects. The potential benefits are enormous. I wrote a little more about these ideas here;

[http://discuss.joelonsoftware.com/default.asp?joel.3.530964.12][1]

Bill Forster
Good point. May I add: get used to using uint16_t, uint8_t and so forth (instead of just int, char) so that your types are more predictable when jumping from embedded platform to PC, and also between different embedded platforms.
Craig McQueen