nvs: allow nvs_flash_init to be called more than once

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.
This commit is contained in:
Ivan Grokhotkov 2016-11-15 18:24:56 +08:00
parent 51021b06f8
commit 6e97936bac
7 changed files with 73 additions and 23 deletions

View File

@ -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
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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 <sstream>
#include <iostream>