ESP32调用vTaskDelay时触发崩溃的问题排查求助
ESP32-IDF任务执行vTaskDelay触发LoadProhibited崩溃问题分析
问题场景
在PlatformIO基于ESP32-IDF环境下,烧录代码到ESP32设备后,程序在led_blink任务的第一个vTaskDelay处触发系统panic,抛出LoadProhibited错误。已确认电源提供2A电流,满足设备需求,GPIO设置返回值正常,但日志显示引脚OutputEn: 0。
运行代码
#include <driver/gpio.h> #include <freertos/FreeRTOS.h> #include <freertos/task.h> #define RELAY 2 void hello_task(void *pvParameter) { printf("Hello world!\n"); for (int i = 10; i >= 0; i--) { printf("Restarting in %d seconds...\n", i); vTaskDelay(pdMS_TO_TICKS(1000)); } printf("Restarting now.\n"); fflush(stdout); esp_restart(); } void led_blink(void *pvParams) { printf("Resetting pin\n"); gpio_reset_pin(RELAY); printf("Setting pin direction\n"); gpio_set_direction(RELAY,GPIO_MODE_OUTPUT); while (1) { printf("Setting GPIO level low\n"); esp_err_t error_num = gpio_set_level(RELAY,0); printf("error_num: %d\n", error_num); vTaskDelay(pdMS_TO_TICKS(500)); // 崩溃发生在此处 printf("Setting GPIO level high\n"); error_num = gpio_set_level(RELAY,1); printf("error_num: %d\n", error_num); vTaskDelay(pdMS_TO_TICKS(1000)); } } void app_main() { xTaskCreate(&hello_task, "hello_task", 2048, NULL, 5, NULL); xTaskCreate(&led_blink,"LED_BLINK",1024,NULL,5,NULL); }
崩溃日志
I (306) app_start: Starting scheduler on CPU0 I (311) app_start: Starting scheduler on CPU1 I (311) main_task: Started on CPU0 I (321) main_task: Calling app_main() Hello world! Restarting in 10 seconds... Resetting pin I (321) gpio: GPIO[2]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 Setting pin direction Setting GPIO level low error_num: 0 I (341) main_task: Returned from app_main() Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled. Core 0 register dump: PC : 0x400869c8 PS : 0x00060033 A0 : 0x800883ea A1 : 0x3ffb0e50 A2 : 0x00000001 A3 : 0x0000000a A4 : 0x00000035 A5 : 0x00000005 A6 : 0xb33fffff A7 : 0xb33fffff A8 : 0x00000001 A9 : 0x00000000 A10 : 0x00000000 A11 : 0x80000001 A12 : 0x00000000 A13 : 0x00060023 A14 : 0xb33fffff A15 : 0xb33fffff SAR : 0x0000001e EXCCAUSE: 0x0000001c EXCVADDR: 0x0000000e LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000 Backtrace: 0x400869c5:0x3ffb0e50 0x400883e7:0x3ffb0e70 0x40088231:0x3ffb0e90 0x40082732:0x3ffb0ea0 0x4008467f:0x3ffb5290 0x400d385f:0x3ffb52b0 0x40086726:0x3ffb52d0 0x40087c79:0x3ffb52f0
问题原因
- 栈空间不足是核心崩溃原因:
led_blink任务仅分配了1024字节栈空间,但任务中多次调用printf(这类函数需要较大栈空间处理格式化输出),加上FreeRTOS任务自身的栈开销,1024字节不足以容纳这些操作,执行vTaskDelay时触发栈溢出,进而导致LoadProhibited错误(访问非法内存地址)。 OutputEn: 0与崩溃无关:gpio_reset_pin执行后,引脚默认处于输入模式,此时OutputEn为0是正常状态。后续gpio_set_direction将引脚设为输出模式后,该标志会自动变为1,只是日志未再次打印引脚状态;且gpio_set_level返回0也证明引脚配置是成功的。
解决方案
直接增大led_blink任务的栈空间,将创建任务时的栈大小从1024调整为2048(与hello_task一致),或更大的数值(如4096):
xTaskCreate(&led_blink,"LED_BLINK",2048,NULL,5,NULL);
内容的提问来源于stack exchange,提问作者Liam Clink
相关产品推荐
相关产品推荐

