Search code examples
c++cembeddediar

How to correctly start a C and C++ IAR embedded project?


I am currently working on an embedded project for the stm32f3. In this project I want to use both .cpp and .c files: The C files are for the UART/I2C... initialisation files while the C++ ones are for a more object oriented solution. Therefore I really need to keep both of them. My question is how to make it work properly? I have seen a few answer on the web but it all seem very confusing to me.

I already had a project with uart.c/h files inside a C++ project (the board was working just fine), but as I added a i2c.c/h files to the project, a lot of linkage errors appeared.

Example = Error[Li005]: no definition for "I2C_StructInit" [referenced from C:\Users\IAR Embedded Workbench\STM32F3-Discovery_FW_V1.1.0\Project\I2C Interface CPU\Debug\Obj\i2c.o]

Should the main be a C or C++ file?

Should I use Language\Auto in the project setting, or specify for each file to compile in C or C++ ?

When do I need to use extern "C"?

I am using IAR Embedded Workbench IDE. Any other advices are welcome.


Solution

  • I'm not familiar with this platform, but the problems sound pretty general.

    Should the main be a C or C++ file?

    C++ would be the safer choice because main relates to program initialization, and C++ implements dynamic initialization unlike C.

    When do I need to use extern "C"?

    This is important, and a likely source of your problem. You need extern "C" to decorate every declaration used in C++ whose definition is provided in C.

    If your C headers lack extern "C", you can in a pinch add it for them:

    extern "C" {
    #include "i2c.h"
    }
    

    Putting a #include directive inside anything is generally a very bad idea, but this is relatively harmless because extern "C" {} doesn't introduce a new, nested declarative scope, aside from modifying the linkage of declarations contained within.

    As Mine suggests, you could also modify the header files to contain extern "C" when compiling in C++ mode. My advice is based on the idea that modifying a library is the greater evil. In my experience, embedded drivers may be dynamically generated for the platform, or in any case you might move later to a slightly different platform. You should use the idiom in that answer for your own headers, but personally I'd avoid editing i2c.h at all costs.