2012-08-08 09:30 AM
I have some PLC .cpp source/header files that I want to port over to my micro code that uses linked lists and what not. I noticed that main is a c file as is the rest of the stm320xx std periph drivers.
Can I use c++ src/inc files and call those functions from main.c? Do I have to make main.c into main.cpp? Is this just asking for trouble and i should implement an array/struct solution instead of using linked lists?2012-08-08 09:45 AM
I'm not a C++ guy, although I can follow along well enough to understand whats happening.
You should be able to mix-n-match, just watch for the name mangling that C++ does, and the calling conventions. I would definitely leave the library and main in C if I could. One of the other things to watch is that C++ wants to allocate memory at run time, which gets a lot more complicated in systems with finite resources, and embedded.2012-08-09 04:20 PM
Note that linked lists don't have to be dynamically allocated...
2012-08-11 01:42 AM
Use the
extern ''C''
construct to selectively turn off the C++ name mangling. You use this in your C++ code to create hooks that straight C code can call. If C++ is to call C code, then the declaration that C++ sees should include extern ''C''.That takes care of most of the issues. You'll probably want to turn off exceptions and RTTI too, but that's more of a command line switch than anything you do in the source code. Lastly, C++ compilers spit out static initialization code that your linker script and startup code will need to know about.It takes a little bit of effort to get things going the first time, but it's very easy after that, and letting the compiler generate your static initialization code is much nicer than doing it by hand.And linked lists are especially tasty in C++ ...http://getoffmylawnentertainment.com/blog/2011/05/18/the-curiously-recurring-template-pattern/2012-08-18 01:32 PM
@turk.andy
'' Lastly, C++ compilers spit out static initialization code that your linker script and startup code will need to know about.'' Can you give an example of this? And how to do it. much appreciated Tim
2012-08-18 08:55 PM
In GNU/GCC you call __libc_init_array prior to calling main.
/* Call static constructors */ bl __libc_init_array or something akin to/* Call C++ constructors */
LDR r0, =__ctors_start__
LDR r1, =__ctors_end__
ctor_loop:
CMP r0, r1
BEQ ctor_end
LDR r2, [r0], #4
STMFD sp!, {r0-r1}
MOV lr, pc
MOV pc, r2
LDMFD sp!, {r0-r1}
B ctor_loop
ctor_end:
which calls the individual constructor functions.
Now in a PC system you'd also have the complementary destructors, but embedded systems are not designed to exit.
Although a bit dated this might provide some background
http://www.state-machine.com/arm/Building_bare-metal_ARM_with_GNU.pdf
http://newlib.sourcearchive.com/documentation/1.0/init_8c-source.html
.text :
{
..
KEEP(*(.init))
*(.text .text.*)
KEEP(*(.fini))
*(.gcc_except_table)
} >FLASH
. = ALIGN(4);
/* .ctors .dtors are used for c++ constructors/destructors */
.ctors :
{
PROVIDE(__ctors_start__ = .);
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(__ctors_end__ = .);
} >FLASH
.dtors :
{
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
} >FLASH
2012-08-19 09:14 PM
Thanks for the reply clive1, and the documentation.
2012-08-20 10:59 AM
Clive1 got it right, as usual. You don't *need* assembly though. Here's a simple reset handler in C++ that does the same thing: http://pastebin.com/wvcZUzPL