From 6e97936bace204d802cee8d34f6cbfed3a5dee0c Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 15 Nov 2016 18:24:56 +0800 Subject: [PATCH] nvs: allow nvs_flash_init to be called more than once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also don’t assert in nvs_* functions if nvs_flash_init wasn’t called, and make nvs_flash_init_custom an internal API for unit tests. --- components/nvs_flash/include/nvs_flash.h | 10 ----- components/nvs_flash/src/nvs_api.cpp | 9 +++-- components/nvs_flash/src/nvs_platform.hpp | 21 +++++----- components/nvs_flash/src/nvs_storage.cpp | 5 +++ components/nvs_flash/src/nvs_storage.hpp | 2 + components/nvs_flash/src/nvs_test_api.h | 47 +++++++++++++++++++++++ components/nvs_flash/test/test_nvs.cpp | 2 +- 7 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 components/nvs_flash/src/nvs_test_api.h diff --git a/components/nvs_flash/include/nvs_flash.h b/components/nvs_flash/include/nvs_flash.h index eca7f99edd..0162a8f8ac 100644 --- a/components/nvs_flash/include/nvs_flash.h +++ b/components/nvs_flash/include/nvs_flash.h @@ -25,16 +25,6 @@ extern "C" { */ esp_err_t nvs_flash_init(void); -/** - * @brief Initialize NVS flash storage with custom flash sector layout - * @note Make sure specified sectors don't fall within ranges occupied - * by other partitions. - * @param baseSector Flash sector (units of 4096 bytes) offset to start NVS - * @param sectorCount Length (in flash sectors) of NVS region - * @return ESP_OK if flash was successfully initialized - */ -esp_err_t nvs_flash_init_custom(uint32_t baseSector, uint32_t sectorCount); - #ifdef __cplusplus } diff --git a/components/nvs_flash/src/nvs_api.cpp b/components/nvs_flash/src/nvs_api.cpp index b2cb5e7ad4..751542ee12 100644 --- a/components/nvs_flash/src/nvs_api.cpp +++ b/components/nvs_flash/src/nvs_api.cpp @@ -65,6 +65,11 @@ extern "C" void nvs_dump() #ifdef ESP_PLATFORM extern "C" esp_err_t nvs_flash_init(void) { + Lock::init(); + Lock lock; + if (s_nvs_storage.isValid()) { + return ESP_OK; + } const esp_partition_t* partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); if (partition == NULL) { @@ -78,9 +83,7 @@ extern "C" esp_err_t nvs_flash_init(void) extern "C" esp_err_t nvs_flash_init_custom(uint32_t baseSector, uint32_t sectorCount) { - Lock::init(); - Lock lock; - ESP_LOGD(TAG, "init start=%d count=%d", baseSector, sectorCount); + ESP_LOGD(TAG, "nvs_flash_init_custom start=%d count=%d", baseSector, sectorCount); s_nvs_handles.clear(); return s_nvs_storage.init(baseSector, sectorCount); } diff --git a/components/nvs_flash/src/nvs_platform.hpp b/components/nvs_flash/src/nvs_platform.hpp index 374dbca6cc..0973c4875c 100644 --- a/components/nvs_flash/src/nvs_platform.hpp +++ b/components/nvs_flash/src/nvs_platform.hpp @@ -16,9 +16,6 @@ #ifdef ESP_PLATFORM -#define NVS_DEBUGV(...) ets_printf(__VA_ARGS__) - -#include "rom/ets_sys.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -30,19 +27,23 @@ class Lock public: Lock() { - assert(mSemaphore); - xSemaphoreTake(mSemaphore, portMAX_DELAY); + if (mSemaphore) { + xSemaphoreTake(mSemaphore, portMAX_DELAY); + } } ~Lock() { - assert(mSemaphore); - xSemaphoreGive(mSemaphore); + if (mSemaphore) { + xSemaphoreGive(mSemaphore); + } } static esp_err_t init() { - assert(mSemaphore == nullptr); + if (mSemaphore) { + return ESP_OK; + } mSemaphore = xSemaphoreCreateMutex(); if (!mSemaphore) { return ESP_ERR_NO_MEM; @@ -52,7 +53,9 @@ public: static void uninit() { - vSemaphoreDelete(mSemaphore); + if (mSemaphore) { + vSemaphoreDelete(mSemaphore); + } mSemaphore = nullptr; } diff --git a/components/nvs_flash/src/nvs_storage.cpp b/components/nvs_flash/src/nvs_storage.cpp index cacfbd4022..f8da28fa24 100644 --- a/components/nvs_flash/src/nvs_storage.cpp +++ b/components/nvs_flash/src/nvs_storage.cpp @@ -69,6 +69,11 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount) return ESP_OK; } +bool Storage::isValid() const +{ + return mState == StorageState::ACTIVE; +} + esp_err_t Storage::findItem(uint8_t nsIndex, ItemType datatype, const char* key, Page* &page, Item& item) { for (auto it = std::begin(mPageManager); it != std::end(mPageManager); ++it) { diff --git a/components/nvs_flash/src/nvs_storage.hpp b/components/nvs_flash/src/nvs_storage.hpp index f8cee9f2a9..ecf2651ae5 100644 --- a/components/nvs_flash/src/nvs_storage.hpp +++ b/components/nvs_flash/src/nvs_storage.hpp @@ -47,6 +47,8 @@ public: esp_err_t init(uint32_t baseSector, uint32_t sectorCount); + bool isValid() const; + esp_err_t createOrOpenNamespace(const char* nsName, bool canCreate, uint8_t& nsIndex); esp_err_t writeItem(uint8_t nsIndex, ItemType datatype, const char* key, const void* data, size_t dataSize); diff --git a/components/nvs_flash/src/nvs_test_api.h b/components/nvs_flash/src/nvs_test_api.h new file mode 100644 index 0000000000..97940092d5 --- /dev/null +++ b/components/nvs_flash/src/nvs_test_api.h @@ -0,0 +1,47 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nvs_flash.h" + +/** + * @brief Initialize NVS flash storage with custom flash sector layout + * + * @note This API is intended to be used in unit tests. + * + * @param baseSector Flash sector (units of 4096 bytes) offset to start NVS + * @param sectorCount Length (in flash sectors) of NVS region. + NVS partition must be at least 3 sectors long. + * @return ESP_OK if flash was successfully initialized + */ +esp_err_t nvs_flash_init_custom(uint32_t baseSector, uint32_t sectorCount); + + +/** + * @brief Dump contents of NVS storage to stdout + * + * This function may be used for debugging purposes to inspect the state + * of NVS pages. For each page, list of entries is also dumped. + */ +void nvs_dump(void); + + +#ifdef __cplusplus +} +#endif diff --git a/components/nvs_flash/test/test_nvs.cpp b/components/nvs_flash/test/test_nvs.cpp index 81bf7fd216..282d4de48e 100644 --- a/components/nvs_flash/test/test_nvs.cpp +++ b/components/nvs_flash/test/test_nvs.cpp @@ -13,7 +13,7 @@ // limitations under the License. #include "catch.hpp" #include "nvs.hpp" -#include "nvs_flash.h" +#include "nvs_test_api.h" #include "spi_flash_emulation.h" #include #include