esp-idf_关闭调度产生复位问题

发布时间 2023-04-25 16:31:30作者: SpinJump

esp-idf 里面关闭 freeRtos 之后产生的复位问题

esp-idf 里面需要使用的 vTaskSuspendAll 吗?

  1. 一般是不需要的,根据 esp 官方的回答, esp-idf 的大多数都是可重入函数。

此外,esp-idf 中的大多数 API 都是可重入的;您根本不应该使用 vTaskSuspendAll。(如果你认为无论如何都需要使用它,请使用互斥体 - ESP32 有相当多的东西在后台运行,使用 vTaskSuspendAll 阻止它们就像在蚊子上使用大炮一样。

具体可参看 :FreeRTOS、printf 和 vTaskSuspend 的问题

  1. 还有一个原因,那就是因为它是双核的,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 函数

  1. 正常来说,调用 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