freertos: Fix usage of vTaskSuspendAll()/xTaskResumeAll()

IDF FreeRTOS uses vTaskSuspendAll()/xTaskResumeAll() to stop preemption
on a particular core. However, those functions behave differently in FreeRTOS SMP.
This commit replaces all calls of vTaskSuspendAll()/xTaskResumeAll() with
vTaskPreemptionDisable()/vTaskPreemptionEnable() when compiling with SMP FreeRTOS.
This commit is contained in:
Darian Leung
2022-03-08 14:59:18 +08:00
parent 883da858b0
commit 27f5c90e2e
5 changed files with 108 additions and 0 deletions
+37
View File
@@ -112,7 +112,15 @@ void spi_flash_op_unlock(void)
void IRAM_ATTR spi_flash_op_block_func(void *arg)
{
// Disable scheduler on this CPU
#ifdef CONFIG_FREERTOS_SMP
/*
Note: FreeRTOS SMP has changed the behavior of scheduler suspension. But the vTaskPreemptionDisable() function should
achieve the same affect as before (i.e., prevent the current task from being preempted).
*/
vTaskPreemptionDisable(NULL);
#else
vTaskSuspendAll();
#endif // CONFIG_FREERTOS_SMP
// Restore interrupts that aren't located in IRAM
esp_intr_noniram_disable();
uint32_t cpuid = (uint32_t) arg;
@@ -128,8 +136,13 @@ void IRAM_ATTR spi_flash_op_block_func(void *arg)
spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]);
// Restore interrupts that aren't located in IRAM
esp_intr_noniram_enable();
#ifdef CONFIG_FREERTOS_SMP
//Note: Scheduler suspension behavior changed in FreeRTOS SMP
vTaskPreemptionEnable(NULL);
#else
// Re-enable scheduler
xTaskResumeAll();
#endif // CONFIG_FREERTOS_SMP
}
void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void)
@@ -167,8 +180,13 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void)
// Busy loop and wait for spi_flash_op_block_func to disable cache
// on the other CPU
}
#ifdef CONFIG_FREERTOS_SMP
//Note: Scheduler suspension behavior changed in FreeRTOS SMP
vTaskPreemptionDisable(NULL);
#else
// Disable scheduler on the current CPU
vTaskSuspendAll();
#endif // CONFIG_FREERTOS_SMP
// Can now set the priority back to the normal one
vTaskPrioritySet(NULL, old_prio);
// This is guaranteed to run on CPU <cpuid> because the other CPU is now
@@ -216,7 +234,12 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void)
// But esp_intr_noniram_enable has to be called on the same CPU which
// called esp_intr_noniram_disable
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#ifdef CONFIG_FREERTOS_SMP
//Note: Scheduler suspension behavior changed in FreeRTOS SMP
vTaskPreemptionEnable(NULL);
#else
xTaskResumeAll();
#endif // CONFIG_FREERTOS_SMP
}
// Release API lock
spi_flash_op_unlock();
@@ -253,12 +276,26 @@ void spi_flash_init_lock(void)
void spi_flash_op_lock(void)
{
#ifdef CONFIG_FREERTOS_SMP
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
//Note: Scheduler suspension behavior changed in FreeRTOS SMP
vTaskPreemptionDisable(NULL);
}
#else
vTaskSuspendAll();
#endif // CONFIG_FREERTOS_SMP
}
void spi_flash_op_unlock(void)
{
#ifdef CONFIG_FREERTOS_SMP
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
//Note: Scheduler suspension behavior changed in FreeRTOS SMP
vTaskPreemptionEnable(NULL);
}
#else
xTaskResumeAll();
#endif // CONFIG_FREERTOS_SMP
}