STM32 crashing when trying to take a semaphore in release mode

dibosco wrote on Tuesday, March 07, 2017:

Folks,

Not sure this is really a FreeRTOS issue, so tell me to go and ask somewhere else if it’s inappropriate, I won’t be at all offended.

I have FreeROS running on an STM32 and it runs fine in debug mode. However, when I run it in release mode it crashes. The debugger does at least seem to keep track of the call stack still and I can see that it’s when it tries to grab my SPI Port 2 mutex for the first time when it wants to read the EEPROM. Depending on the level of optimisation it either crashes (hard fault handler) in xQueueGenericReceive() or __aeabi_memcpy4().

At first I thought I’d sussed it because in a couple of places I Was trying to access a mutex before I’d started the scheduler, then a queue before I’d started the scheduler. However, after having fixed those two issues, it’s still crashing as soon as I access xSPI2Mutex in a task.

I must stress it works fine with no optimisation.

Does anyone have any ideas about what might be causing this please? Am happy to provide anny other information that might point us in the right direction.

Many thanks,

Rob

rtel wrote on Tuesday, March 07, 2017:

Are you using GCC?

In recent versions of GCC, albeit not on Cortex-M parts, I have had
problems with built-in memcpy(), memmove(), memset(), etc. functions
attempting misaligned accesses. Providing my own implementation of
these functions has fixed the problem - but even then it is difficult to
get get GCC to use my implementations as it pattern matches, sees my
functions do the same as one of its build-in functions, then happily
carries on using its build-in function. I had to write really
inefficient code, with volatiles and the like, to get it to do something
else.

Could this potentially be your problem? I’m not sure at what
optimisation level it switches from using library functions to its
buil-in functions.

Forgot - an easier way of testing this is actually just to use the
command line option that prevents it using the built in functions. I
forget what it is but you can look it up, something like -fno-builtin

Regards.

heinbali01 wrote on Tuesday, March 07, 2017:

It sounds very probably what Richard mentions. I have also seen that happening while debugging with '-Os'.

For both memcpy() and memset(), the compiler can decide to create some inline code, and sometimes it isn’t really aware of aligment.
Try: -fno-builtin-memcpy -fno-builtin-memset while compiling.

A problem that we saw with memcpy() on cortexa9 is that it uses 64-bit registers of the FPU. By default, these registers are not saved on stack during a task swap.

You’ll find alternatives for memcpy() in the /labs software. Regards.