StoreProhibitedCause 异常与 ESP8266 上的链表
StoreProhibitedCause Exception with linked list on ESP8266
我实现了一个链表 class 如下用于存储传感器数据读数。
(请注意,总代码约为 4000 行,因此我无法提供全部,希望这能让您了解已完成的工作)。
struct DataItem {
String _dataType;
float _dataArray[dataArraySize_const];
float _calibratedData = -1.0;
float _rawData = -1.0;
DataItem *_next;
uint8_t _dataArraySize = dataArraySize_const;
float *_calibrationParameters;
uint8_t _numCalibrationParameters;
};
class DataContainer {
public:
DataContainer() {
_head = NULL;
_tail = NULL;
};
DataItem* addDataItem(String dataTypeIn, float calibrationParameters[10], uint8_t numberOfCalibrationParameters) {
DataItem *temp = new DataItem;
temp->_dataType = dataTypeIn;
temp->_calibratedData = -1.0;
temp->_rawData = -1.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) { temp->_dataArray[i] = 0; } //Setting all the data array to 0
temp->_calibrationParameters = calibrationParameters;
temp->_numCalibrationParameters = numberOfCalibrationParameters;
temp->_next = NULL;
if(_head == NULL) {
_head = temp;
_tail = temp;
temp = NULL;
}
else {
_tail->_next = temp;
_tail = temp;
}
return temp;
};
uint8_t setDataValue(String dataType, float value, uint8_t arrayIndex) {
DataItem *temp = new DataItem;
temp = _head;
Serial.println("Addresses: ");
while(temp != NULL) {
Serial.print("temp address: 0x");
Serial.println((unsigned long)temp, HEX);
Serial.print("head address: 0x");
Serial.println((unsigned long)_head, HEX);
Serial.print("temp add address: 0x");
Serial.println((unsigned long)&temp, HEX);
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_dataArray[arrayIndex] = value;
float sum = 0.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) {
sum += temp->_dataArray[i];
}
temp->_rawData = sum/dataArraySize_const;
Serial.println("Pre calibration");
this->calibrate(temp);
Serial.println("Finished calibration");
return 0;
};
void calibrate(DataItem *temp) {
temp->_calibratedData = temp->_calibrationParameters[0];
for (uint8_t i = 1; i <= temp->_numCalibrationParameters; i++) {
temp->_calibratedData += temp->_calibrationParameters[i] * pow(temp->_rawData, i);
}
}
uint8_t setCalibrationParameters(String dataType, float calibrationParameters[10]) {
DataItem *temp = new DataItem;
temp = _head;
while(temp != NULL) {
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_calibrationParameters = calibrationParameters;
return 0;
};
private:
DataItem *_head, *_tail;
};
uint8_t numUsedCalibrationParameters = 10;
float calibrationParam[numUsedCalibrationParameters] = {0,1,0,0,0,0,0,0,0,0};
uint8_t dataArrayPosition = 0;
uint8_t dataArraySize = 10;
void setup(void) {
Serial.begin(115200);
Serial.setDebugOutput(false);
delay(20);
Serial.println("\n\nbegin");
pinMode(A0, INPUT);
dataContainer.addDataItem("ADC",calibrationParam,numUsedCalibrationParameters);
void loop(void) {
dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
if (dataArrayPosition < dataArraySize) { ++dataArrayPosition; }
else { dataArrayPosition = 0; }
delay(100);
}
在大约 31000 次循环后(不到 2^15,这对我来说是可疑的),我得到了 StoreProhibitedCause 异常。如果我注释掉 dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
,我将不再得到异常。我怀疑这是我实现链表的某种方式,它有内存问题,但我已经尝试打印出所有内容的地址,但看起来 运行 没有任何东西。
异常:
Exception (29):
epc1=0x4000df64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 01a0
3fffedb0: 4024576b 3fff0b08 00000002 40245700
.....
===================== 已解决 =====================
DataItem *temp = new DataItem;
对于 setDataValue()
和 setCalibrationParameters()
应该是 DataItem *temp;
。
否则它会继续为每次添加创建新结构。
对于 setDataValue()
和 setCalibrationParameters()
.,DataItem *temp = new DataItem;
应该是 DataItem *temp;
否则它会继续为每次添加创建新结构。
(我无法在没有答案的情况下将其标记为已解决)。
我实现了一个链表 class 如下用于存储传感器数据读数。
(请注意,总代码约为 4000 行,因此我无法提供全部,希望这能让您了解已完成的工作)。
struct DataItem {
String _dataType;
float _dataArray[dataArraySize_const];
float _calibratedData = -1.0;
float _rawData = -1.0;
DataItem *_next;
uint8_t _dataArraySize = dataArraySize_const;
float *_calibrationParameters;
uint8_t _numCalibrationParameters;
};
class DataContainer {
public:
DataContainer() {
_head = NULL;
_tail = NULL;
};
DataItem* addDataItem(String dataTypeIn, float calibrationParameters[10], uint8_t numberOfCalibrationParameters) {
DataItem *temp = new DataItem;
temp->_dataType = dataTypeIn;
temp->_calibratedData = -1.0;
temp->_rawData = -1.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) { temp->_dataArray[i] = 0; } //Setting all the data array to 0
temp->_calibrationParameters = calibrationParameters;
temp->_numCalibrationParameters = numberOfCalibrationParameters;
temp->_next = NULL;
if(_head == NULL) {
_head = temp;
_tail = temp;
temp = NULL;
}
else {
_tail->_next = temp;
_tail = temp;
}
return temp;
};
uint8_t setDataValue(String dataType, float value, uint8_t arrayIndex) {
DataItem *temp = new DataItem;
temp = _head;
Serial.println("Addresses: ");
while(temp != NULL) {
Serial.print("temp address: 0x");
Serial.println((unsigned long)temp, HEX);
Serial.print("head address: 0x");
Serial.println((unsigned long)_head, HEX);
Serial.print("temp add address: 0x");
Serial.println((unsigned long)&temp, HEX);
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_dataArray[arrayIndex] = value;
float sum = 0.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) {
sum += temp->_dataArray[i];
}
temp->_rawData = sum/dataArraySize_const;
Serial.println("Pre calibration");
this->calibrate(temp);
Serial.println("Finished calibration");
return 0;
};
void calibrate(DataItem *temp) {
temp->_calibratedData = temp->_calibrationParameters[0];
for (uint8_t i = 1; i <= temp->_numCalibrationParameters; i++) {
temp->_calibratedData += temp->_calibrationParameters[i] * pow(temp->_rawData, i);
}
}
uint8_t setCalibrationParameters(String dataType, float calibrationParameters[10]) {
DataItem *temp = new DataItem;
temp = _head;
while(temp != NULL) {
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_calibrationParameters = calibrationParameters;
return 0;
};
private:
DataItem *_head, *_tail;
};
uint8_t numUsedCalibrationParameters = 10;
float calibrationParam[numUsedCalibrationParameters] = {0,1,0,0,0,0,0,0,0,0};
uint8_t dataArrayPosition = 0;
uint8_t dataArraySize = 10;
void setup(void) {
Serial.begin(115200);
Serial.setDebugOutput(false);
delay(20);
Serial.println("\n\nbegin");
pinMode(A0, INPUT);
dataContainer.addDataItem("ADC",calibrationParam,numUsedCalibrationParameters);
void loop(void) {
dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
if (dataArrayPosition < dataArraySize) { ++dataArrayPosition; }
else { dataArrayPosition = 0; }
delay(100);
}
在大约 31000 次循环后(不到 2^15,这对我来说是可疑的),我得到了 StoreProhibitedCause 异常。如果我注释掉 dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
,我将不再得到异常。我怀疑这是我实现链表的某种方式,它有内存问题,但我已经尝试打印出所有内容的地址,但看起来 运行 没有任何东西。
异常:
Exception (29):
epc1=0x4000df64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 01a0
3fffedb0: 4024576b 3fff0b08 00000002 40245700
.....
===================== 已解决 =====================
DataItem *temp = new DataItem;
对于 setDataValue()
和 setCalibrationParameters()
应该是 DataItem *temp;
。
否则它会继续为每次添加创建新结构。
setDataValue()
和 setCalibrationParameters()
.,DataItem *temp = new DataItem;
应该是 DataItem *temp;
否则它会继续为每次添加创建新结构。
(我无法在没有答案的情况下将其标记为已解决)。