StoreProhibitedCause Exception with linked list on ESP8266

2

I have implemented a linked list class as follows for storage of sensor data readings.

(Note the total code is ~4000 lines so I can't provide it all, hopefully this gives an idea of what's done).

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);
}

After around 31000 loops (just under 2^15 which is suspicious to me), I get a StoreProhibitedCause Exception. If I comment out dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);, I no longer get the exception. I suspect it's some way that I have implemented the linked list and it has a memory issue but I have tried printing out the addresses of everything and it doesn't look like anything is running away.

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

===================== SOLVED ===================== DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().

Otherwise it keeps on creating new structs for every addition.

arduino
esp8266
nodemcu
arduino-esp8266
asked on Stack Overflow Feb 6, 2020 by HumptyDumps • edited Feb 8, 2020 by HumptyDumps

1 Answer

2

DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().

Otherwise it keeps on creating new structs for every addition.

(I can't mark it solved without having an answer).

answered on Stack Overflow Feb 6, 2020 by HumptyDumps

User contributions licensed under CC BY-SA 3.0