Mar 11, 2012

Is TDD one of the solutions for difficulty of concurrent development of software and hardware?

In my 5 year experience of embedded software engineer, I became to think concurrent development of software and hardware is the biggest risk of embedded systems. I thinks TDD is one of the solutions for the problem. So I held a book club of "Test Driven Development for Embedded C (Pragmatic Programmers)" in Tokyo. Here is my thought on how we fight with difficulty of  concurrent development of software and hardware.

Writing code for uncompleted hardware is so hard : (

General process of embedded software development is as follows:
  1. Developing software on own computer
  2. Debugging on an evaluation board
  3. Testing on a target hardware
At the first step, we don't have the target hardware and have to write code for imaginary hardware that we have never seen. After we got the evaluation board, which is the second step, we try to debug on it to find bugs.

Most of engineers that I have met try to debugging on an evaluation board as quickly as possible, so they tend not to care about testability for unit test. As a result, we get high coupling code.

At the time, we have to advance the development with several risks as follows:
  • Own computer, evaluation board and target hardware have a little bit different library and compiler.
  • The evaluation board is bad in quality at the beginning of the development.
  • There are many mistakes in logic of code
  • Software engineer has to resolve underlying discrepancy in specification at the end of development.
  • etc.
Problems occur someday. They make debugging time longer and distinguishing cause of bugs more difficult.

If we do agile software development for embedded software system, this will be a bottleneck.

Dual-Target Testing

For this problem, the author of "Test Driven Development for Embedded C (Pragmatic Programmers)" recommend hardware-independent software design and unit test on both of own computer and evaluation board from the beginning. This is called "Dual-Target Testing". If we do it from the beginning, we can eliminate bugs and make test easier.

What do we need for Dual-Target Tesing

At first, we need software design techniques to make software more testable. That is discussed in the books like "Test Driven Development: By Example" written by Kent-Beck or "Working Effectively with Legacy Code" written by Michael Feathers.

Second, we need cooperation with hardware engineers for low layer software development. For example, in the book of "Test-Driven Development for Embedded C ", there is a scene that software engineer and hardware engineer are discussing about design of interface between software and hardware so that software engineer can decide design of Test Double.

What "Test-Driven Development for Embedded C" is doing for this?

There are some code examples in my github. There is product code and test code for LED driver.

Key point of this example is a dependency injection at a constructor. Passing writing port address to constructor makes software independent with hardware. We can do unit test on both of own computer and the evaluation board.

This driver has writing port only. State of LED driver is stored at variable ledsImage once, then write to the port. This was an issue that software engineer and hardware engineer discussed in the book.

You might think that this example is quite simple and there are more difficult examples in real world. I think basic idea is the same as this example, which is interface design between software and hardware and low coupling software design against hardware and other software modules.

I will held the third monthly meeting of "Test Driven Development for Embedded C" book club in Tokyo and see this problem deeply : )

No comments:

Post a Comment