Showing results for 
Search instead for 
Did you mean: 

STM32F302 + FreeRTOS -- CPU register cleared after wfi/sleep mode



We're currently facing a weird problem with our project and FreeRTOS. I've asked in the FreeRTOS forum (see FreeRTOS Forum post), and the ARM forum (ARM Community Forum), but without success. 

The problem manifests itself in the program hanging in one of the RTOS asserts on system power up. After some forward and backward (see other thread), my conclusion is that, at boot, when the RTOS uses the sleep function for the first time, one of the CPU registers is cleared without any obvious reason. This leads to an RTOS Assert further down the chain.
This is the sleep function: (sleep function source code).  This is called in the idle task: idle task source. This is the assert: Tick plausability.
The assert fails because the value of xTickCount is invalid. I've analysed the assembly to the point that at the beginning of the function, CPU reg R7 is set as pointer to xTickCount. This register is then de-referenced later again, to get the tick for the assert. At this point, however, the register contains the value "0", leading to another value being loaded. I've narrowed it down to a few lines after the call to "wfi".


__asm volatile("mov %0, r7" : "=r" (test5257));
if( xModifiableIdleTime > 0 )
__asm volatile ( "dsb" ::: "memory" );
__asm volatile ( "wfi" );
__asm volatile ( "isb" );
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

//don't enable interrupt processing here, just to be sure...
//__asm volatile ( "cpsie i" ::: "memory" ); <-----------------
__asm volatile ("nop" ::: "memory");
__asm volatile ( "dsb" );
__asm volatile ( "isb" ); // <---------------------------------

__asm volatile("mov %0, r7" : "=r" (test5258));


when I pause the target with the debugger and read the values of the variables, "test5257" contains a pointer to xTickCount and "test5258" contains "0". When i patch the second "isb" directly in the binary to a 4 byte "nop", the pointer remains valid and the assertion is gone. I can't see any reason why the value of the register should change as a result of the "isb" instruction.

  • The error occurs only after power-up, not on reset.
  • Adding/removing a line of code in the right spot removes the problem. I haven't found any logic to this. This might be why we haven't seen this problem before now.
  • placing a breakpoint and then starting the target also removes the problem.

I would appreciate any help on understanding what causes this behaviour. As adding/removing code sometimes "fixes" the error, I have no idea how I can check if a change actually fixed the underlying problem...


Details for our system:

CPU is a Cortex M4F STM32F302CCT
FreeRTOS Code base V11.0.1 (FreeRTOS)
Custom board
custom drivers, not STM Cube
toolchain "arm-freertos-eabi-gcc (GNU Tools for ARM Embedded Processors 6-2017-q3-update)" (standard toolchain modified to have thread-save malloc/newlib)
optimization "-Os" + link time