ESP32中Mittelwert任务触发Guru Meditation Error问题求助
ESP32多任务程序中Mittelwert任务触发LoadProhibited Guru Meditation Error排查
为ESP32编写的多任务程序,其余任务运行正常,但启动Mittelwert任务时触发Guru Meditation Error(LoadProhibited)。此前该任务曾引发看门狗错误,调整优先级后变为当前错误,已定位问题出在Mittelwert.h中,但无法找到具体原因,以下是相关代码及错误日志:
相关代码
main.cpp
#include <Arduino.h> #include <Document.h> void updateDocument(void * par){ //Task to Update a document or create if not existing for(;;){ Documentgetting(); Documentupdate(); } } void getLuxTempHum(void * par){ //Task to get Humidity Temperatur and Lux for(;;){ gHumidity(); gLux(); gTemperatur(); } } void getgps(void * par){ // Task to get GPS for(;;){ gGPS(); } } void setaktor(void * par){ // Task to get Aktoren for(;;){ gmotor(); /*LEDsss(dark); shakeit(shake);*/ } } void getWindRain(void* arg){//Task for wind for(;;){ gWind(); } } void getMittelwert(void* par){//get Mittelwert from sensors for(;;){ gMittelwerte(); } } void setup() { //****************************** TMP117 MS8607 TSL2591********************************* if(!tmp117.begin()){} configureSensor(); if(!tsl.begin()){} if(!ms8607.begin()){} ms8607.setHumidityResolution(MS8607_HUMIDITY_RESOLUTION_OSR_8b); xTaskCreate( getLuxTempHum, "get LuxTempHum", 10000, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, 1, NULL ); //*********************************************************************** //***************************** Wind/Regen ************************************ setupwr(); xTaskCreate( getWindRain, "getWindRain", 4500, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, tskIDLE_PRIORITY, NULL ); //*************************************************************************/ //***************************** GPS**************************************** setupGPS(); xTaskCreate( getgps, "get GPS", 7000, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, 1, NULL ); //*************************************************************************/ //******************************Aktoren************************************ setupledandmotor(); xTaskCreate( setaktor, "set Aktor", 4500, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, 1, NULL ); //************************************************************************* //****************************Mittelwert********************************* mittelsetup(); xTaskCreate( getMittelwert, "get Mittelwert", 10000, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, 1, NULL ); //*************************************************************************/ //**************************** Firebase ******************************* setupFire(); xTaskCreate( updateDocument, "update/create Document", 20000, //make higher if complex task, 4500 mostlikely is enough for most jobs NULL, 1, NULL ); //********************************************************************* } void loop() { if(gotwindgeschwingkeit>=11){ Sperre=true; U=true; O=false; }else{ Sperre=false; } delay(10); }
Mittelwert.h
#include <Arduino.h> //******************************Lux, Temp, Hum************************* #include <Lux.h> #include <Temp.h> #include <Humidity.h> //********************************Wind/Regen*********************************** #include <WindRegen.h> bool gethalfhour = false; bool getthreeminutes = false; int halfhouri = 0; int threemini = 0; double sensors[]={gotHum, gotLux, gotTemp, gotwindgeschwingkeit}; double sensorshh[sizeof(sensors)]; double sensorstm[sizeof(sensors)]; void mittelsetup(){ for(int i = sizeof(sensors)-1; i>=0; i--){ sensorshh[i]=sensors[i]; sensorstm[i]=sensors[i]; } } void updatesenorssss(){ sensors[0]=gotHum; sensors[1]=gotLux; sensors[2]=gotTemp; sensors[3]=gotwindgeschwingkeit; } void gMittelwerte(){ updatesenorssss(); vTaskDelay(1000/portTICK_PERIOD_MS); halfhouri++; threemini++; for(int i = sizeof(sensors)-1; i>=0; i--){ sensorshh[i]+=sensors[i]; sensorstm[i]+=sensors[i]; } if(gethalfhour){ for(int i = sizeof(sensors)-1; i>=0; i--){ sensorshh[i]=sensorshh[i]/halfhouri; } halfhouri=0; vTaskDelay(500/portTICK_PERIOD_MS); for(int i = sizeof(sensorshh)-1; i>=0; i--){ sensorshh[i]=0; } } if(getthreeminutes){ for(int i = sizeof(sensors)-1; i>=0; i--){ sensorstm[i]=sensorstm[i]/threemini; } threemini=0; vTaskDelay(500/portTICK_PERIOD_MS); for(int i = sizeof(sensorstm)-1; i>=0; i--){ sensorstm[i]=0; } } }
错误日志
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x4016407f PS : 0x00060030 A0 : 0x80164165 A1 : 0x3ffb4e70 A2 : 0x00000000 A3 : 0x3ffb4ebe A4 : 0x00000001 A5 : 0x00000000 A6 : 0x00000000 A7 : 0x00000000 A8 : 0x80083c3c A9 : 0x3ffb4e60 A10 : 0x3ff000e0 A11 : 0x00000001 A12 : 0x3ffbddc8 A13 : 0x00000000 A14 : 0x007bf1f8 A15 : 0x003fffff SAR : 0x0000001d EXCCAUSE: 0x0000001c EXCVADDR: 0x0000000c LBEG : 0x40089dcc LEND : 0x40089de2 LCOUNT : 0xffffffff Backtrace:0x4016407c:0x3ffb4e700x40164162:0x3ffb4e90 0x400e3695:0x3ffb4eb0 0x400e385f:0x3ffb4ee0 0x400d35d5:0x3ffb4f00 0x400d35f7:0x3ffb4f20 0x400d365a:0x3ffb4f40
排查与修复方案
数组越界(核心问题)
- 所有循环中使用
sizeof(sensors)-1是错误的:sizeof(sensors)返回的是数组总字节数(4个double元素,共32字节),不是元素个数。这会导致循环索引从31开始,远超出数组的有效索引范围(0-3),直接访问非法内存触发LoadProhibited错误。 - 修复方式:先计算元素个数,再遍历:
// 计算传感器数组元素个数 const int sensorCount = sizeof(sensors) / sizeof(double); // 修改mittelsetup中的循环 void mittelsetup(){ for(int i = sensorCount - 1; i >= 0; i--){ sensorshh[i] = sensors[i]; sensorstm[i] = sensors[i]; } } // 同理修改gMittelwerte中的所有循环,替换sizeof(sensors)-1为sensorCount-1,sizeof(sensorshh)-1也换成sensorCount-1
- 所有循环中使用
全局变量并发访问风险
gotHum、gotLux等全局变量被多个任务同时读写,没有同步机制,可能导致数据异常甚至内存访问错误。添加互斥锁保护:// 在全局区域创建互斥锁 SemaphoreHandle_t sensorMutex = NULL; // 在setup中初始化 void setup(){ sensorMutex = xSemaphoreCreateMutex(); // ...其他初始化代码 } // 在读写全局变量的地方加锁,比如updatesenorssss中: void updatesenorssss(){ if(xSemaphoreTake(sensorMutex, portMAX_DELAY) == pdTRUE){ sensors[0] = gotHum; sensors[1] = gotLux; sensors[2] = gotTemp; sensors[3] = gotwindgeschwingkeit; xSemaphoreGive(sensorMutex); } } // 同时在其他任务(比如getLuxTempHum、getWindRain)中读写这些变量时也要加锁
除以零防范
- 当
gethalfhour或getthreeminutes触发时,halfhouri或threemini可能为0,导致除法错误。添加判断:if(gethalfhour && halfhouri > 0){ for(int i = sensorCount - 1; i >= 0; i--){ sensorshh[i] = sensorshh[i]/halfhouri; } // ...后续代码 }
- 当
任务栈与优先级检查
- 当前
getMittelwert栈大小设为10000足够,但要确保没有其他内存泄漏问题;优先级调整后解决了看门狗问题,保持当前设置即可。
- 当前
内容的提问来源于stack exchange,提问作者nottaK was
相关产品推荐
相关产品推荐

