Travails of a Newly-Embedded TDDer

17 06 2012

So, as someone who has done a lot of building and repair of things strictly electrical, but who has done practically nothing having to do with analog or digital electronic hardware, I’ve taken delivery of an Arduino microcontroller board and have been playing around with it.  I’ve got a fairly decent breadboard, a set of wire jumpers, and a mess of resistors, capacitors, and LEDs.   I’ve put together several meaningless toy “devices,” ranging from a program that just repeatedly blinked “Shave And a Hair-cut, Two Bits” on an on-board LED to one that sequenced green outboard LEDs until you pulled a particular pin low, at which point it would sequence red outboard LEDs until you let the pin go, at which point it would go back to sequencing the green LEDs.

But as a TDD, I’m beginning to feel really, really crowded by the difficulty of test-driving embedded microcontroller code.  I just happened to find a bug in one of my programs that happened because I was refactoring without tests; if I had not just happened across it, there’s no reliable way I could have found it without tests.

So I’m thinking: If I could wish into existence whatever I wanted to support my Arduino development, what would I wish?

At first I thought, hey, this isn’t so hard.  Arduino provides me with a C library full of API calls like pinMode(), that sets a pin to input or output mode, digitalWrite(), that sets an output pin high or low, analogRead(), that reads a value from one of the ADC pins, and so on.  All I have to do is write an instrumented static-mock version of that library.  When I want to run tests, I can compile the microcontroller code for my development machine instead of for the microcontroller, link in my static mock instead of the Arduino library, and run tests with Google Test.  I can set up the static mock so that I can attach prerecorded “analog” signals (essentially sequences of floating-point numbers) to particular input pins, and attach “recorder” objects to particular output pins.  In the Assert portion of the tests, I can examine the recordings and make sure they recorded what should have happened.

But then I thought about timing.  Timing’s real important to microcontrollers.  For example, suppose I wanted to test-drive handling of the situation when an interrupt is received while a value is being written to EEPROM.  How am I going to arrange the input signal on the interrupt pin so that it changes state exactly at the right time during the run of the code under test?  Without access to the hardware on which that code is running, how do I even simulate an interrupt at all?

Now I’m thinking I need to write a complete software emulator of the microcontroller–keeping the idea of prerecording input signals and recording output signals during the test, and having asserts to compare them, but with debugger-like awareness of just what’s executing in the test: for example, you could have prerecorded signals where the numbers weren’t just numbers, but could be tagged with clock cycle counts or time delays, or even with something like “Fire this sample the third time execution passes address XXXX with memory location XXXX set to XXXX.”

There is at least one software emulator in existence for my microcontroller–the AVR ATmega2560–but it doesn’t offer the kind of control that a TDD (this one, anyway) would want.

But I’m thinking there’s got to be an easier way.

Advertisements

Actions

Information

3 responses

30 04 2016
Christopher J. McClellan

How is this endeavor going for you? I’m also interested in the embedded world (I have an AT-Xmega myself) and as much as I love Atmel’s emulator/IDE, I find doing TDD on this stuff awkward at best too. I’d be interested in hearing more about the project.

30 04 2016
Dan Wiebe

It’s taught me quite a bit, but I was distracted from it by a coworker who has demonstrated the _real_ way to test embedded projects. It’s not unit testing, but it works better. He uses a separate microcontroller board to inject and detect signals in the board under test, and drives it with tests written in whatever language falls easiest to hand.

This way, you can do real-world testing, which is more important than simulation testing, and you can test your whole circuit, not just the firmware.

So I probably won’t do much more on Simulino (https://github.com/dnwiebe/Simulino), but you’re welcome to fork it and carry on if you like. It’s got a pretty good suite of tests.

30 04 2016
Christopher J. McClellan

Thanks, I’ll try to find some time to check it out. Embedded is a bit of a hobby, nothing I do professionally. The test board concept is interesting as well. Thanks again!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: