cancel
Showing results for 
Search instead for 
Did you mean: 

C++?

lanchon
Associate III
Posted on February 28, 2008 at 16:20

C++?

16 REPLIES 16
lanchon
Associate III
Posted on May 17, 2011 at 12:24

hi!

is anyone using c++ successfully with the stm32? using what tools?

I'm trying to use the latest codesourcery but can't make it work. two problems:

#1. when I include a c++ source file in the build, the injected stack unwinding code indirectly generates these references:

thumb2\libc.a(lib_a-abort.o): In function `abort': abort.c: undefined reference to `_exit'

thumb2\libc.a(lib_a-signalr.o): In function `_getpid_r': signalr.c: undefined reference to `_getpid'

thumb2\libc.a(lib_a-signalr.o): In function `_kill_r': signalr.c: undefined reference to `_kill'

thumb2\libc.a(lib_a-sbrkr.o): In function `_sbrk_r': sbrkr.c: undefined reference to `_sbrk'

I've read something about codesourcery's newlib being built with --disable-newlib-supplied-syscalls, but I don't know why it's built that way, or how to fix this (I'm not familiar with GCC and it's libs at all). for now I've sidestepped the issue by using -fno-exceptions, which avoids the stack unwinding code, but bumped into...

#2. now the the build completes but the program doesn't work on the target. I assume the presence of c++ code forces the selection of a different initialization code, and somehow this new code fails (I'm guessing it might have something to do with the linker script).

no workaround for #2! would someone be able to help me? what info would you need posted? what other tools do work for c++ on the stm32?

thank you very much!

lanchon
Associate III
lanchon
Associate III
Posted on May 17, 2011 at 12:24

update: apparently Ride7 doesn't really want to do c++. after some massaging I got it to build a c++ app, and...

-#1 wasn't an issue, apparently they have some fallback system calls for newlib

-the build didn't work, so #2 keeps on being the show stopper (not really a surprise, since the linker file I'm using comes from Ride7)

...so still blocked...

lanchon
Associate III
Posted on May 17, 2011 at 12:24

to clarify on Ride7, though it builds the app, OpenOCD can't program the chip using the produced ELF. it fails with this error:

Info: configuration.c:50 configuration_output_handler(): failed writing image flash: error reading from image

(this is different from when I build directly with codesourcery, in which case OpenOCD programs ok but the target fails to run.)

I've also tried Anglia's IDEaliST. it's friendly to c++ but the output file has the same problem with OpenOCD if a c++ source is included in the build. (#1 isn't an issue with this IDE.)

seriously, no one's using c++?

lanchon
Associate III
Posted on May 17, 2011 at 12:24

ok, I sort of know what's up with #2, I'll write tomorrow if I find the time.

lanchon
Associate III
Posted on May 17, 2011 at 12:24

I guess noone's working with c++ after all. is anybody interested in me keeping on posting to this thread?

lanchon
Associate III
Posted on May 17, 2011 at 12:24

I'm using these macros to define pointers to bit-band bits:

#define BB_BIT(NAME, REGISTER, BIT_NUMBER, BASE, BB_BASE) static volatile int* const (NAME) = ((int *) ((BB_BASE) + (((int) &(REGISTER)) - (BASE)) * 32 + (BIT_NUMBER) * 4));

#define PERIPHERAL_BIT(NAME, REGISTER, BIT_NUMBER) BB_BIT(NAME, REGISTER, BIT_NUMBER, PERIPH_BASE, PERIPH_BB_BASE)

and using them like this:

PERIPHERAL_BIT(LED, GPIOC->ODR, 12);

void f(void) { *LED = 1; }

this defines ''static volatile int* const'' pointers that should be as efficient as macros. now I don't know the first thing about arm assembler but when the code is compiled as c it's clear that it's optimized and that the bit-band bit address is loaded into r2 as if it were a constant from .L40:

.L38:

ldr r2, .L40

mov r0, #393216

ldr r3, [r2, #0]

eor r3, r3, #1

str r3, [r2, #0]

bl busyWait

b .L38

.L41:

.align 2

.L40:

.word 1109524912

(incidentally, the use of offline constants like .L40 beats the prefetch mechanism; can't it be done any better?)

however when the same code is compiled as c++, it's not optimized:

ldr r3, .L49

ldr r4, [r3, #0]

.L47:

ldr r3, [r4, #0]

mov r0, #393216

eor r3, r3, #1

str r3, [r4, #0]

bl _Z8busyWaiti

b .L47

.L50:

.align 2

.L49:

.word .LANCHOR0

here .L49 holds the address of the pointer pointing to the bit-band bit address (the pointer is called .LANCHOR0 (strangely similar to my nick) and not LED, since it's static).

why the c++ compile is less optimized is anybody's guess. I think there's no good reason for it, could someone comment?

anyway, this means that .LANCHOR0 must be initialized. in c this would be done through the .data section, but in c++ initializations invoke constructors which may have side effects, so copying memory is not sufficient and user code must be run (in the general case). g++ chose to handle this initialization with code, and puts a pointer to the code in section .init_array.

the linker script should dump that section into the flash and init symbols describing it's extent, and the boot code should read that data and invoke the initializers before invoking main. I've never seen a linker script in my life before, but it's clear that mine is not dumping .init_array into the flash, and besides the boot code that comes with the stm32 fwlib wouldn't invoke the initializers either. so that's why the code fails.

being naive, I thought I could simply modify both things so that the list of initializers would get called, but there must be more to it than that. in particular, since a constructor could refer to a global constructed value, how is initialization ordered across compile modules so that inits are done in the right order? (if such an order is guaranteed by c++, and I imagine it is.) (there must also be a similar mechanism for destructing globals, but that not important for non-hosted embedded apps.)

could somebody point to c++ startup code and linker script samples? as you can guess I'm also unfamiliar with gcc...

in short, I want to handle abstractions, not details! :)

obtronix
Associate II
Posted on May 17, 2011 at 12:24

Quote:

On 21-02-2008 at 21:53, Anonymous wrote:

I guess noone's working with c++ after all. is anybody interested in me keeping on posting to this thread?

I suspect many of us design using OOD but implement in C and Assembly, at least I do.

simonellwood9
Associate II
Posted on May 17, 2011 at 12:24

I have used c++ in an embedded environment on ARMs for years. It has been on ones with external SDRAM.

I considered using C++ on a small application for the NXP LPC2103.

I did not in the end just for the sort of reasons you are getting in to. I used C++ like structures in a similar way to how I would have done it in C++.

The code that GCC made was very good and gave me confidence that some elements of C++ would work well even on very small applications.

If you get it working I would look at using C++ again. If and when ST bring out parts with more memory then C++ on those chips will be pretty common. A lot of common coding practices used on C++ will not work well on chips with very small amounts of RAM.

Good Luck, and keep posting!