ARM_CM3 port and optimization

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 :( 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? regards Andreas

ARM_CM3 port and optimization

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? d.

ARM_CM3 port and optimization

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. Regards.

ARM_CM3 port and optimization

Missing the obvious point – check you are not just overflowing a stack when the optimisation if off. http://www.freertos.org/Stacks-and-stack-overflow-checking.html Regards.

ARM_CM3 port and optimization

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 Thanks! Andreas

ARM_CM3 port and optimization

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

ARM_CM3 port and optimization

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 :( 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.. regards Mathias

ARM_CM3 port and optimization

Now I tried the second free gcc compiler, from Raisonance( 4.3.2, http://www.mcu-raisonance.com/index.php?alias=mcu_downloads). -> same behavior :(

ARM_CM3 port and optimization

The demo in DemoCORTEX_LM3Sxxxx_EclipseRTOSDemo works fine with 0 optimization and uses the same code.

ARM_CM3 port and optimization

Which compiler  did you use?

ARM_CM3 port and optimization

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? Regards, Stefano

ARM_CM3 port and optimization

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? regards andreas

ARM_CM3 port and optimization

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) stf12.net Regards, Stefano

ARM_CM3 port and optimization

why not use a pastebin for posting snippets of code? e.g. http://pastebin.com

ARM_CM3 port and optimization

Got it! Startup was written in ‘C’. The vector table looks like this: http://pastebin.com/mffbef15 The code itself was pretty straight forward: http://pastebin.com/m26270dfa 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! Andreas

ARM_CM3 port and optimization

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.

ARM_CM3 port and optimization

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.0SourceportableGCCARM_CM3port.c I guess you use it also :)