ARM_CM3 port and optimization

amieska wrote on Saturday, May 02, 2009:

Hi all,

this is my first post here, so forgive me if I violate a rule.

I’ve encountered a strange behavior when compiling the CM3 port *without* optimization.
My first build was a release build with -O2 optimization and it worked perfectly. Then I turned to the debug version (with -g3 an -O0) and I got a HardFaultException after some msec.   I couldn’t get the exact reason or position of the crash because the link register is pointing to 0xfffffffc :frowning:

I made plenty of tests with the result that, whenever I turn on a kind of optimization the code works. -O1 is enough.

The compiler was the CodeWork 2008q3-66 release. Any hints?


spacewrench wrote on Saturday, May 02, 2009:

CM3 automatically pushes a set of registers on exception, and the LR of 0xfffffffc is a magic value indicating something like the exception-return requirements.  You can find the actual return address (or exception address) by looking on the stack (which is pointed to by SP).  IIRC, the automatically-pushed registers are R0-R3 and LR.

I can’t help you with your compiler optimization problem, though.  Perhaps you’re running out of memory and/or stack if the compiler doesn’t optimize its usage?


rtel wrote on Saturday, May 02, 2009:

I’ve never heard of CodeWord, but presume this is a GCC build?  If so then I would also assume it is based on the CodeSourcery as that is the only source of CM3 GCC that I am aware of.

Is your startup code written in C or ASM?  If C then can you ascertain whether or not main() is ever called.  If the code crashed before main is called on a CM3 then the most likely cause is a loop that clears the RAM being corrupted.  If the loop is written in C then without optimisation the loop variables will be read from and written back to RAM on each iteration of the loop - and the loop will most likely zero out these variables.  When optimisation is on the loop variables will be held in registers so zeroing out the RAM does not corrupt the loop variables.

One easy solution to this is to keep optimisation on just for the startup code, even when the rest of the code uses zero optimisation.


rtel wrote on Saturday, May 02, 2009:

Missing the obvious point - check you are not just overflowing a stack when the optimisation if off.


amieska wrote on Saturday, May 02, 2009:

Thanks for the answers!

Sorry, I meant CodeSourcery, my fault.
The stack  seems to be OK, I’ve filled all the memory with a pattern, checked it  and additionaly watched the sbrk() result (using the heap_3 implementation).

I will read the CM3 manual, check the exception cause and post the results tomorrow


anonymous wrote on Saturday, May 02, 2009:

Side note: I use the vanilla GCC (from on CM3 and it has been working just fine so far, using both 4.4.0 and 4.5.0-SVN.

amieska wrote on Sunday, May 03, 2009:

No luck so far.

The LR contenet of 0xfffffffx signalizes the type of exception return. Then I checked the state of the "Configurable fault status register" the cause of the exception was this:

"INVSTATE: Invalid state usage fault:
When this bit is set to 1, the PC value stacked for the exception return points to the instruction that attempted the illegal use of the EPSR. …"

But the stacked PC value already points to a non memory location :frowning:

I might get a Lauterbach with ETM memory next week, but I’m not sure if it works with Cortex nor if it is licenced for Cortex.

I assume a fault in my code or build environment, I don’t think it’s a problem with the compiler or FreeRTOS, but I will try a different compiler.

To answer the other questions:
the startup code is written in ‘C’, memory fill and dump for the stack check was made via JTAG.
The whole project consists of my code, the STM32 firmware lib and FreeRTOS. The only portion of code which requires the optimization is FreeRTOS. All other parts are build with -O0.

The behavior also occurs when I just start one LED flash task.  I can observe one scheduler call (SVCHandler) before I get the exception.

I let you know further results…


amieska wrote on Sunday, May 03, 2009:

Now I tried the second free gcc compiler, from Raisonance( 4.3.2, -> same behavior :frowning:

edwards3 wrote on Sunday, May 03, 2009:

The demo in Demo\CORTEX_LM3Sxxxx_Eclipse\RTOSDemo works fine with 0 optimization and uses the same code.

amieska wrote on Sunday, May 03, 2009:

Which compiler  did you use?

stf12 wrote on Monday, May 04, 2009:

Hi to all,

I’m working with STM32 + CodeSourcery v. 2008q3-66 and it woks fine using -g3 and -O0 compiler options.

Which startup code and linker script are you using?


amieska wrote on Monday, May 04, 2009:

Hi Stefano,

thanks for pointing to my startup code.
I’ve stubbed all exceptions and marked them for weak linking, like:

void PendSVC(void) __attribute__ ((weak));

The default implementation calls some code indicating an unhandled exception. Three handlers are overloaded by RTOS calls.

This might be the only difference between the RTOS code and the rest of my App (I removed all other interrupt handlers).

I will check this later. 

May I post the linkerfile and the two source files here?


stf12 wrote on Monday, May 04, 2009:

Hi Andreas,

I don’t know if is possible to post files in this forum.

I can provide my files to you. If it could be useful for you e-mail me at:

software (AT)


hooverphonique wrote on Monday, May 04, 2009:

why not use a pastebin for posting snippets of code?


amieska wrote on Monday, May 04, 2009:

Got it!

Startup was written in ‘C’. The vector table looks like this:

The code itself was pretty straight forward:

The issue arises with my declaration of all the exception handlers:

void SVCHandler(void) __attribute__ ((weak));
void PendSVC(void) __attribute__ ((weak));
void SysTickHandler(void) __attribute__ ((weak));

All functions are implemented like this:
void PendSVC(void) {DefaultHandler();}

The default handler ends in a loop with flashing LEDs to indicate an unhandeled exception.

Normally the linker will create a weak binding and if he finds a non weak binding, he replaces the function pointer with the address of the non weak function.

But, and I’m not clear why, it doesn’t work with naked functions like this:
void PendSVHandler( void ) __attribute__ (( naked ));

I looked to some old arm code and I’m pretty much sure it worked with ARM. Anyway I removed the weak bindings

Thanks again!

edwards3 wrote on Monday, May 04, 2009:

Definitely do NOT use the naked attribute on CortexM3 interrupts. That will make it crash for sure. Use the examples in the download as a reference that can be copied.

amieska wrote on Monday, May 04, 2009:

You can use the naked attribute for sure. The only point is to take care of the stackframe. A scheduler usually doesn’t use normal ‘C’ function stackframes because you don’t leave the scheduler like a normal function, you’re activating a different thread. There is no easy (and generic) way to restore the stack modified when entering the scheduler.

Look at the file .\FreeRTOSV5.2.0\Source\portable\GCC\ARM_CM3\port.c I guess you use it also :slight_smile: