Bosch Sensortec Community

    cancel
    Showing results for 
    Search instead for 
    Did you mean: 

    Memory Leak in bsec Library with ESP8266

    Memory Leak in bsec Library with ESP8266

    Multi123321
    New Poster

    Hallo,

    I'm currently facing a problem with the bsec-Library and an ESP8266.

    I started with the basic.ino script which seems to work, but after ~30min the ESP8266 crashes and reboots. Therefore I modified the script a little bit to print the free heap size. This shows that there is a memory leak and the ESP8266 crashes after it ran out of memory.

    image.pngThis is the free heap size in bytes between two crashes.

    Is this a known problem and is there a fix for this?

    I am using this version:
    Arduino IDE: 1.8.13
    bsec: 1.6.1480
    esp8266 core: 2.7.4

     

     

    #include "bsec.h"
    
    extern "C" {
    #include "user_interface.h"
    }
    
    // Helper functions declarations
    void checkIaqSensorStatus(void);
    
    // Create an object of the class Bsec
    Bsec iaqSensor;
    
    String output;
    
    // Entry point for the example
    void setup(void)
    {
      Serial.begin(115200);
      Wire.begin();
    
      iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
      Serial.println(output);
      checkIaqSensorStatus();
    
      bsec_virtual_sensor_t sensorList[2] = {
        BSEC_OUTPUT_IAQ,
        BSEC_OUTPUT_STATIC_IAQ,
      };
    
      iaqSensor.updateSubscription(sensorList, 2, BSEC_SAMPLE_RATE_CONTINUOUS);
      checkIaqSensorStatus();
    
      // Print the header
      output = "Timestamp [ms], IAQ, IAQ accuracy";
      Serial.println(output);
    }
    
    // Function that is looped forever
    void loop(void)
    {
      unsigned long time_trigger = millis();
      if (iaqSensor.run()) { // If new data is available
        output = String(time_trigger);
        output += ", " + String(iaqSensor.iaq);
        output += ", " + String(iaqSensor.iaqAccuracy);
        Serial.println(output);
    
        
        uint32_t free = system_get_free_heap_size();
        Serial.print("Free RAM: ");
        Serial.println(free);
      } else {
        checkIaqSensorStatus();
      }
    }
    
    // Helper function definitions
    void checkIaqSensorStatus(void)
    {
      if (iaqSensor.status != BSEC_OK) {
        if (iaqSensor.status < BSEC_OK) {
          Serial.println("Error");
          for (;;) {}
        } else {
          Serial.println("Warning");
        }
      }
    
      if (iaqSensor.bme680Status != BME680_OK) {
        if (iaqSensor.bme680Status < BME680_OK) {
          Serial.println("Error");
          for (;;) {}
        } else {
          Serial.println("Warning");
        }
      }
    }

     

     

     This is the output of the ESP8266 Exception Decoder:

     

     

    Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
    PC: 0x4000df64
    EXCVADDR: 0x00000000
    
    Decoding stack results
    0x40100508: pvPortZalloc(size_t, char const*, int) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\heap.cpp line 301
    0x4021e0bc: mem_malloc at core/mem.c line 210
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x402068d5: Bsec::setState(unsigned char*) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 286
    0x40206ca9: Bsec::run(long long) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 209
    0x402068d8: Bsec::setState(unsigned char*) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 286
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40106b39: Twi::busywait(unsigned int) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 237
    0x40208654: Twi::write_bit(bool) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 280
    0x40210c4c: expf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libm/math/wf_exp.c line 44
    0x40210f1f: powf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libm/math/wf_pow.c line 36
    0x40206b01: Bsec::readProcessData(long long, bsec_bme_settings_t) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 399
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40211240: sqrtf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libm/math/wf_sqrt.c line 36
    0x40211240: sqrtf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libm/math/wf_sqrt.c line 36
    0x402085d6: Twi::write_stop() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 262
    0x402085d6: Twi::write_stop() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 262
    0x4020884d: Twi::writeTo(unsigned char, unsigned char*, unsigned int, unsigned char) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 349
    0x402085d6: Twi::write_stop() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 262
    0x40208ab4: twi_writeTo(unsigned char, unsigned char*, unsigned int, unsigned char) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_si2c.cpp line 984
    0x40207050: TwoWire::endTransmission(unsigned char) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\Wire\Wire.cpp line 171
    0x40207078: TwoWire::endTransmission() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\libraries\Wire\Wire.cpp line 180
    0x402066d1: Bsec::i2cWrite(unsigned char, unsigned char, unsigned char*, unsigned short) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 578
    0x40201204: bme680_set_regs at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bme680\bme680.c line 355
    0x40207c94: __esp_yield() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/core_esp8266_features.h line 92
    0x40208c02: __delay(unsigned long) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_wiring.cpp line 54
    0x40206df0: Bsec::delay_ms(unsigned int) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 533
    0x40206d65: Bsec::run(long long) at C:\Users\{USER}\Documents\Arduino\libraries\BSEC_Software_Library\src\bsec.cpp line 242
    0x40207110: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
    0x4020711c: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 165
    0x40207110: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
    0x4020730d: Print::write(char const*) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/Print.h line 62
    0x4020742d: Print::printNumber(unsigned long, unsigned char) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\Print.cpp line 268
    0x40209471: uart_write(uart_t*, char const*, size_t) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\uart.cpp line 509
    0x4020736c: Print::println() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\Print.cpp line 186
    0x40206599: loop() at C:\Users\{USER}\Downloads\temp\basic/basic.ino line 42
    0x40100154: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 177
    0x40100175: esp_schedule() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 125
    0x40207dbc: loop_wrapper() at C:\Users\{USER}\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\core_esp8266_main.cpp line 197

     

     

     

     

    5 REPLIES 5

    BSTRobin
    Community Moderator
    Community Moderator

    Hello Multi123321,

    1.Could you find where the function call caused the memory leak?

    2.Under you ESP8266 arduino SW platform, you could  try to increase the stack size of MCU startup code?


    @BSTRobin wrote:

    Hello Multi123321,

    1.Could you find where the function call caused the memory leak?

    2.Under you ESP8266 arduino SW platform, you could  try to increase the stack size of MCU startup code?


    Hi,

    I just tracked down the memory leak by reducing function calls and by removing dynamic memory allocation by using strings. See below for my code now.
    I turned out, that the memory leak comes form the iaqSensor.run() call in the loop function.

    What do you expect form increasing the stack size?

    Regards,
    Markus

    #include "bsec.h"
    
    extern "C"
    {
    #include "user_interface.h"
    }
    
    // Create an object of the class Bsec
    Bsec iaqSensor;
    
    // Entry point for the example
    void setup(void)
    {
      Serial.begin(115200);
      Wire.begin();
    
      iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
      // checkIaqSensorStatus();
    
      bsec_virtual_sensor_t sensorList[2] = {
          BSEC_OUTPUT_IAQ,
          BSEC_OUTPUT_STATIC_IAQ,
      };
    
      iaqSensor.updateSubscription(sensorList, 2, BSEC_SAMPLE_RATE_CONTINUOUS);
      // checkIaqSensorStatus();
    
      // Print the header
      Serial.println("Timestamp [ms], IAQ, IAQ accuracy");
    }
    
    uint32_t beforeRun;
    // Function that is looped forever
    void loop(void)
    {
      unsigned long time_trigger = millis();
    
      beforeRun = system_get_free_heap_size();
      if (iaqSensor.run())
      { // If new data is available
        uint32_t afterRun = system_get_free_heap_size();
    
        Serial.print(time_trigger);
        Serial.print(", ");
        Serial.print(iaqSensor.iaq);
        Serial.print(", ");
        Serial.print(iaqSensor.iaqAccuracy);
        Serial.println();
    
        Serial.print("Free RAM: ");
        Serial.print(beforeRun);
        Serial.print(", ");
        Serial.println(afterRun);
      }
      else
      {
        // checkIaqSensorStatus();
      }
    }

     

    BSTRobin
    Community Moderator
    Community Moderator

    Hello Multi123321,

    Increasing the stack size to ensure BSEC algorithm had enough memory to be used. Refer other community ticket:

    https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BME680-with-BSEC-produces-on-0-0s-even-a...

    Hello,

    what is an appropriate stack size for the bsec library? I could not find any documentation on this.

    A can you please give me a hint on how to specify the stack size using Arduino?

    Regards 
    Multi123321

    Icon--AD-black-48x48Icon--address-consumer-data-black-48x48Icon--appointment-black-48x48Icon--back-left-black-48x48Icon--calendar-black-48x48Icon--center-alignedIcon--Checkbox-checkIcon--clock-black-48x48Icon--close-black-48x48Icon--compare-black-48x48Icon--confirmation-black-48x48Icon--dealer-details-black-48x48Icon--delete-black-48x48Icon--delivery-black-48x48Icon--down-black-48x48Icon--download-black-48x48Ic-OverlayAlertIcon--externallink-black-48x48Icon-Filledforward-right_adjustedIcon--grid-view-black-48x48IC_gd_Check-Circle170821_Icons_Community170823_Bosch_Icons170823_Bosch_Icons170821_Icons_CommunityIC-logout170821_Icons_Community170825_Bosch_Icons170821_Icons_CommunityIC-shopping-cart2170821_Icons_CommunityIC-upIC_UserIcon--imageIcon--info-i-black-48x48Icon--left-alignedIcon--Less-minimize-black-48x48Icon-FilledIcon--List-Check-grennIcon--List-Check-blackIcon--List-Cross-blackIcon--list-view-mobile-black-48x48Icon--list-view-black-48x48Icon--More-Maximize-black-48x48Icon--my-product-black-48x48Icon--newsletter-black-48x48Icon--payment-black-48x48Icon--print-black-48x48Icon--promotion-black-48x48Icon--registration-black-48x48Icon--Reset-black-48x48Icon--right-alignedshare-circle1Icon--share-black-48x48Icon--shopping-bag-black-48x48Icon-shopping-cartIcon--start-play-black-48x48Icon--store-locator-black-48x48Ic-OverlayAlertIcon--summary-black-48x48tumblrIcon-FilledvineIc-OverlayAlertwhishlist