ESP32 Wrover模块FreeRTOS队列发送两次消息触发LoadProhibited Guru Meditation Error求助
问题根源分析
你的问题核心出在任务参数的内存生命周期上!
看你的setup函数里,sensorTaskDescriptor是一个栈上的局部变量:
const ReadSensorsParameters sensorTaskDescriptor{ &debugMsgQueue,&sensorDataBufQueue,&sensorTaskWatchdog,rtc};
setup函数执行完毕后,这个局部变量所在的栈空间会被系统回收。而你把这个结构体的地址传给了ReadSensors任务,当任务开始运行(尤其是第二次发送队列时),原来的栈内存已经被覆盖或释放,pvParameters指向的是失效的内存区域,导致handlers变成野指针,后续访问*handlers->debugQueue时就触发了空指针访问(对应错误日志里的EXCVADDR: 0x00000000)。
第一次发送时可能只是侥幸内存还没被改写,第二次操作时内存被破坏,就触发了LoadProhibited异常。
解决方案
有几种简单的修复方式,选哪种都可以:
方案1:把结构体改成静态局部变量
在setup里定义结构体时加上static,这样它的内存会分配在静态存储区,不会随setup函数结束而释放:
static const ReadSensorsParameters sensorTaskDescriptor{ &debugMsgQueue,&sensorDataBufQueue,&sensorTaskWatchdog,rtc};
方案2:用动态内存分配(堆)
在setup里用malloc分配结构体内存,任务结束后记得释放(不过你任务最后用了vTaskDelete(NULL),可以在删除前释放,规范起见最好处理):
ReadSensorsParameters* sensorTaskDescriptor = (ReadSensorsParameters*)malloc(sizeof(ReadSensorsParameters)); if(sensorTaskDescriptor != NULL){ *sensorTaskDescriptor = { &debugMsgQueue,&sensorDataBufQueue,&sensorTaskWatchdog,rtc}; xReturned = xTaskCreate(ReadSensors, "GETDATA", 4096, (void*)sensorTaskDescriptor, 1, &sensorTaskHandle); }
然后在ReadSensors任务末尾添加释放代码:
free(pvParameters); // 在vTaskDelete之前执行 vTaskDelete(NULL);
方案3:改用全局结构体
把sensorTaskDescriptor定义成全局变量,这样内存生命周期和程序一致:
// 放在setup函数外面 ReadSensorsParameters sensorTaskDescriptor; void setup(){ // ...其他初始化代码 sensorTaskDescriptor = { &debugMsgQueue,&sensorDataBufQueue,&sensorTaskWatchdog,rtc}; xReturned = xTaskCreate(ReadSensors, "GETDATA", 4096, (void*)&sensorTaskDescriptor, 1, &sensorTaskHandle); // ... }
额外建议
- 以后传递任务参数时,一定要确保参数的内存生命周期覆盖任务的运行周期,栈上的局部变量绝对不能用来做任务参数(除非任务在
setup执行期间就完成并删除,但这种场景很少)。 - 你可以在
ReadSensors任务开头加个检查,确认pvParameters和handlers都不为NULL,进一步避免异常:
void ReadSensors(void* pvParameters) { if(pvParameters == NULL){ vTaskDelete(NULL); return; } ReadSensorsParameters* handlers = (ReadSensorsParameters*) pvParameters; if(handlers->debugQueue == NULL || *handlers->debugQueue == NULL){ vTaskDelete(NULL); return; } // ...后续业务代码 }
内容的提问来源于stack exchange,提问作者Vrabély Csaba
相关产品推荐
相关产品推荐

