bt: call nvs_flash_init in examples, show error if NVS is not initialized

NVS is used to store PHY calibration data, WiFi configuration, and BT
configuration. Previously BT examples did not call nvs_flash_init,
relying on the fact that it is called during PHY init. However PHY init
did not handle possible NVS initialization errors.

This change moves PHY init procedure into the application, and adds
diagnostic messages to BT config management routines if NVS is not
initialized.
This commit is contained in:
Ivan Grokhotkov 2017-07-13 23:46:19 +08:00
parent 1ed4eadfab
commit 979fce0df5
17 changed files with 132 additions and 31 deletions

View File

@ -91,7 +91,12 @@ config_t *config_new(const char *filename)
nvs_handle fp; nvs_handle fp;
err = nvs_open(filename, NVS_READWRITE, &fp); err = nvs_open(filename, NVS_READWRITE, &fp);
if (err != ESP_OK) { if (err != ESP_OK) {
LOG_ERROR("%s unable to open file '%s'\n", __func__, filename); if (err == ESP_ERR_NVS_NOT_INITIALIZED) {
LOG_ERROR("%s: NVS not initialized. "
"Call nvs_flash_init before initializing bluetooth.", __func__);
} else {
LOG_ERROR("%s unable to open NVS namespace '%s'\n", __func__, filename);
}
config_free(config); config_free(config);
return NULL; return NULL;
} }
@ -316,6 +321,10 @@ bool config_save(const config_t *config, const char *filename)
err = nvs_open(filename, NVS_READWRITE, &fp); err = nvs_open(filename, NVS_READWRITE, &fp);
if (err != ESP_OK) { if (err != ESP_OK) {
if (err == ESP_ERR_NVS_NOT_INITIALIZED) {
LOG_ERROR("%s: NVS not initialized. "
"Call nvs_flash_init before initializing bluetooth.", __func__);
}
err_code |= 0x02; err_code |= 0x02;
goto error; goto error;
} }

View File

@ -159,22 +159,18 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_data) esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_data)
{ {
esp_err_t err = nvs_flash_init();
if (err != ESP_OK) {
ESP_LOGW(TAG, "%s: failed to initialize NVS (0x%x)", __func__, err);
return err;
}
nvs_handle handle; nvs_handle handle;
err = nvs_open(PHY_NAMESPACE, NVS_READONLY, &handle); esp_err_t err = nvs_open(PHY_NAMESPACE, NVS_READONLY, &handle);
if (err != ESP_OK) { if (err == ESP_ERR_NVS_NOT_INITIALIZED) {
ESP_LOGE(TAG, "%s: NVS has not been initialized. "
"Call nvs_flash_init before starting WiFi/BT.", __func__);
} else if (err != ESP_OK) {
ESP_LOGD(TAG, "%s: failed to open NVS namespace (0x%x)", __func__, err); ESP_LOGD(TAG, "%s: failed to open NVS namespace (0x%x)", __func__, err);
return err; return err;
} }
else { err = load_cal_data_from_nvs_handle(handle, out_cal_data);
err = load_cal_data_from_nvs_handle(handle, out_cal_data); nvs_close(handle);
nvs_close(handle); return err;
return err;
}
} }
esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data) esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data)

View File

@ -18,6 +18,8 @@
extern "C" { extern "C" {
#endif #endif
#include "nvs.h"
/** /**
* @brief Initialize NVS flash storage with layout given in the partition table. * @brief Initialize NVS flash storage with layout given in the partition table.
* *
@ -30,6 +32,17 @@ extern "C" {
esp_err_t nvs_flash_init(void); esp_err_t nvs_flash_init(void);
/**
* @brief Erase NVS partition
*
* This function erases all contents of NVS partition
*
* @return
* - ESP_OK on success
* - ESP_ERR_NOT_FOUND if there is no NVS partition in the partition table
*/
esp_err_t nvs_flash_erase(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -86,6 +86,17 @@ extern "C" esp_err_t nvs_flash_init(void)
return nvs_flash_init_custom(partition->address / SPI_FLASH_SEC_SIZE, return nvs_flash_init_custom(partition->address / SPI_FLASH_SEC_SIZE,
partition->size / SPI_FLASH_SEC_SIZE); partition->size / SPI_FLASH_SEC_SIZE);
} }
extern "C" esp_err_t nvs_flash_erase()
{
const esp_partition_t* partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
if (partition == NULL) {
return ESP_ERR_NOT_FOUND;
}
return esp_partition_erase_range(partition, 0, partition->size);
}
#endif #endif
static esp_err_t nvs_find_ns_handle(nvs_handle handle, HandleEntry& entry) static esp_err_t nvs_find_ns_handle(nvs_handle handle, HandleEntry& entry)

View File

@ -43,7 +43,14 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param);
void app_main() void app_main()
{ {
nvs_flash_init(); /* Initialize NVS — it is used to store PHY calibration data */
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {

View File

@ -18,6 +18,7 @@
#include "freertos/task.h" #include "freertos/task.h"
#include "bt.h" #include "bt.h"
#include "esp_log.h" #include "esp_log.h"
#include "nvs_flash.h"
static const char *tag = "BLE_ADV"; static const char *tag = "BLE_ADV";
@ -217,6 +218,13 @@ void bleAdvtTask(void *pvParameters)
void app_main() void app_main()
{ {
/* Initialize NVS — it is used to store PHY calibration data */
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {

View File

@ -321,7 +321,14 @@ void app_main()
{ {
esp_err_t ret; esp_err_t ret;
ESP_ERROR_CHECK( nvs_flash_init() ); // Initialize NVS
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
initialise_wifi(); initialise_wifi();
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();

View File

@ -14,7 +14,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "nvs.h"
#include "bt.h" #include "bt.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "esp_log.h" #include "esp_log.h"
@ -34,6 +34,15 @@ void app_main()
{ {
esp_err_t ret; esp_err_t ret;
/* Initialize NVS — it is used to store PHY calibration data */
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
/* As the UART1/2 pin conflict with flash pin, so do matrix of the signal and pin */ /* As the UART1/2 pin conflict with flash pin, so do matrix of the signal and pin */
uart_gpio_reset(); uart_gpio_reset();

View File

@ -24,6 +24,8 @@
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "controller.h" #include "controller.h"
#include "bt.h" #include "bt.h"
@ -409,6 +411,14 @@ void gattc_client_test(void)
void app_main() void app_main()
{ {
// Initialize NVS.
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg); esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BTDM); esp_bt_controller_enable(ESP_BT_MODE_BTDM);

View File

@ -366,6 +366,15 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
void app_main() void app_main()
{ {
esp_err_t ret; esp_err_t ret;
// Initialize NVS.
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg); ret = esp_bt_controller_init(&bt_cfg);
if (ret) { if (ret) {

View File

@ -503,6 +503,14 @@ void app_main()
{ {
esp_err_t ret; esp_err_t ret;
// Initialize NVS.
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg); ret = esp_bt_controller_init(&bt_cfg);
if (ret) { if (ret) {

View File

@ -318,6 +318,14 @@ void app_main()
{ {
esp_err_t ret; esp_err_t ret;
// Initialize NVS.
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ret = esp_bt_controller_init(&bt_cfg); ret = esp_bt_controller_init(&bt_cfg);
if (ret) { if (ret) {

View File

@ -13,7 +13,6 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_partition.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "nvs.h" #include "nvs.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@ -150,11 +149,8 @@ void app_main()
esp_err_t err = nvs_flash_init(); esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) { if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
// NVS partition was truncated and needs to be erased // NVS partition was truncated and needs to be erased
const esp_partition_t* nvs_partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
assert(nvs_partition && "partition table must have an NVS partition");
ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) );
// Retry nvs_flash_init // Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init(); err = nvs_flash_init();
} }
ESP_ERROR_CHECK( err ); ESP_ERROR_CHECK( err );

View File

@ -13,7 +13,6 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_partition.h"
#include "nvs_flash.h" #include "nvs_flash.h"
#include "nvs.h" #include "nvs.h"
@ -23,11 +22,8 @@ void app_main()
esp_err_t err = nvs_flash_init(); esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) { if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
// NVS partition was truncated and needs to be erased // NVS partition was truncated and needs to be erased
const esp_partition_t* nvs_partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
assert(nvs_partition && "partition table must have an NVS partition");
ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) );
// Retry nvs_flash_init // Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init(); err = nvs_flash_init();
} }
ESP_ERROR_CHECK( err ); ESP_ERROR_CHECK( err );

View File

@ -19,7 +19,6 @@
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_ota_ops.h" #include "esp_ota_ops.h"
#include "esp_partition.h"
#include "nvs.h" #include "nvs.h"
#include "nvs_flash.h" #include "nvs_flash.h"
@ -286,10 +285,7 @@ void app_main()
// OTA app partition table has a smaller NVS partition size than the non-OTA // OTA app partition table has a smaller NVS partition size than the non-OTA
// partition table. This size mismatch may cause NVS initialization to fail. // partition table. This size mismatch may cause NVS initialization to fail.
// If this happens, we erase NVS partition and initialize NVS again. // If this happens, we erase NVS partition and initialize NVS again.
const esp_partition_t* nvs_partition = esp_partition_find_first( ESP_ERROR_CHECK(nvs_flash_erase());
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
assert(nvs_partition && "partition table must have an NVS partition");
ESP_ERROR_CHECK( esp_partition_erase_range(nvs_partition, 0, nvs_partition->size) );
err = nvs_flash_init(); err = nvs_flash_init();
} }
ESP_ERROR_CHECK( err ); ESP_ERROR_CHECK( err );

View File

@ -17,6 +17,7 @@
#include "esp_wifi.h" #include "esp_wifi.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "nvs_flash.h"
/*set the ssid and password via "make menuconfig"*/ /*set the ssid and password via "make menuconfig"*/
#define DEFAULT_SSID CONFIG_WIFI_SSID #define DEFAULT_SSID CONFIG_WIFI_SSID
@ -79,5 +80,13 @@ static void wifi_power_save(void)
void app_main() void app_main()
{ {
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
wifi_power_save(); wifi_power_save();
} }

View File

@ -20,6 +20,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "esp_wps.h" #include "esp_wps.h"
#include "esp_event_loop.h" #include "esp_event_loop.h"
#include "nvs_flash.h"
/*set wps mode via "make menuconfig"*/ /*set wps mode via "make menuconfig"*/
@ -106,5 +107,13 @@ static void start_wps(void)
void app_main() void app_main()
{ {
/* Initialize NVS — it is used to store PHY calibration data */
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );
start_wps(); start_wps();
} }