mjaakkol / bme680_esp_idf

BME680 software build on top of ESP-IDF 4.0 generation and Bosch BSEC stack
MIT License
11 stars 2 forks source link

Core dumping after loading configuration. #3

Closed horsemann07 closed 3 years ago

horsemann07 commented 3 years ago

Hello @mjaakkol

I used your repository in ESP-IDF 4.2, I given the NVS partition but esp not able to find the nvs. So, I comment on that part.

After the loading configuration, the esp core is dumping continuously.

Here is the example file.


#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_FREQUENCY 100000
#define I2C_GPIO_SDA GPIO_NUM_21
#define I2C_GPIO_SCL GPIO_NUM_22
#define ACTIVE_I2C I2C_NUM_0

#define STORAGE_NAMESPACE "storage"

static const char *TAG = "bme680_sensor";
static const char *sensor_binary = "sensor_blob";

/**********************************************************************************************************************/
/* functions */
/**********************************************************************************************************************/

/*!
 * @brief           Write operation in either I2C or SPI
 *
 * param[in]        dev_addr        I2C or SPI device address
 * param[in]        reg_addr        register address
 * param[in]        reg_data_ptr    pointer to the data to be written
 * param[in]        data_len        number of bytes to be written
 *
 * @return          result of the bus communication function
 */
int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
    // ...
    // Please insert system specific function to write to the bus where BME680 is connected
    // ...
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    assert(data_len > 0 && reg_data_ptr != NULL); // Safeguarding the assumptions
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg_addr, true);
    i2c_master_write(cmd, reg_data_ptr, data_len, true);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    // ESP_OK matches with the function success code (0)
    return (int8_t)ret;
}

/*!
 * @brief           Read operation in either I2C or SPI
 *
 * param[in]        dev_addr        I2C or SPI device address
 * param[in]        reg_addr        register address
 * param[out]       reg_data_ptr    pointer to the memory to be used to store the read data
 * param[in]        data_len        number of bytes to be read
 *
 * @return          result of the bus communication function
 */
int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
    // ...
    // Please insert system specific function to read from bus where BME680 is connected
    // ...
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    assert(data_len > 0 && reg_data_ptr != NULL); // Safeguarding the assumptions
    // Feeding the command in
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg_addr, true);

    //bme680_sleep(150);
    // Reading data back
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (dev_addr << 1) | I2C_MASTER_READ, true);
    if (data_len > 1)
    {
        i2c_master_read(cmd, reg_data_ptr, data_len - 1, I2C_MASTER_ACK);
    }
    i2c_master_read_byte(cmd, reg_data_ptr + data_len - 1, I2C_MASTER_NACK);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    // ESP_OK matches with the function success code (0)
    return (int8_t)ret;
}

/*!
 * @brief           System specific implementation of sleep function
 *
 * @param[in]       t_ms    time in milliseconds
 *
 * @return          none
 */
static void bme680_sleep(uint32_t t_ms)
{
    // ...
    // Please insert system specific function sleep or delay for t_ms milliseconds
    // ...
    vTaskDelay(pdMS_TO_TICKS(t_ms));
}

/*!
 * @brief           Handling of the ready outputs
 *
 * @param[in]       timestamp       time in nanoseconds
 * @param[in]       iaq             IAQ signal
 * @param[in]       iaq_accuracy    accuracy of IAQ signal
 * @param[in]       temperature     temperature signal
 * @param[in]       humidity        humidity signal
 * @param[in]       pressure        pressure signal
 * @param[in]       raw_temperature raw temperature signal
 * @param[in]       raw_humidity    raw humidity signal
 * @param[in]       gas             raw gas sensor signal
 * @param[in]       bsec_status     value returned by the bsec_do_steps() call
 *
 * @return          none
 */
void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity,
                  float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status,
                  float static_iaq, float co2_equivalent, float breath_voc_equivalent)
{
    // ...
    // Please insert system specific code to further process or display the BSEC outputs
    // ...
    ESP_LOGI(TAG, "iaq %f temp %f hum %f press %f static iaq %f co2_equivalent %f breath voc %f", iaq, temperature, humidity, pressure, static_iaq, co2_equivalent, breath_voc_equivalent);
}

/*!
 * @brief           Load previous library state from non-volatile memory
 *
 * @param[in,out]   state_buffer    buffer to hold the loaded state string
 * @param[in]       n_buffer        size of the allocated state buffer
 *
 * @return          number of bytes copied to state_buffer
 */

uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer)
{
    // ...
    // Load a previous library state from non-volatile memory, if available.
    //
    // Return zero if loading was unsuccessful or no state was available,
    // otherwise return length of loaded state string.
    // ...
    nvs_handle_t my_handle;
    // esp_err_t err = nvs_open(STORAGE_NAMESPACE, NVS_READONLY, &my_handle);
    // switch (err)
    // {
    // case ESP_OK:
    //     printf("< storage handle was opened successfully \n");
    //     err = nvs_get_blob(my_handle, sensor_binary, state_buffer, &n_buffer);
    //     // We close this anyway even if the operation didn't succeed.
    //     nvs_close(my_handle);
    //     if (err == ESP_OK)
    //     {
    //         return n_buffer;
    //     }
    //     ESP_LOGI(TAG, "loading sensor binary blob failed with code %d", err);
    //     break;
    // case ESP_ERR_NVS_NOT_INITIALIZED:
    //     printf(" < ESP_ERR_NVS_NOT_INITIALIZED \n");
    //     break;
    // case ESP_ERR_NVS_PART_NOT_FOUND:
    //     printf(" < ESP_ERR_NVS_PART_NOT_FOUND \n");
    //     break;
    // case ESP_ERR_NVS_NOT_FOUND:
    //     printf(" < ESP_ERR_NVS_NOT_FOUND \n");
    //     break;
    // case ESP_ERR_NVS_INVALID_NAME:
    //     printf(" < ESP_ERR_NVS_INVALID_NAME \n");
    //     break;
    // case ESP_ERR_NO_MEM:
    //     printf(" < ESP_ERR_NO_MEM \n");
    //     break;
    // default:
    //     break;
    // }
    //ESP_ERROR_CHECK( err );

    return 0;
}

/*!
 * @brief           Save library state to non-volatile memory
 *
 * @param[in]       state_buffer    buffer holding the state to be stored
 * @param[in]       length          length of the state string to be stored
 *
 * @return          none
 */
void state_save(const uint8_t *state_buffer, uint32_t length)
{
    // ...
    // Save the string some form of non-volatile memory, if possible.
    // ...
    nvs_handle_t my_handle;
    // esp_err_t err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
    // //ESP_ERROR_CHECK(err);
    // switch (err)
    // {
    // case ESP_OK:
    //     printf("->storage handle was opened successfully \n");
    //     err = nvs_set_blob(my_handle, sensor_binary, state_buffer, length);
    //     //ESP_ERROR_CHECK( err );
    //     err = nvs_commit(my_handle);
    //     // ESP_ERROR_CHECK(err);
    //     nvs_close(my_handle);
    //     break;
    // case ESP_ERR_NVS_NOT_INITIALIZED:
    //     printf(" ->ESP_ERR_NVS_NOT_INITIALIZED \n");
    //     break;
    // case ESP_ERR_NVS_PART_NOT_FOUND:
    //     printf(" ->ESP_ERR_NVS_PART_NOT_FOUND \n");
    //     break;
    // case ESP_ERR_NVS_NOT_FOUND:
    //     printf(" ->ESP_ERR_NVS_NOT_FOUND \n");
    //     break;
    // case ESP_ERR_NVS_INVALID_NAME:
    //     printf(" ->ESP_ERR_NVS_INVALID_NAME \n");
    //     break;
    // case ESP_ERR_NO_MEM:
    //     printf(" ->ESP_ERR_NO_MEM \n");
    //     break;
    // default:
    //     break;
    // }

    return;
}

/*!
 * @brief           Load library config from non-volatile memory
 *
 * @param[in,out]   config_buffer    buffer to hold the loaded state string
 * @param[in]       n_buffer        size of the allocated state buffer
 *
 * @return          number of bytes copied to config_buffer
 */
uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer)
{
    // ...
    // Load a library config from non-volatile memory, if available.
    //
    // Return zero if loading was unsuccessful or no config was available,
    // otherwise return length of loaded config string.
    // ...
    ESP_LOGI(TAG, "Loading configuration: buffer-size %d  config size %d", n_buffer, sizeof(bsec_config_iaq));
    assert(n_buffer >= sizeof(bsec_config_iaq));
    memcpy(config_buffer, bsec_config_iaq, sizeof(bsec_config_iaq));

    return sizeof(bsec_config_iaq);
}

static esp_err_t i2c_master_init(void)
{
    esp_err_t ret;
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_GPIO_SDA,
        .scl_io_num = I2C_GPIO_SCL,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_FREQUENCY,
    };
    i2c_param_config(I2C_NUM_0, &conf);
    ret = i2c_driver_install(I2C_NUM_0, conf.mode,
                             I2C_MASTER_RX_BUF_DISABLE,
                             I2C_MASTER_TX_BUF_DISABLE, 0);
    switch (ret)
    {
    case ESP_OK:
        printf("I2C initialize-->\n");
        break;
    default:
        printf("I2C Failed-->\n");
        break;
    }
    return ret;
}

/*!
 * @brief       Main function which configures BSEC library and then reads and processes the data from sensor based
 *              on timer ticks
 *
 * @return      result of the processing
 */
void initialize_sensor()
{
    return_values_init ret;
    esp_err_t err = i2c_master_init();
    ESP_ERROR_CHECK(err);

    ESP_LOGI(TAG, "I2C initialized");
    /* Call to the function which initializes the BSEC library
     * Switch on low-power mode and provide no temperature offset */
    ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0.0f, bus_write, bus_read, bme680_sleep, state_load, config_load);
    if (ret.bme680_status)
    {
        /* Could not initialize BME680 */
        ESP_LOGE(TAG, "initializing BME680 failed %d", ret.bme680_status);
        //return (int)ret.bme680_status;
    }
    else if (ret.bsec_status)
    {
        /* Could not intialize BSEC library */
        ESP_LOGE(TAG, "initializing BSEC failed %d", ret.bsec_status);
        //return (int)ret.bsec_status;
    }

    //ESP_LOGI(TAG, "Entering into the loop");
    /* Call to endless loop function which reads and processes data based on sensor settings */
    /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes  */
    bsec_iot_loop(bme680_sleep, esp_timer_get_time, output_ready, state_save, 10000);

    return; //0;
}

/*! @}*/

void app_main()
{
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        // NVS partition was truncated and needs to be erased
        // Retry nvs_flash_init
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK(err);
    //initialize_sensor();
    TaskHandle_t xHandle = NULL;
    xTaskCreate(initialize_sensor, "Initialize_Sensor", 4096, NULL, 1, &xHandle);
}

/*
Current ESP-IDF 4.0 doesn't provide the function for newlib so the approximation
is provided here for __ieee754_sqrtf

Once the linker warning appears, feel free to delete the code
*/

float __ieee754_sqrtf(float number)
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y = number;
    i = *(long *)&y;           // floating point bit level hacking [sic]
    i = 0x5f3759df - (i >> 1); // Newton's approximation
    y = *(float *)&i;
    y = y * (threehalfs - (x2 * y * y)); // 1st iteration
    y = y * (threehalfs - (x2 * y * y)); // 2nd iteration
    y = y * (threehalfs - (x2 * y * y)); // 3rd iteration

    return 1 / y;
}

Log.

I (85) boot:  2 factory          factory app      00 00 00010000 00100000
I (93) boot:  3 storage          OTA data         01 00 00110000 00040000
I (100) boot: End of partition table
I (105) boot: Defaulting to factory image
I (109) boot_comm: chip revision: 1, min. application chip revision: 0
I (117) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x0936c ( 37740) map
I (140) esp_image: segment 1: paddr=0x00019394 vaddr=0x3ffb0000 size=0x0210c (  8460) load
I (144) esp_image: segment 2: paddr=0x0001b4a8 vaddr=0x40080000 size=0x00404 (  1028) load
I (147) esp_image: segment 3: paddr=0x0001b8b4 vaddr=0x40080404 size=0x04764 ( 18276) load
I (164) esp_image: segment 4: paddr=0x00020020 vaddr=0x400d0020 size=0x21afc (137980) map
I (217) esp_image: segment 5: paddr=0x00041b24 vaddr=0x40084b68 size=0x06fd4 ( 28628) load
I (236) boot: Loaded app from partition at offset 0x10000
I (236) boot: Disabling RNG early entropy source...
I (237) cpu_start: Pro cpu up.
I (241) cpu_start: Application information:
I (245) cpu_start: Project name:     bme680_esp
I (251) cpu_start: App version:      v4.2-351-gce2c615bb-dirty
I (257) cpu_start: Compile time:     Apr  3 2021 17:00:20
I (263) cpu_start: ELF file SHA256:  2685d837d7b96ed2...
I (269) cpu_start: ESP-IDF:          v4.2-351-gce2c615bb-dirty
I (276) cpu_start: Starting app cpu, entry point is 0x40081758
I (268) cpu_start: App cpu up.
I (286) heap_init: Initializing. RAM available for dynamic allocation:
I (293) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (299) heap_init: At 3FFB2ED8 len 0002D128 (180 KiB): DRAM
I (305) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (312) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (318) heap_init: At 4008BB3C len 000144C4 (81 KiB): IRAM
I (324) cpu_start: Pro cpu start user code
I (343) spi_flash: detected chip: generic
I (343) spi_flash: flash io: dio
I (343) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I2C initialize-->
I (10) bme680_sensor: I2C initialized
I (20) bme680_sensor: Loading configuration: buffer-size 454  config size 454
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x400d288e  PS      : 0x00060b33  A0      : 0x800d2c1d  A1      : 0x3ffb5430  
A2      : 0x00000000  A3      : 0x3ffb5450  A4      : 0x00000014  A5      : 0x000000a5  
A6      : 0x000000a5  A7      : 0x00060023  A8      : 0x8005937d  A9      : 0x3ffb5420  
A10     : 0x3ffb5570  A11     : 0x00060b23  A12     : 0x00060b23  A13     : 0x00060b23  
A14     : 0x00000001  A15     : 0x0000007f  SAR     : 0x00000000  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x8005937d  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

Backtrace:0x400d288b:0x3ffb5430 0x400d2c1a:0x3ffb5450 0x400d2c47:0x3ffb5480 0x400d2ce5:0x3ffb54a0 0x4008682a:0x3ffb54c0 0x40085ead:0x3ffb54e0

ELF file SHA256: 2685d837d7b96ed2

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:4
load:0x3fff0034,len:7336
load:0x40078000,len:13212
load:0x40080400,len:4568
entry 0x400806f4