17 Apr 2010, 17:39

Dave Kellogg (27 posts)

Hi James,

I’ve be thinking a lot about what things would make the book more accessible, particularly to the C-only, embedded-only crowd.

One of my conclusions is that it would be very helpful to include a chapter about exactly HOW to do dual-targeting. Dual targeting is a very fundamental underlying assumption needed to support doing TDD on the development PC, and it deserves its own explicit visibility.

For less experienced embedded engineers, HOW to implement dual targeting can be a stumbling block. So explain how to do it, and make dual-targeting accessible by offering practical advice.

Although the book is about TDD for embedded, it depends on dual targeting. And while I’ve read widely, I don’t recall seeing any other resource that dives into explaining how to do dual targeting well. I feel that your book is the place for this explanation.

These are some topics that could be covered: 1. RTOS (Real Time Operating System) calls. In most cases, I suspect that it is not practical (or possible) to port the RTOS to run on the dev PC. Guidance as to the alternatives would be helpful. I suspect that this would involve linker substitution.

  1. Handling #pragmas, particularly those relating to memory layout (ROM, EEPROM, etc.)

  2. Extensions to C required by the embedded compiler. Eg, “@isr” for defining an interrupt service routine. The best that I can think of is some macro magic to expand differently when building for the target vs building for the dev sys. But you may have a better way of doing this.

  3. Non volatile memory, such as EEPROM. I suspect that on the dev sys, this would involve a test double that would read a file representing EEPROM. But again, you may know of strategies that work better.

  4. How to report test results while running tests on the target. In some cases, the target won’t have a serial port. So there must be some other mechanism, such as blink a LED, leave the results in a memory buffer, etc. Somewhere the topic of what needs to be done to port CppUTest to the target should be covered, too.

  5. Designing the production code so that memory-mapped registers (peripherals, timers, I/O, etc.) will work with both the dev sys and the target.

  6. The possibility of using I/O connected to the dev sys as a way of replicating I/O in the embedded target. For instance, using some of the data acquisition devices on market that connect directly to the PC.

  7. The case where there is no Cpp compiler for the embedded target. Is it better to use CppUTest when testing on the dev sys, and something “C” only (you suggest Unity) when running tests on the embedded target. Or is it better to stick with the same framework for both sides of the dual targeting?

  8. C language portability issues. Differing length of int, bit field ordering, size and capability of pointers, etc. Suggest strategies for how to handle these types of things. This would probably include coding standard conventions for new code. (Use size-specific typedefs instead of the raw underlying C types, etc.)

  9. On page 89 - 90 (B1.0), you got into how to handle compiler header files that are different between the two targets. This is really part of the dual-targeting discussion.

  10. Use a library for the production code. Point out that there probably would be two libraries of production code: one generated by the librarian for the dev sys, and one for the librarian for the embedded target.

There is more to this list. But you get the idea. Tell us HOW to do dual porting.

22 May 2010, 01:14

Dave Kellogg (27 posts)

Hi James,

I’m still chewing on the challanges of dual targeting (both PC and enbedded hardware). I’m 100% convinced that it is the right thing to do. It just has a learning curve that some practical advice would help.

Since my first pass through reading Beta 1, I decided to take a run at getting some of my existing embedded C code to be dual targeted to run on my Windows PC. So I needed a compiler. Some browsing convinced me that MinGW is the way to go for a Windows environment. I found a nice prebuild distro so I did not have to compile from sources: see http://nuwen.net/mingw.html. It is current as of a Spring 2010.

Perhaps you could mention link to it in the Dual Targeting chapter / appendix. Having some recommended links to documentation for GCC would also save a person’s time.

In the previous post I suggested packaging the Dual Targeting subject material as a separate chapter.

After further thought, maybe this would be good material for an entirely separate book.

Throw in discussion about Continuous Integration, hardware in-the-loop testing, automating and maintaining dual targets, etc. These are all “just” enablers for doing TTD on an embedded target. But there is very little guidance published to help a person minimize the effort it takes to go from legacy, target-only embedded code to a viable dual-targeted environment.

I attended the Embedded Agile conference in Boston last year, where you and Russel presented a lot of these ideas. I learned a lot at that forum. But it should would be easier if there was a cook-book focused on Dual targeting.

So perhaps a second book oriented toward the mechanics of Dual Targeting would have good reception.

25 May 2010, 03:09

Charles Manning (22 posts)

I’ve pretty much always done DT. Almost all code that is not hardware specific is a candidate for dual targeting.

If you can, don’t just DT. Multi-target. Different compilers give different warnings and different memory footprints and are more likely to shake out bugs.

It might be challenging to retrofit DT to existing code, particularly if it is not clean portable code (eg. pragma, use of non-standard types, and embedding calls to RTOS functions etc). Try to do it in stages…

I almost always start off coding in an simulator application. When the code is solid, and only then, do I try get the code running on a target. I might compile for target once a week or so just to check for things like code size etc.

This approach forces DT. But the main reason I do this is because code dev in a PC application is way faster and with a much richer toolset (memory checkers, better debuggers, MMU,..), infinite resources (well relatively speaking) for logging, graphing variables in real time etc etc.

Apart from the testing benefits you end up with clean code that you can easily reuse. For example, I once wrote a J1939 CAN networking layer this way. The code was intended for use in an embedded micro with an RTOS in a vehicle. But later we also needed the same layer in a PC application for a laptop and also in a diagnostic Windows CE device. Guess what - the code just dropped in and was running in less than a day (most of the time taken up by a meeting discussing how long it would take). Didn’t need to first tease out the RTOS calls etc.

Same deal with the file system I wrote called yaffs. This was developed in an application test harness which is still used as the primary development framework. The code is highly modular and has been used in multiple OSs. I’ll wager that yaffs is used in a wider range of OSs and processors than any other file system code.

I don’t consider DT part of TDD. I’m pretty much always done DT, but very seldom done unit-testing etc. I’m trying to get better :-).

In the old MS-DOS days you could do more with DT. I once made up an ISA-bus plug-in card with the peripherals I was going to have in my embedded board. I got all the code + drivers + pretty much everything running as a PC with a custom plug-in board. Porting to the final hardware was trivial. But those are the good/bad old days….

04 Jun 2010, 22:09

Dave Kellogg (27 posts)

Hi Charles,

Sounds like you are quite experienced with dual targeting for C.
Question: On the PC side, what is your suggested tool chain? Microsoft? GCC?

What suggestions or resources do you have to help with education regarding writing clean, portable code?

I’m using wrapper defines instead of the underlying types (UINT32, SINT16, etc). But I’m more puzzled by how to keep pragmas out of the code, etc.

Since I don’t want to hyjack James’s book discussion forum, perhaps you could contact me directly: dave dot kellogg at RaymondCorp dot com.


07 Jun 2010, 19:35

James Grenning (137 posts)

Feel free to carry on with the conversation here.

For windows, you will probably consider a virtual machine running linux. One client reports 10x speed improvement.

re: pragmas, see if you can corral the code that depends on the target development tools. Minimize and isolate it. then build a replacement file for host based testing.

11 Mar 2014, 20:04

Robert Lee (1 post)

I also am struggling with the Dual/Multiple Targeting. Are there any good books, blog posts, articles that describe the pros / cons of different methods of structuring a project for DT/MT?

21 Apr 2014, 18:40

Richard Hagberg (10 posts)

This is something that I would also be interested in hearing more about. It seems like it is something that is nearly as complex as TDD itself. I am an embedded engineer who has been writing “Firmware” for my whole career, and am more interested in writing software instead, as per one of James blog posts. I am sure I could eventually figure it all out myself, but I’d rather learn from those with experience and even get a discussion going so we could all come up with some best practices. Miro Samek wrote an interesting article on dual targeting and even came up with a win32 GUI toolkit to let you simulate hardware like push buttons and displays. I think it is worth a read if you are interested in DT. Here is a link. http://embeddedgurus.com/state-space/2013/04/dual-targeting-and-agile-prototyping-of-embedded-software-on-windows/

  You must be logged in to comment