mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(nvs_flash): Added function nvs_find_key
Closes https://github.com/espressif/esp-idf/issues/12155
This commit is contained in:
parent
a36d8bc742
commit
6949092234
@ -3319,7 +3319,92 @@ TEST_CASE("nvs multiple write with same key but different types", "[nvs][xxx]")
|
||||
TEST_ESP_OK(nvs_flash_deinit_partition(NVS_DEFAULT_PART_NAME));
|
||||
}
|
||||
|
||||
TEST_CASE("nvs find key tests", "[nvs]")
|
||||
{
|
||||
const size_t buff_len = 4096;
|
||||
|
||||
PartitionEmulationFixture f(0, 20);
|
||||
f.randomize(100);
|
||||
|
||||
nvs_handle_t handle_1;
|
||||
nvs_handle_t handle_2;
|
||||
|
||||
const uint32_t NVS_FLASH_SECTOR = 6;
|
||||
const uint32_t NVS_FLASH_SECTOR_COUNT_MIN = 13;
|
||||
|
||||
|
||||
TEST_ESP_ERR(nvs_open("namespace1", NVS_READWRITE, &handle_1), ESP_ERR_NVS_NOT_INITIALIZED);
|
||||
for (uint16_t i = NVS_FLASH_SECTOR; i < NVS_FLASH_SECTOR + NVS_FLASH_SECTOR_COUNT_MIN; ++i) {
|
||||
f.erase(i);
|
||||
}
|
||||
TEST_ESP_OK(nvs::NVSPartitionManager::get_instance()->init_custom(f.part(),
|
||||
NVS_FLASH_SECTOR,
|
||||
NVS_FLASH_SECTOR_COUNT_MIN));
|
||||
|
||||
nvs_type_t datatype_found; // datatype of entry found
|
||||
|
||||
// open writeable namespace
|
||||
TEST_ESP_OK(nvs_open("namespace1", NVS_READWRITE, &handle_1));
|
||||
|
||||
// set value, erease value, test find before and after each of steps
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
// write "foo" as I32, should find it, first attempt without pointer to type variable
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "foo", 0x12345678));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo", nullptr));
|
||||
// second search attempt with pointer to type variable specified
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo", &datatype_found));
|
||||
CHECK(datatype_found == NVS_TYPE_I32);
|
||||
TEST_ESP_OK(nvs_erase_key(handle_1, "foo"));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
|
||||
// set value, rewrite value, erease value, test find before and after each of steps
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_OK(nvs_set_i16(handle_1, "foo1", 0x1234));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo1", &datatype_found));
|
||||
CHECK(datatype_found == NVS_TYPE_I16);
|
||||
TEST_ESP_OK(nvs_set_i16(handle_1, "foo1", 0x4321));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo1", &datatype_found));
|
||||
CHECK(datatype_found == NVS_TYPE_I16);
|
||||
TEST_ESP_OK(nvs_erase_key(handle_1, "foo1"));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
|
||||
// set blob value, rewrite blob, delete blob, test find before and after each of steps
|
||||
uint8_t *p_buff = (uint8_t *) malloc(buff_len);
|
||||
CHECK(p_buff != nullptr);
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo2", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
for(size_t i=0; i<buff_len; i++) p_buff[i] = (uint8_t) (i%0xff);
|
||||
TEST_ESP_OK(nvs_set_blob(handle_1, "foo2", p_buff, buff_len));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo2", &datatype_found));
|
||||
CHECK(datatype_found == NVS_TYPE_BLOB);
|
||||
for(size_t i=0; i<buff_len; i++) p_buff[i] = (uint8_t) ((buff_len-i-1)%0xff);
|
||||
TEST_ESP_OK(nvs_set_blob(handle_1, "foo2", p_buff, buff_len));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foo2", &datatype_found));
|
||||
CHECK(datatype_found == NVS_TYPE_BLOB);
|
||||
TEST_ESP_OK(nvs_erase_key(handle_1, "foo2"));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foo2", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
|
||||
// test namespace is respected in nvs_find_key
|
||||
// open second writeable namespace
|
||||
TEST_ESP_OK(nvs_open("namespace2", NVS_READWRITE, &handle_2));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_ERR(nvs_find_key(handle_2, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_OK(nvs_set_i16(handle_1, "foon1", 0x1234));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foon1", &datatype_found));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_2, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_OK(nvs_set_i16(handle_2, "foon1", 0x1234));
|
||||
TEST_ESP_OK(nvs_find_key(handle_1, "foon1", &datatype_found));
|
||||
TEST_ESP_OK(nvs_find_key(handle_2, "foon1", &datatype_found));
|
||||
TEST_ESP_OK(nvs_erase_key(handle_1, "foon1"));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_OK(nvs_find_key(handle_2, "foon1", &datatype_found));
|
||||
TEST_ESP_OK(nvs_erase_key(handle_2, "foon1"));
|
||||
TEST_ESP_ERR(nvs_find_key(handle_1, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
TEST_ESP_ERR(nvs_find_key(handle_2, "foon1", &datatype_found), ESP_ERR_NVS_NOT_FOUND);
|
||||
|
||||
nvs_close(handle_1);
|
||||
nvs_close(handle_2);
|
||||
TEST_ESP_OK(nvs_flash_deinit_partition(NVS_DEFAULT_PART_NAME));
|
||||
}
|
||||
/* Add new tests above */
|
||||
/* This test has to be the final one */
|
||||
|
||||
|
@ -481,6 +481,25 @@ esp_err_t nvs_get_str (nvs_handle_t handle, const char* key, char* out_value, si
|
||||
esp_err_t nvs_get_blob(nvs_handle_t handle, const char* key, void* out_value, size_t* length);
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief Lookup key-value pair with given key name.
|
||||
*
|
||||
* Note that function may indicate both existence of the key as well as the data type of NVS entry if it is found.
|
||||
*
|
||||
* @param[in] handle Storage handle obtained with nvs_open.
|
||||
* @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty.
|
||||
* @param[out] out_type Pointer to the output variable populated with data type of NVS entry in case key was found.
|
||||
* May be NULL, respective data type is then not provided.
|
||||
* @return
|
||||
* - ESP_OK if NVS entry for key provided was found
|
||||
* - 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_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled)
|
||||
* - other error codes from the underlying storage driver
|
||||
*/
|
||||
esp_err_t nvs_find_key(nvs_handle_t handle, const char* key, nvs_type_t* out_type);
|
||||
|
||||
/**
|
||||
* @brief Erase key-value pair with given key name.
|
||||
*
|
||||
|
@ -164,6 +164,21 @@ public:
|
||||
*/
|
||||
virtual esp_err_t get_item_size(ItemType datatype, const char *key, size_t &size) = 0;
|
||||
|
||||
/**
|
||||
* @brief Checks whether key exists and optionally returns also data type of associated entry.
|
||||
*
|
||||
* @param[in] key Key name. Maximum length is (NVS_KEY_NAME_MAX_SIZE-1) characters. Shouldn't be empty.
|
||||
* @param[out] nvstype Nvs data type to of entry, if it exists.
|
||||
*
|
||||
* @return - ESP_OK if NVS entry for key provided was found. Data type will be returned via \c nvstype.
|
||||
* - 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_FAIL if there is an internal error; most likely due to corrupted
|
||||
* NVS partition (only if NVS assertion checks are disabled).
|
||||
* - other error codes from the underlying storage driver.
|
||||
*/
|
||||
virtual esp_err_t find_key(const char* key, nvs_type_t &nvstype) = 0;
|
||||
|
||||
/**
|
||||
* @brief Erases an entry.
|
||||
*/
|
||||
|
@ -306,6 +306,25 @@ extern "C" void nvs_close(nvs_handle_t handle)
|
||||
delete static_cast<NVSHandleEntry*>(it);
|
||||
}
|
||||
|
||||
extern "C" esp_err_t nvs_find_key(nvs_handle_t c_handle, const char* key, nvs_type_t* out_type)
|
||||
{
|
||||
Lock lock;
|
||||
ESP_LOGD(TAG, "%s %s", __func__, key);
|
||||
NVSHandleSimple *handle;
|
||||
auto err = nvs_find_ns_handle(c_handle, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
nvs_type_t nvstype;
|
||||
err = handle->find_key(key, nvstype);
|
||||
|
||||
if(err == ESP_OK && out_type != nullptr)
|
||||
*out_type = nvstype;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern "C" esp_err_t nvs_erase_key(nvs_handle_t c_handle, const char* key)
|
||||
{
|
||||
Lock lock;
|
||||
|
@ -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-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "nvs_handle_locked.hpp"
|
||||
|
||||
namespace nvs {
|
||||
@ -47,6 +39,12 @@ esp_err_t NVSHandleLocked::get_item_size(ItemType datatype, const char *key, siz
|
||||
return handle->get_item_size(datatype, key, size);
|
||||
}
|
||||
|
||||
esp_err_t NVSHandleLocked::find_key(const char* key, nvs_type_t &nvstype)
|
||||
{
|
||||
Lock lock;
|
||||
return handle->find_key(key, nvstype);
|
||||
}
|
||||
|
||||
esp_err_t NVSHandleLocked::erase_item(const char* key) {
|
||||
Lock lock;
|
||||
return handle->erase_item(key);
|
||||
|
@ -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-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef NVS_HANDLE_LOCKED_HPP_
|
||||
#define NVS_HANDLE_LOCKED_HPP_
|
||||
|
||||
@ -49,6 +41,8 @@ public:
|
||||
|
||||
esp_err_t get_item_size(ItemType datatype, const char *key, size_t &size) override;
|
||||
|
||||
esp_err_t find_key(const char* key, nvs_type_t &nvstype) override;
|
||||
|
||||
esp_err_t erase_item(const char* key) override;
|
||||
|
||||
esp_err_t erase_all() override;
|
||||
|
@ -65,6 +65,23 @@ esp_err_t NVSHandleSimple::get_item_size(ItemType datatype, const char *key, siz
|
||||
return mStoragePtr->getItemDataSize(mNsIndex, datatype, key, size);
|
||||
}
|
||||
|
||||
esp_err_t NVSHandleSimple::find_key(const char* key, nvs_type_t &nvstype)
|
||||
{
|
||||
if (!valid) return ESP_ERR_NVS_INVALID_HANDLE;
|
||||
|
||||
nvs::ItemType datatype;
|
||||
esp_err_t err = mStoragePtr->findKey(mNsIndex, key, &datatype);
|
||||
if(err != ESP_OK)
|
||||
return err;
|
||||
|
||||
if(datatype == ItemType::BLOB_IDX || datatype == ItemType::BLOB)
|
||||
datatype = ItemType::BLOB_DATA;
|
||||
|
||||
nvstype = (nvs_type_t) datatype;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t NVSHandleSimple::erase_item(const char* key)
|
||||
{
|
||||
if (!valid) return ESP_ERR_NVS_INVALID_HANDLE;
|
||||
|
@ -51,6 +51,8 @@ public:
|
||||
|
||||
esp_err_t get_item_size(ItemType datatype, const char *key, size_t &size) override;
|
||||
|
||||
esp_err_t find_key(const char *key, nvs_type_t &nvstype) override;
|
||||
|
||||
esp_err_t erase_item(const char *key) override;
|
||||
|
||||
esp_err_t erase_all() override;
|
||||
|
@ -683,6 +683,26 @@ esp_err_t Storage::eraseNamespace(uint8_t nsIndex)
|
||||
|
||||
}
|
||||
|
||||
esp_err_t Storage::findKey(const uint8_t nsIndex, const char* key, ItemType* datatype)
|
||||
{
|
||||
if (mState != StorageState::ACTIVE) {
|
||||
return ESP_ERR_NVS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
Item item;
|
||||
Page* findPage = nullptr;
|
||||
auto err = findItem(nsIndex, ItemType::ANY, key, findPage, item);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if(datatype != nullptr) {
|
||||
*datatype = item.datatype;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t Storage::getItemDataSize(uint8_t nsIndex, ItemType datatype, const char* key, size_t& dataSize)
|
||||
{
|
||||
if (mState != StorageState::ACTIVE) {
|
||||
|
@ -71,6 +71,8 @@ public:
|
||||
|
||||
esp_err_t readItem(uint8_t nsIndex, ItemType datatype, const char* key, void* data, size_t dataSize);
|
||||
|
||||
esp_err_t findKey(const uint8_t nsIndex, const char* key, ItemType* datatype);
|
||||
|
||||
esp_err_t getItemDataSize(uint8_t nsIndex, ItemType datatype, const char* key, size_t& dataSize);
|
||||
|
||||
esp_err_t eraseItem(uint8_t nsIndex, ItemType datatype, const char* key);
|
||||
|
@ -583,8 +583,6 @@ components/mbedtls/port/sha/parallel_engine/sha.c
|
||||
components/nvs_flash/include/nvs_handle.hpp
|
||||
components/nvs_flash/src/nvs_cxx_api.cpp
|
||||
components/nvs_flash/src/nvs_encrypted_partition.hpp
|
||||
components/nvs_flash/src/nvs_handle_locked.cpp
|
||||
components/nvs_flash/src/nvs_handle_locked.hpp
|
||||
components/nvs_flash/src/nvs_item_hash_list.cpp
|
||||
components/nvs_flash/src/nvs_pagemanager.hpp
|
||||
components/nvs_flash/src/nvs_partition_lookup.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user