ESP32运行FreeRTOS基础程序触发Guru Meditation Error求助
ESP32 FreeRTOS任务触发Guru Meditation Error(非法指令)的解决方法
问题背景
在ESP32上运行FreeRTOS基础程序,功能是将全局变量内容打印到串口监视器,但运行后出现非法指令panic。代码及错误信息如下:
原始代码
#if CONFIG_FREERTOS_UNICORE //this will return false (reading from config in freertos.h file), so we’ll set it to run on the second core app_cpu=1 static const BaseType_t app_cpu = 0; #else static const BaseType_t app_cpu = 1; #endif //global variable char buffer[] = "Mary had a little lamb"; //task1 void Task1_Function( void *params) { uint8_t i = 0; uint8_t msg_len = strlen(buffer); //read (print) whatever is in the buffer Serial.print("Task1: "); for(int i; i < msg_len; i++) { Serial.print(buffer[i]); } Serial.println(); vTaskDelay(1000 / portTICK_PERIOD_MS); } //task2 //void Task1_Function( void *params) //{ //} void setup() { //Initialize Serial monitor Serial.begin(9600); BaseType_t status; TaskHandle_t task1_handler, task2_handler; //Task 1 Creation status = xTaskCreatePinnedToCore(Task1_Function, "Task-1-Function", 1024, //This is stack size in words, in bytes for a 32bit miccrocontroller each word is 4 bytes. so 500*4 = 20000 bytes NULL, //no parameters passed 1, //priority &task1_handler, app_cpu ); //check if task creation, memory allocation was sucessfull if (status != pdTRUE) { Serial.println("Error Task1 creation failed"); //using Arduino IDE } //Or you can use the assert //configASSERT(status == pdTRUE); } void loop() { // put your main code here, to run repeatedly: }
运行错误信息
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:2 load:0x3fff0030,len:1156 load:0x40078000,len:11456 ho 0 tail 12 room 4 load:0x40080400,len:2972 entry 0x400805dc Task1: Mary had a little lamb Guru Meditation Error: Core 1 panic'ed (IllegalInstruction). Exception was unhandled. Memory dump at 0x400d1428: 4ce5e8a3 00f01db8 b2808430 Core 1 register dump: PC : 0x400d142d PS : 0x00060b30 A0 : 0x00000000 A1 : 0x3ffb8d10 A2 : 0x3ffc1058 A3 : 0x00000016 A4 : 0x3ffbdb60 A5 : 0x00000016 A6 : 0x00000000 A7 : 0x00000000 A8 : 0x800d142d A9 :
问题分析
核心原因:FreeRTOS任务函数未实现无限循环
FreeRTOS的任务函数必须持续运行,不能执行完毕后返回。Task1_Function在执行一次打印和延迟后就退出了,这种行为会触发系统非法指令异常。次要问题:循环变量未初始化
在Task1_Function的for循环中,重复声明了int i但未初始化,属于未定义行为,本次运行巧合打印出内容,但存在潜在风险。
修复后的代码
#if CONFIG_FREERTOS_UNICORE static const BaseType_t app_cpu = 0; #else static const BaseType_t app_cpu = 1; #endif //global variable char buffer[] = "Mary had a little lamb"; //task1 void Task1_Function( void *params) { uint8_t msg_len = strlen(buffer); // FreeRTOS任务必须保持运行,添加无限循环 while(true) { Serial.print("Task1: "); // 初始化循环变量,避免未定义行为 for(uint8_t i = 0; i < msg_len; i++) { Serial.print(buffer[i]); } Serial.println(); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void setup() { Serial.begin(9600); BaseType_t status; TaskHandle_t task1_handler; //Task 1 Creation status = xTaskCreatePinnedToCore(Task1_Function, "Task-1-Function", 1024, NULL, 1, &task1_handler, app_cpu ); if (status != pdTRUE) { Serial.println("Error Task1 creation failed"); } } void loop() { // 空loop不影响,FreeRTOS任务已独立运行 }
修改说明
- 添加
while(true)无限循环:将打印和延迟逻辑放入循环内,确保任务函数持续运行,不会返回,彻底解决非法指令panic问题。 - 修复循环变量:移除重复声明的
int i,改为在循环内初始化uint8_t i = 0,消除未定义行为,同时与msg_len类型保持一致。 - 清理冗余代码:移除未使用的
task2_handler和重复的变量声明,简化代码结构。
内容的提问来源于stack exchange,提问作者tadm123
相关产品推荐
相关产品推荐

