Electronic – Writing one program for different microcontrollers

cprogramming

I got 2 totally different microcontrollers (one is 16-bit MSP and another 32-bit nordic). They are supposed to do the same task and I thought that maybe it would be posible to write one program in C language and then use different compilers while programming them. I got some common xxx.h files with different source implementations for each device so part of the code would look exactly the same. The difference is when it comes to writing internal registers and that part of code has to be various for each device so I tought about introducing some macro that would point which microcontroller I want to compile code for. Then I would be able to use #ifdef directive inside source files to carry conditional compilation. I have no experience with such programming so I need some tips, is it good idea or is it better to write one program for each microcontroller ?

Best Answer

The trick is to define an interface that gives you access to the I/O pins (or other peripherals and functionality that you need, and maybe a delay functions). Declare this interface in a .h file. Now write your application in one or more .c files that use this .h file. Write two .c files, one for each platfom, that implement the interface for that particular platform. When you build for one platform, compile and link with the correct implementation .c file.

A possible .h file:

bool pin_read( unsigned char pin );
void pin_write( unsigned char pin, bool value );
void configure_pin_as_input(  unsigned char pin );
void configure_pin_as_output(  unsigned char pin );
void delay_us( unsigned int t );

This approach does not require any preprocessor trickery, but its does impose a function call overhead on each access to a platform-specific function. If this is not acceptable, you could implement both interfaces as macro's in the .h file (using #ifdefs to select between them).

Another trick is to stick with the .h/.c approach, but to compile all application code with the implementation.c included, and rely on the optimizer to eliminate the function call overhead. This requires two different 'main' files, one for the 16-bit target

// main.c for MSP430
#include "interface.h"
#include "msp430-interface.c"
#include "application.c"

and one for the other target

// main.c for Cortex-M0
#include "interface.h"
#include "CortexM0-interface.c"
#include "application.c"

Personally I prefer C++ to tackle such problems, and I essentialy use the last approach, which is quite normal for C++ template-based programming (templates must be in the .h file). (See this article and this video for my approach)