From a44bc26e21d4a536b11fa39e8d32029fa91fd7cf Mon Sep 17 00:00:00 2001 From: schneider <schneider@blinkenlichts.net> Date: Wed, 29 Apr 2020 22:18:10 +0200 Subject: [PATCH] fix(bsec): Reduce stack usage by calling init before stating the task --- epicardium/main.c | 20 ++++----- epicardium/modules/bsec.c | 78 +++++++++++++++++++++++------------- epicardium/modules/modules.h | 1 + 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/epicardium/main.c b/epicardium/main.c index b9631e45..4e2cba12 100644 --- a/epicardium/main.c +++ b/epicardium/main.c @@ -126,15 +126,17 @@ int main(void) } /* BSEC */ - if (xTaskCreate( - vBSECTask, - (const char *)"BSEC", - configMINIMAL_STACK_SIZE * 4, - NULL, - tskIDLE_PRIORITY + 1, - NULL) != pdPASS) { - LOG_CRIT("startup", "Failed to create %s task!", "BSEC"); - abort(); + if(bsec_activate() == 0) { + if (xTaskCreate( + vBSECTask, + (const char *)"BSEC", + configMINIMAL_STACK_SIZE * 3, /* 768 bytes. Mainly for state saving... */ + NULL, + tskIDLE_PRIORITY + 1, + NULL) != pdPASS) { + LOG_CRIT("startup", "Failed to create %s task!", "BSEC"); + abort(); + } } /* API */ diff --git a/epicardium/modules/bsec.c b/epicardium/modules/bsec.c index abda8a79..08306dd3 100644 --- a/epicardium/modules/bsec.c +++ b/epicardium/modules/bsec.c @@ -20,7 +20,7 @@ TaskHandle_t bsec_task_id; static struct bme680_sensor_data last_bme680_data; static int64_t last_bme680_timestamp; -static bool active; +static bool bsec_task_active; #define ULP 0 // From generic_18v_3s_4d/bsec_serialized_configurations_iaq.c @@ -227,6 +227,17 @@ static int8_t i2c_read(uint8_t addr, uint8_t reg, uint8_t *p_buf, uint16_t size) return ret; } +static void delay(uint32_t msec) +{ + if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) { + /* We need to fall back to hardware waits if not running + * in a task context */ + card10_bosch_delay(msec); + } else { + vTaskDelay(pdMS_TO_TICKS(msec)); + } +} + /*! * @brief Load library config from non-volatile memory * @@ -280,19 +291,14 @@ void ulp_plus_trigger_iaq() } #endif -static void delay(uint32_t msec) -{ - vTaskDelay(pdMS_TO_TICKS(msec)); -} - bool bsec_active(void) { - return active; + return bsec_task_active; } int bsec_read_bme680(struct bme680_sensor_data *data) { - if (!active) { + if (!bsec_task_active) { return BME680_E_COM_FAIL; } while (last_bme680_timestamp == 0) @@ -301,46 +307,62 @@ int bsec_read_bme680(struct bme680_sensor_data *data) return BME680_OK; } -void vBSECTask(void *pvParameters) +/** + * Checks config and activates the BSEC libary if requested. + * + * Initializes the BSEC library before starting the task to + * reduce the stack size needed for the task by at least 512 bytes + */ +int bsec_activate(void) { return_values_init ret; - active = true; - bsec_task_id = xTaskGetCurrentTaskHandle(); - #if ULP float sample_rate = BSEC_SAMPLE_RATE_ULP; - /* State is saved every 100 samples, which means every 100 * 300 secs = 500 minutes */ - const int stat_save_interval = 100; #else float sample_rate = BSEC_SAMPLE_RATE_LP; - /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes */ - const int stat_save_interval = 10000; #endif float temperature_offset = 0.0; - ret = bsec_iot_init( - sample_rate, - temperature_offset, - i2c_write, - i2c_read, - delay, - state_load, - config_load + + /* Puts AT LEAST 2 * #BSEC_MAX_PROPERTY_BLOB_SIZE = 2 * 454 = 908 bytes onto the stack */ + ret = bsec_iot_init( + sample_rate, + temperature_offset, + i2c_write, + i2c_read, + delay, + state_load, + config_load ); if (ret.bme680_status) { printf("bme680 init failed\n"); /* Could not intialize BME680 */ - while (1) - ; + return -1; } else if (ret.bsec_status) { printf("bsec init failed\n"); /* Could not intialize BSEC library */ - while (1) - ; + return -1; } + return 0; +} + +void vBSECTask(void *pvParameters) +{ + bsec_task_active = true; + bsec_task_id = xTaskGetCurrentTaskHandle(); + +#if ULP + /* State is saved every 100 samples, which means every 100 * 300 secs = 500 minutes */ + const int stat_save_interval = 100; +#else + /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes */ + const int stat_save_interval = 10000; +#endif /* Call to endless loop function which reads and processes data based on sensor settings */ + /* Puts AT LEAST 2 * BSEC_MAX_STATE_BLOB_SIZE + 8 * sizeof(bsec_input_t) = + * 2 * 139 + 8 * 20 = 438 bytes onto the stack */ bsec_iot_loop( delay, get_timestamp_us, diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h index 1d962550..a1aab4c4 100644 --- a/epicardium/modules/modules.h +++ b/epicardium/modules/modules.h @@ -137,6 +137,7 @@ void max30001_mutex_init(void); extern gpio_cfg_t gpio_configs[]; /* ---------- BSEC / BME680 ------------------------------------------------ */ +int bsec_activate(void); void vBSECTask(void *pvParameters); bool bsec_active(void); struct bme680_sensor_data; -- GitLab