mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
add: Kconfig assert or errorcode option
add: private include header add: macro encapsulation for assertion or error check add: ESP_FAIL return code documentation in public headers change: replaced all assertions by NVS_ASSERT_OR_RETURN macro change: few internal function return values from void to esp_err_t change: ESP_ERR_NVS_VALUE_TOO_LONG macro comment
This commit is contained in:
parent
1f6fad6f48
commit
58cca07104
@ -183,7 +183,8 @@ static const esp_err_msg_t esp_err_msg_table[] = {
|
||||
and call nvs_flash_init again. */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_VALUE_TOO_LONG
|
||||
ERR_TBL_IT(ESP_ERR_NVS_VALUE_TOO_LONG), /* 4366 0x110e String or blob length is longer than
|
||||
ERR_TBL_IT(ESP_ERR_NVS_VALUE_TOO_LONG), /* 4366 0x110e Value doesn't fit into the entry or
|
||||
string or blob length is longer than
|
||||
supported by the implementation */
|
||||
# endif
|
||||
# ifdef ESP_ERR_NVS_PART_NOT_FOUND
|
||||
|
@ -15,7 +15,8 @@ set(srcs "src/nvs_api.cpp"
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
REQUIRES "spi_flash"
|
||||
INCLUDE_DIRS "include")
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_INCLUDE_DIRS "private_include")
|
||||
|
||||
# If we use the linux target, we need to redirect the crc functions to the linux
|
||||
if(${target} STREQUAL "linux")
|
||||
|
@ -20,4 +20,9 @@ menu "NVS"
|
||||
IDF. Hence, if you have any devices where this flag is kept enabled in partition
|
||||
table then enabling this config will allow to have same behavior as pre v4.3 IDF.
|
||||
|
||||
config NVS_ASSERT_ERROR_CHECK
|
||||
bool "Use assertions for error checking"
|
||||
default n
|
||||
help
|
||||
This option switches error checking type between assertions (y) or return codes (n).
|
||||
endmenu
|
||||
|
@ -3,6 +3,8 @@ idf_component_register(SRCS "nvs_page_test.cpp"
|
||||
"."
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../fixtures"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../src"
|
||||
PRIV_INCLUDE_DIRS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../private_include"
|
||||
REQUIRES cmock nvs_flash spi_flash)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PUBLIC --coverage)
|
||||
|
@ -2,3 +2,4 @@ CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n
|
||||
CONFIG_COMPILER_HIDE_PATHS_MACROS=n
|
||||
CONFIG_IDF_TARGET="linux"
|
||||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||||
CONFIG_NVS_ASSERT_ERROR_CHECK=y
|
||||
|
@ -40,7 +40,7 @@ typedef nvs_handle_t nvs_handle IDF_DEPRECATED("Replace with nvs_handle_t");
|
||||
#define ESP_ERR_NVS_INVALID_STATE (ESP_ERR_NVS_BASE + 0x0b) /*!< NVS is in an inconsistent state due to a previous error. Call nvs_flash_init and nvs_open again, then retry. */
|
||||
#define ESP_ERR_NVS_INVALID_LENGTH (ESP_ERR_NVS_BASE + 0x0c) /*!< String or blob length is not sufficient to store data */
|
||||
#define ESP_ERR_NVS_NO_FREE_PAGES (ESP_ERR_NVS_BASE + 0x0d) /*!< NVS partition doesn't contain any empty pages. This may happen if NVS partition was truncated. Erase the whole partition and call nvs_flash_init again. */
|
||||
#define ESP_ERR_NVS_VALUE_TOO_LONG (ESP_ERR_NVS_BASE + 0x0e) /*!< String or blob length is longer than supported by the implementation */
|
||||
#define ESP_ERR_NVS_VALUE_TOO_LONG (ESP_ERR_NVS_BASE + 0x0e) /*!< Value doesn't fit into the entry or string or blob length is longer than supported by the implementation */
|
||||
#define ESP_ERR_NVS_PART_NOT_FOUND (ESP_ERR_NVS_BASE + 0x0f) /*!< Partition with specified name is not found in the partition table */
|
||||
|
||||
#define ESP_ERR_NVS_NEW_VERSION_FOUND (ESP_ERR_NVS_BASE + 0x10) /*!< NVS partition contains data in new format and cannot be recognized by this version of code */
|
||||
@ -124,6 +124,8 @@ typedef struct nvs_opaque_iterator_t *nvs_iterator_t;
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if storage handle was opened successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized
|
||||
* - ESP_ERR_NVS_PART_NOT_FOUND if the partition with label "nvs" is not found
|
||||
* - ESP_ERR_NVS_NOT_FOUND id namespace doesn't exist yet and
|
||||
@ -151,6 +153,8 @@ esp_err_t nvs_open(const char* name, nvs_open_mode_t open_mode, nvs_handle_t *ou
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if storage handle was opened successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized
|
||||
* - ESP_ERR_NVS_PART_NOT_FOUND if the partition with specified name is not found
|
||||
* - ESP_ERR_NVS_NOT_FOUND id namespace doesn't exist yet and
|
||||
@ -175,6 +179,8 @@ esp_err_t nvs_open_from_partition(const char *part_name, const char* name, nvs_o
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if value was set successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@ -282,6 +288,8 @@ esp_err_t nvs_set_str (nvs_handle_t handle, const char* key, const char* value);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if value was set successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if storage handle was opened as read only
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@ -325,6 +333,8 @@ esp_err_t nvs_set_blob(nvs_handle_t handle, const char* key, const void* value,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if the value was retrieved successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@ -432,6 +442,8 @@ esp_err_t nvs_get_u64 (nvs_handle_t handle, const char* key, uint64_t* out_value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if the value was retrieved successfully
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_INVALID_NAME if key name doesn't satisfy constraints
|
||||
@ -459,6 +471,8 @@ esp_err_t nvs_get_blob(nvs_handle_t handle, const char* key, void* out_value, si
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
@ -476,6 +490,8 @@ esp_err_t nvs_erase_key(nvs_handle_t handle, const char* key);
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - other error codes from the underlying storage driver
|
||||
|
18
components/nvs_flash/private_include/nvs_internal.h
Normal file
18
components/nvs_flash/private_include/nvs_internal.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef NVS_INTERNAL_H
|
||||
#define NVS_INTERNAL_H
|
||||
|
||||
#if CONFIG_NVS_ASSERT_ERROR_CHECK
|
||||
#define NVS_ASSERT_OR_RETURN(condition, retcode) assert(condition);
|
||||
#else
|
||||
#define NVS_ASSERT_OR_RETURN(condition, retcode) \
|
||||
if (!(condition)) { \
|
||||
return retcode; \
|
||||
}
|
||||
#endif // CONFIG_NVS_ASSERT_ERROR_CHECK
|
||||
|
||||
#endif // NVS_INTERNAL_H
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef compressed_enum_table_h
|
||||
#define compressed_enum_table_h
|
||||
@ -18,6 +10,8 @@
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include "nvs_internal.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
template<typename Tenum, size_t Nbits, size_t Nitems>
|
||||
class CompressedEnumTable
|
||||
@ -33,23 +27,25 @@ public:
|
||||
return mData;
|
||||
}
|
||||
|
||||
Tenum get(size_t index) const
|
||||
esp_err_t get(size_t index, Tenum *retval) const
|
||||
{
|
||||
assert(index < Nitems);
|
||||
NVS_ASSERT_OR_RETURN(index < Nitems, ESP_FAIL);
|
||||
size_t wordIndex = index / ITEMS_PER_WORD;
|
||||
size_t offset = (index % ITEMS_PER_WORD) * Nbits;
|
||||
|
||||
return static_cast<Tenum>((mData[wordIndex] >> offset) & VALUE_MASK);
|
||||
*retval = static_cast<Tenum>((mData[wordIndex] >> offset) & VALUE_MASK);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void set(size_t index, Tenum val)
|
||||
esp_err_t set(size_t index, Tenum val)
|
||||
{
|
||||
assert(index < Nitems);
|
||||
NVS_ASSERT_OR_RETURN(index < Nitems, ESP_FAIL);
|
||||
size_t wordIndex = index / ITEMS_PER_WORD;
|
||||
size_t offset = (index % ITEMS_PER_WORD) * Nbits;
|
||||
|
||||
uint32_t v = static_cast<uint32_t>(val) << offset;
|
||||
mData[wordIndex] = (mData[wordIndex] & ~(VALUE_MASK << offset)) | v;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static constexpr size_t getWordIndex(size_t index)
|
||||
|
@ -1,25 +1,17 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef nvs_hpp
|
||||
#define nvs_hpp
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include "nvs.h"
|
||||
#include "nvs_types.hpp"
|
||||
#include "nvs_page.hpp"
|
||||
#include "nvs_pagemanager.hpp"
|
||||
#include "nvs_storage.hpp"
|
||||
#include "nvs_internal.h"
|
||||
|
||||
#endif /* nvs_hpp */
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
#include "nvs.hpp"
|
||||
#include "nvs_flash.h"
|
||||
@ -23,6 +15,7 @@
|
||||
#include "nvs_handle_simple.hpp"
|
||||
#include "esp_err.h"
|
||||
#include <esp_rom_crc.h>
|
||||
#include "nvs_internal.h"
|
||||
|
||||
// Uncomment this line to force output from this module
|
||||
// #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
@ -752,7 +745,7 @@ extern "C" nvs_iterator_t nvs_entry_find(const char *part_name, const char *name
|
||||
extern "C" nvs_iterator_t nvs_entry_next(nvs_iterator_t it)
|
||||
{
|
||||
Lock lock;
|
||||
assert(it);
|
||||
NVS_ASSERT_OR_RETURN(it, nullptr);
|
||||
|
||||
bool entryFound = it->storage->nextEntry(it);
|
||||
if (!entryFound) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <esp_rom_crc.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "nvs_internal.h"
|
||||
|
||||
namespace nvs
|
||||
{
|
||||
@ -79,7 +80,7 @@ esp_err_t Page::load(Partition *partition, uint32_t sectorNumber)
|
||||
case PageState::FULL:
|
||||
case PageState::ACTIVE:
|
||||
case PageState::FREEING:
|
||||
mLoadEntryTable();
|
||||
return mLoadEntryTable();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -92,9 +93,13 @@ esp_err_t Page::load(Partition *partition, uint32_t sectorNumber)
|
||||
|
||||
esp_err_t Page::writeEntry(const Item& item)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t phyAddr;
|
||||
esp_err_t err = getEntryAddress(mNextFreeEntry, &phyAddr);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
err = mPartition->write(phyAddr, &item, sizeof(item));
|
||||
|
||||
err = mPartition->write(getEntryAddress(mNextFreeEntry), &item, sizeof(item));
|
||||
|
||||
if (err != ESP_OK) {
|
||||
mState = PageState::INVALID;
|
||||
@ -118,9 +123,9 @@ esp_err_t Page::writeEntry(const Item& item)
|
||||
|
||||
esp_err_t Page::writeEntryData(const uint8_t* data, size_t size)
|
||||
{
|
||||
assert(size % ENTRY_SIZE == 0);
|
||||
assert(mNextFreeEntry != INVALID_ENTRY);
|
||||
assert(mFirstUsedEntry != INVALID_ENTRY);
|
||||
NVS_ASSERT_OR_RETURN(size % ENTRY_SIZE == 0, ESP_FAIL);
|
||||
NVS_ASSERT_OR_RETURN(mNextFreeEntry != INVALID_ENTRY, ESP_FAIL);
|
||||
NVS_ASSERT_OR_RETURN(mFirstUsedEntry != INVALID_ENTRY, ESP_FAIL);
|
||||
const uint16_t count = size / ENTRY_SIZE;
|
||||
|
||||
const uint8_t* buf = data;
|
||||
@ -143,7 +148,11 @@ esp_err_t Page::writeEntryData(const uint8_t* data, size_t size)
|
||||
}
|
||||
#endif // ! LINUX_TARGET
|
||||
|
||||
auto rc = mPartition->write(getEntryAddress(mNextFreeEntry), buf, size);
|
||||
uint32_t phyAddr;
|
||||
esp_err_t rc = getEntryAddress(mNextFreeEntry, &phyAddr);
|
||||
if (rc == ESP_OK) {
|
||||
rc = mPartition->write(phyAddr, buf, size);
|
||||
}
|
||||
|
||||
#if !defined LINUX_TARGET
|
||||
if (buf != data) {
|
||||
@ -205,8 +214,8 @@ esp_err_t Page::writeItem(uint8_t nsIndex, ItemType datatype, const char* key, c
|
||||
}
|
||||
|
||||
// primitive types should fit into one entry
|
||||
assert(totalSize == ENTRY_SIZE ||
|
||||
isVariableLengthType(datatype));
|
||||
NVS_ASSERT_OR_RETURN(totalSize == ENTRY_SIZE ||
|
||||
isVariableLengthType(datatype), ESP_ERR_NVS_VALUE_TOO_LONG);
|
||||
|
||||
if (mNextFreeEntry == INVALID_ENTRY || mNextFreeEntry + entriesCount > ENTRY_COUNT) {
|
||||
// page will not fit this amount of data
|
||||
@ -388,7 +397,12 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
|
||||
{
|
||||
uint32_t seq_num;
|
||||
getSeqNumber(seq_num);
|
||||
auto state = mEntryTable.get(index);
|
||||
|
||||
EntryState state;
|
||||
esp_err_t err = mEntryTable.get(index, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
size_t span = 1;
|
||||
if (state == EntryState::WRITTEN) {
|
||||
@ -409,7 +423,11 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
|
||||
mHashList.erase(index);
|
||||
span = item.span;
|
||||
for (ptrdiff_t i = index + span - 1; i >= static_cast<ptrdiff_t>(index); --i) {
|
||||
if (mEntryTable.get(i) == EntryState::WRITTEN) {
|
||||
rc = mEntryTable.get(i, &state);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
if (state == EntryState::WRITTEN) {
|
||||
--mUsedEntryCount;
|
||||
}
|
||||
++mErasedEntryCount;
|
||||
@ -431,7 +449,10 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
|
||||
}
|
||||
|
||||
if (index == mFirstUsedEntry) {
|
||||
updateFirstUsedEntry(index, span);
|
||||
auto rc = updateFirstUsedEntry(index, span);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (index + span > mNextFreeEntry) {
|
||||
@ -441,20 +462,27 @@ esp_err_t Page::eraseEntryAndSpan(size_t index)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void Page::updateFirstUsedEntry(size_t index, size_t span)
|
||||
esp_err_t Page::updateFirstUsedEntry(size_t index, size_t span)
|
||||
{
|
||||
assert(index == mFirstUsedEntry);
|
||||
NVS_ASSERT_OR_RETURN(index == mFirstUsedEntry, ESP_FAIL);
|
||||
mFirstUsedEntry = INVALID_ENTRY;
|
||||
size_t end = mNextFreeEntry;
|
||||
EntryState state;
|
||||
esp_err_t err;
|
||||
if (end > ENTRY_COUNT) {
|
||||
end = ENTRY_COUNT;
|
||||
}
|
||||
for (size_t i = index + span; i < end; ++i) {
|
||||
if (mEntryTable.get(i) == EntryState::WRITTEN) {
|
||||
err = mEntryTable.get(i, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state == EntryState::WRITTEN) {
|
||||
mFirstUsedEntry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Page::copyItems(Page& other)
|
||||
@ -472,15 +500,20 @@ esp_err_t Page::copyItems(Page& other)
|
||||
|
||||
Item entry;
|
||||
size_t readEntryIndex = mFirstUsedEntry;
|
||||
EntryState state;
|
||||
esp_err_t err;
|
||||
|
||||
while (readEntryIndex < ENTRY_COUNT) {
|
||||
|
||||
if (mEntryTable.get(readEntryIndex) != EntryState::WRITTEN) {
|
||||
assert(readEntryIndex != mFirstUsedEntry);
|
||||
err = mEntryTable.get(readEntryIndex, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state != EntryState::WRITTEN) {
|
||||
NVS_ASSERT_OR_RETURN(readEntryIndex != mFirstUsedEntry, ESP_FAIL);
|
||||
readEntryIndex++;
|
||||
continue;
|
||||
}
|
||||
auto err = readEntry(readEntryIndex, entry);
|
||||
err = readEntry(readEntryIndex, entry);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@ -497,7 +530,7 @@ esp_err_t Page::copyItems(Page& other)
|
||||
size_t span = entry.span;
|
||||
size_t end = readEntryIndex + span;
|
||||
|
||||
assert(end <= ENTRY_COUNT);
|
||||
NVS_ASSERT_OR_RETURN(end <= ENTRY_COUNT, ESP_FAIL);
|
||||
|
||||
for (size_t i = readEntryIndex + 1; i < end; ++i) {
|
||||
readEntry(i, entry);
|
||||
@ -526,16 +559,21 @@ esp_err_t Page::mLoadEntryTable()
|
||||
}
|
||||
}
|
||||
|
||||
EntryState state;
|
||||
esp_err_t err;
|
||||
mErasedEntryCount = 0;
|
||||
mUsedEntryCount = 0;
|
||||
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
||||
auto s = mEntryTable.get(i);
|
||||
if (s == EntryState::WRITTEN) {
|
||||
err = mEntryTable.get(i, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state == EntryState::WRITTEN) {
|
||||
if (mFirstUsedEntry == INVALID_ENTRY) {
|
||||
mFirstUsedEntry = i;
|
||||
}
|
||||
++mUsedEntryCount;
|
||||
} else if (s == EntryState::ERASED) {
|
||||
} else if (state == EntryState::ERASED) {
|
||||
++mErasedEntryCount;
|
||||
}
|
||||
}
|
||||
@ -544,7 +582,11 @@ esp_err_t Page::mLoadEntryTable()
|
||||
// as such, we need to figure out where the first unused entry is
|
||||
if (mState == PageState::ACTIVE) {
|
||||
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
||||
if (mEntryTable.get(i) == EntryState::EMPTY) {
|
||||
err = mEntryTable.get(i, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state == EntryState::EMPTY) {
|
||||
mNextFreeEntry = i;
|
||||
break;
|
||||
}
|
||||
@ -555,7 +597,11 @@ esp_err_t Page::mLoadEntryTable()
|
||||
// entry state table may actually be half-written.
|
||||
// this is easy to check by reading EntryHeader (i.e. first word)
|
||||
while (mNextFreeEntry < ENTRY_COUNT) {
|
||||
uint32_t entryAddress = getEntryAddress(mNextFreeEntry);
|
||||
uint32_t entryAddress;
|
||||
err = getEntryAddress(mNextFreeEntry, &entryAddress);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
uint32_t header;
|
||||
auto rc = mPartition->read_raw(entryAddress, &header, sizeof(header));
|
||||
if (rc != ESP_OK) {
|
||||
@ -563,8 +609,12 @@ esp_err_t Page::mLoadEntryTable()
|
||||
return rc;
|
||||
}
|
||||
if (header != 0xffffffff) {
|
||||
auto oldState = mEntryTable.get(mNextFreeEntry);
|
||||
auto err = alterEntryState(mNextFreeEntry, EntryState::ERASED);
|
||||
auto oldState = state;
|
||||
rc = mEntryTable.get(mNextFreeEntry, &oldState);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
err = alterEntryState(mNextFreeEntry, EntryState::ERASED);
|
||||
if (err != ESP_OK) {
|
||||
mState = PageState::INVALID;
|
||||
return err;
|
||||
@ -590,12 +640,16 @@ esp_err_t Page::mLoadEntryTable()
|
||||
size_t span;
|
||||
for (size_t i = 0; i < end; i += span) {
|
||||
span = 1;
|
||||
if (mEntryTable.get(i) == EntryState::ERASED) {
|
||||
err = mEntryTable.get(i, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state == EntryState::ERASED) {
|
||||
lastItemIndex = INVALID_ENTRY;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mEntryTable.get(i) == EntryState::ILLEGAL) {
|
||||
if (state == EntryState::ILLEGAL) {
|
||||
lastItemIndex = INVALID_ENTRY;
|
||||
auto err = eraseEntryAndSpan(i);
|
||||
if (err != ESP_OK) {
|
||||
@ -635,7 +689,11 @@ esp_err_t Page::mLoadEntryTable()
|
||||
span = item.span;
|
||||
bool needErase = false;
|
||||
for (size_t j = i; j < i + span; ++j) {
|
||||
if (mEntryTable.get(j) != EntryState::WRITTEN) {
|
||||
err = mEntryTable.get(j, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state != EntryState::WRITTEN) {
|
||||
needErase = true;
|
||||
lastItemIndex = INVALID_ENTRY;
|
||||
break;
|
||||
@ -675,11 +733,15 @@ esp_err_t Page::mLoadEntryTable()
|
||||
// Do the same for the case when page is in full or freeing state.
|
||||
Item item;
|
||||
for (size_t i = mFirstUsedEntry; i < ENTRY_COUNT; ++i) {
|
||||
if (mEntryTable.get(i) != EntryState::WRITTEN) {
|
||||
auto err = mEntryTable.get(i, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state != EntryState::WRITTEN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto err = readEntry(i, item);
|
||||
err = readEntry(i, item);
|
||||
if (err != ESP_OK) {
|
||||
mState = PageState::INVALID;
|
||||
return err;
|
||||
@ -694,7 +756,7 @@ esp_err_t Page::mLoadEntryTable()
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(item.span > 0);
|
||||
NVS_ASSERT_OR_RETURN(item.span > 0, ESP_FAIL);
|
||||
|
||||
err = mHashList.insert(item, i);
|
||||
if (err != ESP_OK) {
|
||||
@ -706,7 +768,11 @@ esp_err_t Page::mLoadEntryTable()
|
||||
|
||||
if (isVariableLengthType(item.datatype)) {
|
||||
for (size_t j = i + 1; j < i + span; ++j) {
|
||||
if (mEntryTable.get(j) != EntryState::WRITTEN) {
|
||||
err = mEntryTable.get(j, &state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
if (state != EntryState::WRITTEN) {
|
||||
eraseEntryAndSpan(i);
|
||||
break;
|
||||
}
|
||||
@ -724,7 +790,7 @@ esp_err_t Page::mLoadEntryTable()
|
||||
|
||||
esp_err_t Page::initialize()
|
||||
{
|
||||
assert(mState == PageState::UNINITIALIZED);
|
||||
NVS_ASSERT_OR_RETURN(mState == PageState::UNINITIALIZED, ESP_FAIL);
|
||||
mState = PageState::ACTIVE;
|
||||
Header header;
|
||||
header.mState = mState;
|
||||
@ -745,26 +811,33 @@ esp_err_t Page::initialize()
|
||||
|
||||
esp_err_t Page::alterEntryState(size_t index, EntryState state)
|
||||
{
|
||||
assert(index < ENTRY_COUNT);
|
||||
mEntryTable.set(index, state);
|
||||
NVS_ASSERT_OR_RETURN(index < ENTRY_COUNT, ESP_FAIL);
|
||||
esp_err_t err = mEntryTable.set(index, state);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
size_t wordToWrite = mEntryTable.getWordIndex(index);
|
||||
uint32_t word = mEntryTable.data()[wordToWrite];
|
||||
auto rc = mPartition->write_raw(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast<uint32_t>(wordToWrite) * 4,
|
||||
err = mPartition->write_raw(mBaseAddress + ENTRY_TABLE_OFFSET + static_cast<uint32_t>(wordToWrite) * 4,
|
||||
&word, sizeof(word));
|
||||
if (rc != ESP_OK) {
|
||||
if (err != ESP_OK) {
|
||||
mState = PageState::INVALID;
|
||||
return rc;
|
||||
return err;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t Page::alterEntryRangeState(size_t begin, size_t end, EntryState state)
|
||||
{
|
||||
assert(end <= ENTRY_COUNT);
|
||||
assert(end > begin);
|
||||
NVS_ASSERT_OR_RETURN(end <= ENTRY_COUNT, ESP_FAIL);
|
||||
NVS_ASSERT_OR_RETURN(end > begin, ESP_FAIL);
|
||||
size_t wordIndex = mEntryTable.getWordIndex(end - 1);
|
||||
esp_err_t err;
|
||||
for (ptrdiff_t i = end - 1; i >= static_cast<ptrdiff_t>(begin); --i) {
|
||||
mEntryTable.set(i, state);
|
||||
err = mEntryTable.set(i, state);
|
||||
if (err != ESP_OK){
|
||||
return err;
|
||||
}
|
||||
size_t nextWordIndex;
|
||||
if (i == static_cast<ptrdiff_t>(begin)) {
|
||||
nextWordIndex = (size_t) -1;
|
||||
@ -798,7 +871,12 @@ esp_err_t Page::alterPageState(PageState state)
|
||||
|
||||
esp_err_t Page::readEntry(size_t index, Item& dst) const
|
||||
{
|
||||
auto rc = mPartition->read(getEntryAddress(index), &dst, sizeof(dst));
|
||||
uint32_t phyAddr;
|
||||
esp_err_t rc = getEntryAddress(index, &phyAddr);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
rc = mPartition->read(phyAddr, &dst, sizeof(dst));
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
@ -836,13 +914,19 @@ esp_err_t Page::findItem(uint8_t nsIndex, ItemType datatype, const char* key, si
|
||||
}
|
||||
|
||||
size_t next;
|
||||
EntryState state;
|
||||
esp_err_t rc;
|
||||
for (size_t i = start; i < end; i = next) {
|
||||
next = i + 1;
|
||||
if (mEntryTable.get(i) != EntryState::WRITTEN) {
|
||||
rc = mEntryTable.get(i, &state);
|
||||
if (rc != ESP_OK) {
|
||||
return rc;
|
||||
}
|
||||
if (state != EntryState::WRITTEN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto rc = readEntry(i, item);
|
||||
rc = readEntry(i, item);
|
||||
if (rc != ESP_OK) {
|
||||
mState = PageState::INVALID;
|
||||
return rc;
|
||||
@ -1009,7 +1093,11 @@ void Page::debugDump() const
|
||||
size_t skip = 0;
|
||||
for (size_t i = 0; i < ENTRY_COUNT; ++i) {
|
||||
printf("%3d: ", static_cast<int>(i));
|
||||
EntryState state = mEntryTable.get(i);
|
||||
EntryState state;
|
||||
if (mEntryTable.get(i, &state) != ESP_OK) {
|
||||
printf("Failed to read entry state\n");
|
||||
return;
|
||||
}
|
||||
if (state == EntryState::EMPTY) {
|
||||
printf("E\n");
|
||||
} else if (state == EntryState::ERASED) {
|
||||
@ -1034,7 +1122,7 @@ void Page::debugDump() const
|
||||
|
||||
esp_err_t Page::calcEntries(nvs_stats_t &nvsStats)
|
||||
{
|
||||
assert(mState != PageState::FREEING);
|
||||
NVS_ASSERT_OR_RETURN(mState != PageState::FREEING, ESP_FAIL);
|
||||
|
||||
nvsStats.total_entries += ENTRY_COUNT;
|
||||
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef nvs_page_hpp
|
||||
#define nvs_page_hpp
|
||||
|
||||
@ -197,17 +189,18 @@ protected:
|
||||
|
||||
esp_err_t eraseEntryAndSpan(size_t index);
|
||||
|
||||
void updateFirstUsedEntry(size_t index, size_t span);
|
||||
esp_err_t updateFirstUsedEntry(size_t index, size_t span);
|
||||
|
||||
static constexpr size_t getAlignmentForType(ItemType type)
|
||||
{
|
||||
return static_cast<uint8_t>(type) & 0x0f;
|
||||
}
|
||||
|
||||
uint32_t getEntryAddress(size_t entry) const
|
||||
esp_err_t getEntryAddress(size_t entry, uint32_t *address) const
|
||||
{
|
||||
assert(entry < ENTRY_COUNT);
|
||||
return mBaseAddress + ENTRY_DATA_OFFSET + static_cast<uint32_t>(entry) * ENTRY_SIZE;
|
||||
NVS_ASSERT_OR_RETURN(entry < ENTRY_COUNT, ESP_FAIL);
|
||||
*address = mBaseAddress + ENTRY_DATA_OFFSET + static_cast<uint32_t>(entry) * ENTRY_SIZE;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static const char* pageStateToName(PageState ps);
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "nvs_pagemanager.hpp"
|
||||
|
||||
namespace nvs
|
||||
@ -191,7 +183,7 @@ esp_err_t PageManager::requestNewPage()
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(usedEntries == newPage->getUsedEntryCount());
|
||||
NVS_ASSERT_OR_RETURN(usedEntries == newPage->getUsedEntryCount(), ESP_FAIL);
|
||||
#endif
|
||||
|
||||
mPageList.erase(maxUnusedItemsPageIt);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "esp_partition.h"
|
||||
#include "nvs_partition_manager.hpp"
|
||||
#include "nvs_partition_lookup.hpp"
|
||||
#include "nvs_internal.h"
|
||||
|
||||
#ifdef CONFIG_NVS_ENCRYPTION
|
||||
#include "nvs_encrypted_partition.hpp"
|
||||
@ -39,7 +40,7 @@ esp_err_t NVSPartitionManager::init_partition(const char *partition_label)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
assert(SPI_FLASH_SEC_SIZE != 0);
|
||||
NVS_ASSERT_OR_RETURN(SPI_FLASH_SEC_SIZE != 0, ESP_FAIL);
|
||||
|
||||
NVSPartition *p = nullptr;
|
||||
esp_err_t result = partition_lookup::lookup_nvs_partition(partition_label, &p);
|
||||
|
@ -110,14 +110,23 @@ esp_err_t Storage::init(uint32_t baseSector, uint32_t sectorCount)
|
||||
}
|
||||
|
||||
item.getKey(entry->mName, sizeof(entry->mName));
|
||||
item.getValue(entry->mIndex);
|
||||
err = item.getValue(entry->mIndex);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
mNamespaces.push_back(entry);
|
||||
mNamespaceUsage.set(entry->mIndex, true);
|
||||
if (mNamespaceUsage.set(entry->mIndex, true) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
itemIndex += item.span;
|
||||
}
|
||||
}
|
||||
mNamespaceUsage.set(0, true);
|
||||
mNamespaceUsage.set(255, true);
|
||||
if (mNamespaceUsage.set(0, true) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (mNamespaceUsage.set(255, true) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
mState = StorageState::ACTIVE;
|
||||
|
||||
// Populate list of multi-page index entries.
|
||||
@ -204,15 +213,17 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
|
||||
}
|
||||
|
||||
/* Split the blob into two and store the chunk of available size onto the current page */
|
||||
assert(tailroom != 0);
|
||||
NVS_ASSERT_OR_RETURN(tailroom != 0, ESP_FAIL);
|
||||
|
||||
chunkSize = (remainingSize > tailroom)? tailroom : remainingSize;
|
||||
remainingSize -= chunkSize;
|
||||
|
||||
err = page.writeItem(nsIndex, ItemType::BLOB_DATA, key,
|
||||
static_cast<const uint8_t*> (data) + offset, chunkSize, static_cast<uint8_t> (chunkStart) + chunkCount);
|
||||
chunkCount++;
|
||||
assert(err != ESP_ERR_NVS_PAGE_FULL);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
NVS_ASSERT_OR_RETURN(err != ESP_ERR_NVS_PAGE_FULL, err);
|
||||
break;
|
||||
} else {
|
||||
UsedPageNode* node = new (std::nothrow) UsedPageNode();
|
||||
@ -245,7 +256,7 @@ esp_err_t Storage::writeMultiPageBlob(uint8_t nsIndex, const char* key, const vo
|
||||
item.blobIndex.chunkStart = chunkStart;
|
||||
|
||||
err = getCurrentPage().writeItem(nsIndex, ItemType::BLOB_IDX, key, item.data, sizeof(item.data));
|
||||
assert(err != ESP_ERR_NVS_PAGE_FULL);
|
||||
NVS_ASSERT_OR_RETURN(err != ESP_ERR_NVS_PAGE_FULL, err);
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
@ -298,7 +309,8 @@ esp_err_t Storage::writeItem(uint8_t nsIndex, ItemType datatype, const char* key
|
||||
}
|
||||
/* Get the version of the previous index with same <ns,key> */
|
||||
prevStart = item.blobIndex.chunkStart;
|
||||
assert(prevStart == VerOffset::VER_0_OFFSET || prevStart == VerOffset::VER_1_OFFSET);
|
||||
NVS_ASSERT_OR_RETURN(prevStart == VerOffset::VER_0_OFFSET || prevStart == VerOffset::VER_1_OFFSET, ESP_FAIL);
|
||||
|
||||
|
||||
/* Toggle the version by changing the offset */
|
||||
nextStart
|
||||
@ -401,8 +413,12 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
|
||||
}
|
||||
|
||||
uint8_t ns;
|
||||
bool ns_state;
|
||||
for (ns = 1; ns < 255; ++ns) {
|
||||
if (mNamespaceUsage.get(ns) == false) {
|
||||
if (mNamespaceUsage.get(ns, &ns_state) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (!ns_state) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -415,7 +431,9 @@ esp_err_t Storage::createOrOpenNamespace(const char* nsName, bool canCreate, uin
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
mNamespaceUsage.set(ns, true);
|
||||
if (mNamespaceUsage.set(ns, true) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
nsIndex = ns;
|
||||
|
||||
NamespaceEntry* entry = new (std::nothrow) NamespaceEntry;
|
||||
@ -449,7 +467,7 @@ esp_err_t Storage::readMultiPageBlob(uint8_t nsIndex, const char* key, void* dat
|
||||
VerOffset chunkStart = item.blobIndex.chunkStart;
|
||||
size_t offset = 0;
|
||||
|
||||
assert(dataSize == item.blobIndex.dataSize);
|
||||
NVS_ASSERT_OR_RETURN(dataSize == item.blobIndex.dataSize, ESP_FAIL);
|
||||
|
||||
/* Now read corresponding chunks */
|
||||
for (uint8_t chunkNum = 0; chunkNum < chunkCount; chunkNum++) {
|
||||
@ -464,12 +482,12 @@ esp_err_t Storage::readMultiPageBlob(uint8_t nsIndex, const char* key, void* dat
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
assert(static_cast<uint8_t> (chunkStart) + chunkNum == item.chunkIndex);
|
||||
NVS_ASSERT_OR_RETURN(static_cast<uint8_t> (chunkStart) + chunkNum == item.chunkIndex, ESP_FAIL);
|
||||
|
||||
offset += item.varLength.dataSize;
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
assert(offset == dataSize);
|
||||
}
|
||||
NVS_ASSERT_OR_RETURN(offset == dataSize, ESP_FAIL);
|
||||
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
eraseMultiPageBlob(nsIndex, key); // cleanup if a chunk is not found
|
||||
}
|
||||
@ -509,12 +527,12 @@ esp_err_t Storage::cmpMultiPageBlob(uint8_t nsIndex, const char* key, const void
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
assert(static_cast<uint8_t> (chunkStart) + chunkNum == item.chunkIndex);
|
||||
NVS_ASSERT_OR_RETURN(static_cast<uint8_t> (chunkStart) + chunkNum == item.chunkIndex, ESP_FAIL);
|
||||
|
||||
offset += item.varLength.dataSize;
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
assert(offset == dataSize);
|
||||
}
|
||||
NVS_ASSERT_OR_RETURN(offset == dataSize, ESP_FAIL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -564,7 +582,7 @@ esp_err_t Storage::eraseMultiPageBlob(uint8_t nsIndex, const char* key, VerOffse
|
||||
if (chunkStart == VerOffset::VER_ANY) {
|
||||
chunkStart = item.blobIndex.chunkStart;
|
||||
} else {
|
||||
assert(chunkStart == item.blobIndex.chunkStart);
|
||||
NVS_ASSERT_OR_RETURN(chunkStart == item.blobIndex.chunkStart, ESP_FAIL);
|
||||
}
|
||||
|
||||
/* Now erase corresponding chunks*/
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef nvs_types_h
|
||||
#define nvs_types_h
|
||||
|
||||
@ -110,10 +102,11 @@ public:
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void getValue(T& dst)
|
||||
esp_err_t getValue(T& dst)
|
||||
{
|
||||
assert(itemTypeOf(dst) == datatype);
|
||||
NVS_ASSERT_OR_RETURN(itemTypeOf(dst) == datatype, ESP_FAIL);
|
||||
dst = *reinterpret_cast<T*>(data);
|
||||
return ESP_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ else
|
||||
COMPILER := gcc
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I../include -I../src -I../../esp_rom/include -I../../esp_rom/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../hal/include -I ../../xtensa/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb
|
||||
CPPFLAGS += -I../private_include -I../include -I../src -I../../esp_rom/include -I../../esp_rom/include/linux -I../../log/include -I./ -I../../esp_common/include -I../../esp32/include -I ../../mbedtls/mbedtls/include -I ../../spi_flash/include -I ../../hal/include -I ../../xtensa/include -I ../../../tools/catch -fprofile-arcs -ftest-coverage -g2 -ggdb
|
||||
CFLAGS += -fprofile-arcs -ftest-coverage -DLINUX_TARGET
|
||||
CXXFLAGS += -std=c++11 -Wall -Werror -DLINUX_TARGET
|
||||
LDFLAGS += -lstdc++ -Wall -fprofile-arcs -ftest-coverage
|
||||
|
@ -4,3 +4,4 @@
|
||||
#define CONFIG_LOG_MAXIMUM_LEVEL 3
|
||||
#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1
|
||||
#define CONFIG_IDF_TARGET_LINUX 1
|
||||
#define CONFIG_NVS_ASSERT_ERROR_CHECK 1
|
||||
|
@ -1,16 +1,8 @@
|
||||
// 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.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "catch.hpp"
|
||||
#include "compressed_enum_table.hpp"
|
||||
#include <cstring>
|
||||
@ -27,26 +19,28 @@ TEST_CASE("test if CompressedEnumTable works as expected", "[enumtable]")
|
||||
};
|
||||
CompressedEnumTable<TEnum1, 2, 252> table;
|
||||
memset(table.data(), 0xff, table.byteSize());
|
||||
TEnum1 tmp;
|
||||
for (size_t i = 0; i < table.count(); ++i) {
|
||||
CHECK(table.get(i) == TEnum1::THREE);
|
||||
CHECK(table.get(i, &tmp) == ESP_OK);
|
||||
CHECK(tmp == TEnum1::THREE);
|
||||
}
|
||||
|
||||
table.set(0, TEnum1::ONE);
|
||||
table.set(1, TEnum1::TWO);
|
||||
table.set(2, TEnum1::ZERO);
|
||||
table.set(3, TEnum1::ONE);
|
||||
table.set(4, TEnum1::TWO);
|
||||
table.set(5, TEnum1::ZERO);
|
||||
table.set(6, TEnum1::ONE);
|
||||
table.set(7, TEnum1::TWO);
|
||||
table.set(8, TEnum1::ZERO);
|
||||
table.set(9, TEnum1::ZERO);
|
||||
table.set(10, TEnum1::ONE);
|
||||
table.set(11, TEnum1::TWO);
|
||||
CHECK(table.set(0, TEnum1::ONE) == ESP_OK);
|
||||
CHECK(table.set(1, TEnum1::TWO) == ESP_OK);
|
||||
CHECK(table.set(2, TEnum1::ZERO) == ESP_OK);
|
||||
CHECK(table.set(3, TEnum1::ONE) == ESP_OK);
|
||||
CHECK(table.set(4, TEnum1::TWO) == ESP_OK);
|
||||
CHECK(table.set(5, TEnum1::ZERO) == ESP_OK);
|
||||
CHECK(table.set(6, TEnum1::ONE) == ESP_OK);
|
||||
CHECK(table.set(7, TEnum1::TWO) == ESP_OK);
|
||||
CHECK(table.set(8, TEnum1::ZERO) == ESP_OK);
|
||||
CHECK(table.set(9, TEnum1::ZERO) == ESP_OK);
|
||||
CHECK(table.set(10, TEnum1::ONE) == ESP_OK);
|
||||
CHECK(table.set(11, TEnum1::TWO) == ESP_OK);
|
||||
// table.set(12, ...
|
||||
table.set(13, TEnum1::ZERO);
|
||||
table.set(14, TEnum1::ONE);
|
||||
table.set(15, TEnum1::TWO);
|
||||
CHECK(table.set(13, TEnum1::ZERO) == ESP_OK);
|
||||
CHECK(table.set(14, TEnum1::ONE) == ESP_OK);
|
||||
CHECK(table.set(15, TEnum1::TWO) == ESP_OK);
|
||||
|
||||
// b10010011100100001001001001001001
|
||||
// h 9 3 9 0 9 2 4 9
|
||||
|
@ -1096,10 +1096,7 @@ components/nvs_flash/host_test/nvs_page_test/main/nvs_page_test.cpp
|
||||
components/nvs_flash/include/nvs_flash.h
|
||||
components/nvs_flash/include/nvs_handle.hpp
|
||||
components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py
|
||||
components/nvs_flash/src/compressed_enum_table.hpp
|
||||
components/nvs_flash/src/intrusive_list.h
|
||||
components/nvs_flash/src/nvs.hpp
|
||||
components/nvs_flash/src/nvs_api.cpp
|
||||
components/nvs_flash/src/nvs_cxx_api.cpp
|
||||
components/nvs_flash/src/nvs_encrypted_partition.cpp
|
||||
components/nvs_flash/src/nvs_encrypted_partition.hpp
|
||||
@ -1109,8 +1106,6 @@ components/nvs_flash/src/nvs_handle_simple.cpp
|
||||
components/nvs_flash/src/nvs_handle_simple.hpp
|
||||
components/nvs_flash/src/nvs_item_hash_list.cpp
|
||||
components/nvs_flash/src/nvs_item_hash_list.hpp
|
||||
components/nvs_flash/src/nvs_page.hpp
|
||||
components/nvs_flash/src/nvs_pagemanager.cpp
|
||||
components/nvs_flash/src/nvs_pagemanager.hpp
|
||||
components/nvs_flash/src/nvs_partition.cpp
|
||||
components/nvs_flash/src/nvs_partition.hpp
|
||||
@ -1121,7 +1116,6 @@ components/nvs_flash/src/nvs_platform.hpp
|
||||
components/nvs_flash/src/nvs_storage.hpp
|
||||
components/nvs_flash/src/nvs_test_api.h
|
||||
components/nvs_flash/src/nvs_types.cpp
|
||||
components/nvs_flash/src/nvs_types.hpp
|
||||
components/nvs_flash/src/partition.hpp
|
||||
components/nvs_flash/test/test_nvs.c
|
||||
components/nvs_flash/test_nvs_host/esp_error_check_stub.cpp
|
||||
@ -1129,7 +1123,6 @@ components/nvs_flash/test_nvs_host/main.cpp
|
||||
components/nvs_flash/test_nvs_host/sdkconfig.h
|
||||
components/nvs_flash/test_nvs_host/spi_flash_emulation.cpp
|
||||
components/nvs_flash/test_nvs_host/spi_flash_emulation.h
|
||||
components/nvs_flash/test_nvs_host/test_compressed_enum_table.cpp
|
||||
components/nvs_flash/test_nvs_host/test_fixtures.hpp
|
||||
components/nvs_flash/test_nvs_host/test_intrusive_list.cpp
|
||||
components/nvs_flash/test_nvs_host/test_nvs.cpp
|
||||
|
@ -30,3 +30,4 @@ CONFIG_MQTT_TEST_BROKER_URI="mqtt://${EXAMPLE_MQTT_BROKER_TCP}"
|
||||
# size of the storage partition divided by flash sector size.
|
||||
# See esp_spiffs_gc description for more info.
|
||||
CONFIG_SPIFFS_GC_MAX_RUNS=132
|
||||
CONFIG_NVS_ASSERT_ERROR_CHECK=y
|
||||
|
Loading…
Reference in New Issue
Block a user