arduino - ESP8266 上的链表出现 StoreProhibitedCause 异常

标签 arduino esp8266 nodemcu arduino-esp8266

我实现了一个链表类,如下所示,用于存储传感器数据读数。

(请注意,总代码约为 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):

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 
.....

======================已解决==================== 对于 setDataValue()setCalibrationParameters()DataItem *temp = new DataItem; 应为 DataItem *temp;

否则它会继续为每次添加创建新的结构。

最佳答案

DataItem *temp = new DataItem;应该是DataItem *temp;对于 setDataValue()setCalibrationParameters() .

否则它会继续为每次添加创建新的结构。

(如果没有答案,我就无法将其标记为已解决)。

关于arduino - ESP8266 上的链表出现 StoreProhibitedCause 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60099765/

相关文章:

c++ - Arduino Sketch with multiple NeoPixels (功能采用不同的 NeoPixels)

arduino - Arduino uno 中用于数字读取和计数脉冲的 CPU 周期

python - 使用结构将 float 从 Arduino 发送到 Python

java - Android & NodeMCU,从服务器接收响应无法正常工作?

html - Raspberry 在后台打开网页

C++ 在另一个使用引用和参数的函数内调用函数

ios - NodeMCU ESP8266 使用 C 连接到 iPhone 热点

arduino - server.args() ESP8266 Arduino

button - 在arduino中创建一个定时三态按钮

java - HttpURLConnection 应用程序因 ESP8266 而崩溃