esp-idf_关闭调度产生复位问题
esp-idf 里面关闭 freeRtos 之后产生的复位问题
esp-idf 里面需要使用的 vTaskSuspendAll 吗?
- 一般是不需要的,根据 esp 官方的回答, esp-idf 的大多数都是可重入函数。
此外,esp-idf 中的大多数 API 都是可重入的;您根本不应该使用 vTaskSuspendAll。(如果你认为无论如何都需要使用它,请使用互斥体 - ESP32 有相当多的东西在后台运行,使用 vTaskSuspendAll 阻止它们就像在蚊子上使用大炮一样。
具体可参看 :FreeRTOS、printf 和 vTaskSuspend 的问题
- 还有一个原因,那就是因为它是双核的,vTaskSuspendAll() 函数只会对当前核起作用。
在 vanilla FreeRTOS 中,通过 vTaskSuspendAll() 挂起调度程序将阻止 vTaskSwitchContext 从上下文切换调用,直到调度程序已使用 xTaskResumeAll() 恢复.但是仍然允许为 ISR 提供服务.因此,在恢复调度程序之前,将不会执行由当前正在运行的任务或 ISRS 导致的任务状态的任何更改. vanilla FreeRTOS 中的调度程序暂停是一种常见的保护方法,可以同时访问任务之间共享的数据,同时仍允许对 ISR 进行服务.
在 ESP-IDF FreeRTOS 中,xTaskResumeAll() 只会阻止调用 vTaskSwitchContext() 来切换调用挂起的核上下文.因此,如果 PRO_CPU 调用 vTaskSuspendAll(), APP_CPU 仍然可以切换上下文.如果数据在固定到不同核的任务之间共享,则调度程序暂停不是防止同时访问的有效方法.在保护 ESP-IDF FreeRTOS 中的共享资源时,请考虑使用关键部分(禁用中断)或信号量(不禁用中断).
通常,最好使用其他 RTOS 原语(如互斥信号量)来防止任务之间共享的数据,而不是 vTaskSuspendAll().
ESP32 官方文档(九)ESP-IDF FreeRTOS SMP Changes
调用 vTaskSuspendAll 之后,不能调用 vTaskDelay 函数
- 正常来说,调用 vTaskSuspendAll() 挂起函数之后,就不能在调用其它的任务切换函数了。而 vTaskDelay 是具有切换性质的函数,而且它会在入口处检查是否全局挂起,如果是,就会报错。
void vTaskDelay( const TickType_t xTicksToDelay )
{
configASSERT( xTaskGetSchedulerState() != taskSCHEDULER_SUSPENDED );
}
assert failed: xQueueSemaphoreTake queue.c:1561 (!( ( xTaskGetSchedulerState() == ( ( BaseType_t ) 0 ) ) && ( xTicksToWait != 0 ) ))
Backtrace: 0x40375cb6:0x3fcf3890 0x4037a161:0x3fcf38b0 0x4037f71d:0x3fcf38d0 0x4037ae25:0x3fcf39f0 0x40377174:0x3fcf3a30 0x40377235:0x3fcf3a60 0x42008819:0x3fcf3a80 0x4200891f:0x3fcf3aa0 0x4200897f:0x3fcf3ac0 0x4200795b:0x3fcf3ae0 0x42019163:0x3fcf3b00 0x4037caf5:0x3fcf3b30
0x40375cb6: panic_abort at /home/sea/esp/esp-idf/components/esp_system/panic.c:412
0x4037a161: esp_system_abort at /home/sea/esp/esp-idf/components/esp_system/esp_system.c:135
0x4037f71d: __assert_func at /home/sea/esp/esp-idf/components/newlib/assert.c:78
0x4037ae25: xQueueSemaphoreTake at /home/sea/esp/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1561 (discriminator 2)
0x40377174: lock_acquire_generic at /home/sea/esp/esp-idf/components/newlib/locks.c:146
0x40377235: _lock_acquire at /home/sea/esp/esp-idf/components/newlib/locks.c:154
0x42008819: ensure_partitions_loaded at /home/sea/esp/esp-idf/components/esp_partition/partition.c:233
0x4200891f: esp_partition_find at /home/sea/esp/esp-idf/components/esp_partition/partition.c:265
0x4200897f: esp_partition_find_first at /home/sea/esp/esp-idf/components/esp_partition/partition.c:321
0x4200795b: app_main at /home/sea/esp/hello_world/build/../main/hello_world_main.c:35
0x42019163: main_task at /home/sea/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:131 (discriminator 2)
0x4037caf5: vPortTaskWrapper at /home/sea/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:151