Cortex-M3 allocating memory before scheduler start locks interrupts

smith84 wrote on Thursday, December 05, 2013:

I am running FreeRTOS 7.4.0 on a Cortex-M3 processor (no MPU).

My initialisation code creates a timer before the OS start, and after the call to xTimerCreate() the BASEPRI is set to block interrupts - this causes other problems in my startup routines.

I have managed to trace the code as follows (showing what I think are the relevant parts only!):

  • xTimerCreate()
    • pvPortMalloc()
      • vTaskSuspendAll()
        • xTaskResumeAll()
          • taskENTER_CRITICAL(): this increments the uxCriticalNesting counter which was at the init value of 0xaaaaaaaa to 0xaaaaaaab
            • portDISABLE_INTERRUPTS(): sets BASEPRI to block interrupts
          • taskEXIT_CRITICAL(): this decrements uxCriticalNesting back to 0xaaaaaaaa which is greater than 0 so it does not call portENABLE_INTERRUPTS()

This mess with uxCriticalNesting is all fixed up when the scheduler is started and uxCriticalNesting is set to 0.

My understanding is that I should be able to create timers and tasks etc before the scheduler is started. However, with this call tree it seems that any call for these types of operations will block the interrupts below the OS masking level.

Any suggestions as to what I can try to resolve this problem? I could simply modify the initialisation value of uxCriticalNesting but that doesn’t seem to be the right thing to do.

rtel wrote on Thursday, December 05, 2013:

This behaviour is completely intentional and the reason why the critical nesting count is never initialised to 0. It is done like this to prevent interrupts attempting to use RTOS API functions before the RTOS has been started - if an interrupt attempted a context switch when the kernel is not running the system would crash. If the crash is caused by an interrupt the user may not understand what has happened.

If you can guarantee this is not going to happen in your system then you can initialise the critical nesting variable to 0 instead of whichever non-zero value is used.


smith84 wrote on Thursday, December 05, 2013:

Thanks for the quick reply. With that information I know that I can work around the problem by using busy-wait loops until the scheduler is started.