diff --git a/components/esp_system/esp_system.c b/components/esp_system/esp_system.c index e451231da6..0767a874fd 100644 --- a/components/esp_system/esp_system.c +++ b/components/esp_system/esp_system.c @@ -81,8 +81,13 @@ void IRAM_ATTR esp_restart(void) } } +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else // Disable scheduler on this core. vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP bool digital_reset_needed = false; #if CONFIG_ESP_SYSTEM_MEMPROT_FEATURE diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index 42b2599023..473e79c942 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -43,8 +43,13 @@ static void do_deep_sleep_from_app_cpu(void) { xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1); +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else // keep running some non-IRAM code vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP while (true) { ; diff --git a/components/freertos/test/test_suspend_scheduler.c b/components/freertos/test/test_suspend_scheduler.c index 02973ef613..7fdf10adfd 100644 --- a/components/freertos/test/test_suspend_scheduler.c +++ b/components/freertos/test/test_suspend_scheduler.c @@ -1,4 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /* Tests for FreeRTOS scheduler suspend & resume all tasks */ +#include "sdkconfig.h" #include #include "freertos/FreeRTOS.h" @@ -90,7 +96,12 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ TEST_ASSERT(isr_count > 10); for (int i = 0; i < 20; i++) { +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP esp_intr_noniram_disable(); unsigned no_sched_task = count_config.counter; @@ -107,7 +118,12 @@ TEST_CASE("Scheduler disabled can handle a pending context switch on resume", "[ // will preempt and count at least one more item esp_intr_noniram_enable(); esp_intr_enable(intr_handle); +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); +#else xTaskResumeAll(); +#endif // CONFIG_FREERTOS_SMP TEST_ASSERT_NOT_EQUAL(count_config.counter, no_sched_task); } @@ -152,7 +168,12 @@ TEST_CASE("Scheduler disabled can wake multiple tasks on resume", "[freertos]") } /* Suspend scheduler on this CPU */ +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP /* Give all the semaphores once. This will wake tasks immediately on the other CPU, but they are deferred here until the scheduler resumes. @@ -174,7 +195,12 @@ TEST_CASE("Scheduler disabled can wake multiple tasks on resume", "[freertos]") } /* Resume scheduler */ +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); +#else xTaskResumeAll(); +#endif // CONFIG_FREERTOS_SMP /* Now the tasks on both CPUs should have been woken once and counted once. */ for (int p = 0; p < portNUM_PROCESSORS; p++) { @@ -197,12 +223,22 @@ TEST_CASE("Scheduler disabled can wake multiple tasks on resume", "[freertos]") static volatile bool sched_suspended; static void suspend_scheduler_5ms_task_fn(void *ignore) { +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP sched_suspended = true; for (int i = 0; i < 5; i++) { esp_rom_delay_us(1000); } +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); +#else xTaskResumeAll(); +#endif // CONFIG_FREERTOS_SMP sched_suspended = false; vTaskDelete(NULL); } diff --git a/components/freertos/test/test_task_suspend_resume.c b/components/freertos/test/test_task_suspend_resume.c index 5ffbf56798..ecfa432628 100644 --- a/components/freertos/test/test_task_suspend_resume.c +++ b/components/freertos/test/test_task_suspend_resume.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /* Tests for FreeRTOS task suspend & resume */ #include #include @@ -196,11 +201,21 @@ static bool suspend_both_cpus; static void IRAM_ATTR suspend_scheduler_while_block_set(void *arg) { +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP while (block) { }; esp_rom_delay_us(1); +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); +#else xTaskResumeAll(); +#endif // CONFIG_FREERTOS_SMP } static void IRAM_ATTR suspend_scheduler_on_both_cpus(void) @@ -210,13 +225,23 @@ static void IRAM_ATTR suspend_scheduler_on_both_cpus(void) TEST_ESP_OK(esp_ipc_call((xPortGetCoreID() == 0) ? 1 : 0, &suspend_scheduler_while_block_set, NULL)); } +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else vTaskSuspendAll(); +#endif // CONFIG_FREERTOS_SMP } static void IRAM_ATTR resume_scheduler_on_both_cpus(void) { block = false; +#ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); +#else xTaskResumeAll(); +#endif // CONFIG_FREERTOS_SMP } static const int waiting_ms = 2000; diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index e1771c3913..8cb43abcdc 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -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 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 }