DRNadler / FreeRTOS_helpers

Helpers for some common problems when using FreeRTOS, GCC, and newlib.
135 stars 20 forks source link

vTaskSuspendAll() / xTaskResumeAll() disables IRQs #6

Open g-mocken opened 3 years ago

g-mocken commented 3 years ago

Regarding this part (and a few more similar occurrences):

#define DRN_ENTER_CRITICAL_SECTION(_usis) vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started, but not in ISR
#define DRN_EXIT_CRITICAL_SECTION(_usis)  xTaskResumeAll();  // Note: safe to use before FreeRTOS scheduler started, but not in ISR

While, as the comment suggests, it may be safe to use before FreeRTOS scheduler is started, it still has a side effect (at least on my M0+ port): Any call to malloc() before starting the scheduler will then return with interrupts disabled.

I suggest to wrap the above with if (xTaskGetSchedulerState()!= taskSCHEDULER_NOT_STARTED){ ... }

(Patching FreeRTOS' handling of the variable uxCriticalNesting would be another way to deal with it, but I prefer not to modify these parts.)

ljluestc commented 1 year ago

Your suggestion of wrapping the critical section code with a check for the scheduler state (xTaskGetSchedulerState()) is a reasonable approach to address the issue. By checking whether the scheduler has been started, you can avoid the side effect of interrupts being disabled when calling malloc() before the scheduler initialization.

Here's how your modified code might look with the suggested change:

if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
    // Before scheduler started
    // Perform critical section without suspending tasks
} else {
    // After scheduler started
    // Enter critical section
    vTaskSuspendAll();

    // ... Critical section code ...

    // Exit critical section
    xTaskResumeAll();
}

This approach ensures that the critical section is only applied when the scheduler has been started, preventing unwanted side effects when using memory allocation functions like malloc() before the scheduler is up and running.