mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/nvs_get_count_used_entries' into 'master'
NVS: add API to get used entries count See merge request idf/esp-idf!1982
This commit is contained in:
commit
5029eb4b3b
@ -356,6 +356,88 @@ esp_err_t nvs_commit(nvs_handle handle);
|
||||
*/
|
||||
void nvs_close(nvs_handle handle);
|
||||
|
||||
/**
|
||||
* @note Info about storage space NVS.
|
||||
*/
|
||||
typedef struct {
|
||||
size_t used_entries; /**< Amount of used entries. */
|
||||
size_t free_entries; /**< Amount of free entries. */
|
||||
size_t total_entries; /**< Amount all available entries. */
|
||||
size_t namespace_count; /**< Amount name space. */
|
||||
} nvs_stats_t;
|
||||
|
||||
/**
|
||||
* @brief Fill structure nvs_stats_t. It provides info about used memory the partition.
|
||||
*
|
||||
* This function calculates to runtime the number of used entries, free entries, total entries,
|
||||
* and amount namespace in partition.
|
||||
*
|
||||
* \code{c}
|
||||
* // Example of nvs_get_stats() to get the number of used entries and free entries:
|
||||
* nvs_stats_t nvs_stats;
|
||||
* nvs_get_stats(NULL, &nvs_stats);
|
||||
* printf("Count: UsedEntries = (%d), FreeEntries = (%d), AllEntries = (%d)\n",
|
||||
nvs_stats.used_entries, nvs_stats.free_entries, nvs_stats.total_entries);
|
||||
* \endcode
|
||||
*
|
||||
* @param[in] part_name Partition name NVS in the partition table.
|
||||
* If pass a NULL than will use NVS_DEFAULT_PART_NAME ("nvs").
|
||||
*
|
||||
* @param[out] nvs_stats Returns filled structure nvs_states_t.
|
||||
* It provides info about used memory the partition.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if the changes have been written successfully.
|
||||
* Return param nvs_stats will be filled.
|
||||
* - ESP_ERR_NVS_PART_NOT_FOUND if the partition with label "name" is not found.
|
||||
* Return param nvs_stats will be filled 0.
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized.
|
||||
* Return param nvs_stats will be filled 0.
|
||||
* - ESP_ERR_INVALID_ARG if nvs_stats equal to NULL.
|
||||
* - ESP_ERR_INVALID_STATE if there is page with the status of INVALID.
|
||||
* Return param nvs_stats will be filled not with correct values because
|
||||
* not all pages will be counted. Counting will be interrupted at the first INVALID page.
|
||||
*/
|
||||
esp_err_t nvs_get_stats(const char* part_name, nvs_stats_t* nvs_stats);
|
||||
|
||||
/**
|
||||
* @brief Calculate all entries in a namespace.
|
||||
*
|
||||
* Note that to find out the total number of records occupied by the namespace,
|
||||
* add one to the returned value used_entries (if err is equal to ESP_OK).
|
||||
* Because the name space entry takes one entry.
|
||||
*
|
||||
* \code{c}
|
||||
* // Example of nvs_get_used_entry_count() to get amount of all key-value pairs in one namespace:
|
||||
* nvs_handle handle;
|
||||
* nvs_open("namespace1", NVS_READWRITE, &handle);
|
||||
* ...
|
||||
* size_t used_entries;
|
||||
* size_t total_entries_namespace;
|
||||
* if(nvs_get_used_entry_count(handle, &used_entries) == ESP_OK){
|
||||
* // the total number of records occupied by the namespace
|
||||
* total_entries_namespace = used_entries + 1;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @param[in] handle Handle obtained from nvs_open function.
|
||||
*
|
||||
* @param[out] used_entries Returns amount of used entries from a namespace.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK if the changes have been written successfully.
|
||||
* Return param used_entries will be filled valid value.
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage driver is not initialized.
|
||||
* Return param used_entries will be filled 0.
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL.
|
||||
* Return param used_entries will be filled 0.
|
||||
* - ESP_ERR_INVALID_ARG if nvs_stats equal to NULL.
|
||||
* - Other error codes from the underlying storage driver.
|
||||
* Return param used_entries will be filled 0.
|
||||
*/
|
||||
esp_err_t nvs_get_used_entry_count(nvs_handle handle, size_t* used_entries);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
@ -458,3 +458,49 @@ extern "C" esp_err_t nvs_get_blob(nvs_handle handle, const char* key, void* out_
|
||||
return nvs_get_str_or_blob(handle, nvs::ItemType::BLOB, key, out_value, length);
|
||||
}
|
||||
|
||||
extern "C" esp_err_t nvs_get_stats(const char* part_name, nvs_stats_t* nvs_stats)
|
||||
{
|
||||
Lock lock;
|
||||
nvs::Storage* pStorage;
|
||||
|
||||
if (nvs_stats == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
nvs_stats->used_entries = 0;
|
||||
nvs_stats->free_entries = 0;
|
||||
nvs_stats->total_entries = 0;
|
||||
nvs_stats->namespace_count = 0;
|
||||
|
||||
pStorage = lookup_storage_from_name((part_name == NULL) ? NVS_DEFAULT_PART_NAME : part_name);
|
||||
if (pStorage == NULL) {
|
||||
return ESP_ERR_NVS_PART_NOT_FOUND;
|
||||
}
|
||||
|
||||
if(!pStorage->isValid()){
|
||||
return ESP_ERR_NVS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return pStorage->fillStats(*nvs_stats);
|
||||
}
|
||||
|
||||
extern "C" esp_err_t nvs_get_used_entry_count(nvs_handle handle, size_t* used_entries)
|
||||
{
|
||||
Lock lock;
|
||||
if(used_entries == NULL){
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
*used_entries = 0;
|
||||
|
||||
HandleEntry entry;
|
||||
auto err = nvs_find_ns_handle(handle, entry);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
size_t used_entry_count;
|
||||
err = entry.mStoragePtr->calcEntriesInNamespace(entry.mNsIndex, used_entry_count);
|
||||
if(err == ESP_OK){
|
||||
*used_entries = used_entry_count;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
@ -862,4 +862,33 @@ void Page::debugDump() const
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t Page::calcEntries(nvs_stats_t &nvsStats)
|
||||
{
|
||||
assert(mState != PageState::FREEING);
|
||||
|
||||
nvsStats.total_entries += ENTRY_COUNT;
|
||||
|
||||
switch (mState) {
|
||||
case PageState::UNINITIALIZED:
|
||||
case PageState::CORRUPT:
|
||||
nvsStats.free_entries += ENTRY_COUNT;
|
||||
break;
|
||||
|
||||
case PageState::FULL:
|
||||
case PageState::ACTIVE:
|
||||
nvsStats.used_entries += mUsedEntryCount;
|
||||
nvsStats.free_entries += ENTRY_COUNT - mUsedEntryCount; // it's equivalent free + erase entries.
|
||||
break;
|
||||
|
||||
case PageState::INVALID:
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false && "Unhandled state");
|
||||
break;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} // namespace nvs
|
||||
|
@ -133,6 +133,8 @@ public:
|
||||
|
||||
void debugDump() const;
|
||||
|
||||
esp_err_t calcEntries(nvs_stats_t &nvsStats);
|
||||
|
||||
protected:
|
||||
|
||||
class Header
|
||||
|
@ -197,4 +197,26 @@ esp_err_t PageManager::activatePage()
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t PageManager::fillStats(nvs_stats_t& nvsStats)
|
||||
{
|
||||
nvsStats.used_entries = 0;
|
||||
nvsStats.free_entries = 0;
|
||||
nvsStats.total_entries = 0;
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
// list of used pages
|
||||
for (auto p = mPageList.begin(); p != mPageList.end(); ++p) {
|
||||
err = p->calcEntries(nvsStats);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// free pages
|
||||
nvsStats.total_entries += mFreePageList.size() * Page::ENTRY_COUNT;
|
||||
nvsStats.free_entries += mFreePageList.size() * Page::ENTRY_COUNT;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
} // namespace nvs
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
|
||||
esp_err_t requestNewPage();
|
||||
|
||||
esp_err_t fillStats(nvs_stats_t& nvsStats);
|
||||
|
||||
protected:
|
||||
friend class Iterator;
|
||||
|
||||
|
@ -291,4 +291,37 @@ void Storage::debugCheck()
|
||||
}
|
||||
#endif //ESP_PLATFORM
|
||||
|
||||
esp_err_t Storage::fillStats(nvs_stats_t& nvsStats)
|
||||
{
|
||||
nvsStats.namespace_count = mNamespaces.size();
|
||||
return mPageManager.fillStats(nvsStats);
|
||||
}
|
||||
|
||||
esp_err_t Storage::calcEntriesInNamespace(uint8_t nsIndex, size_t& usedEntries)
|
||||
{
|
||||
usedEntries = 0;
|
||||
|
||||
if (mState != StorageState::ACTIVE) {
|
||||
return ESP_ERR_NVS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
for (auto it = std::begin(mPageManager); it != std::end(mPageManager); ++it) {
|
||||
size_t itemIndex = 0;
|
||||
Item item;
|
||||
while (true) {
|
||||
auto err = it->findItem(nsIndex, ItemType::ANY, nullptr, itemIndex, item);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
break;
|
||||
}
|
||||
else if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
usedEntries += item.span;
|
||||
itemIndex += item.span;
|
||||
if(itemIndex >= it->ENTRY_COUNT) break;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ public:
|
||||
|
||||
void debugCheck();
|
||||
|
||||
esp_err_t fillStats(nvs_stats_t& nvsStats);
|
||||
|
||||
esp_err_t calcEntriesInNamespace(uint8_t nsIndex, size_t& usedEntries);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -65,3 +65,151 @@ TEST_CASE("various nvs tests", "[nvs]")
|
||||
|
||||
nvs_close(handle_2);
|
||||
}
|
||||
|
||||
TEST_CASE("calculate used and free space", "[nvs]")
|
||||
{
|
||||
TEST_ESP_ERR(nvs_get_stats(NULL, NULL), ESP_ERR_INVALID_ARG);
|
||||
nvs_stats_t stat1;
|
||||
nvs_stats_t stat2;
|
||||
TEST_ESP_ERR(nvs_get_stats(NULL, &stat1), ESP_ERR_NVS_PART_NOT_FOUND);
|
||||
TEST_ASSERT_TRUE(stat1.free_entries == 0);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 0);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries == 0);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 0);
|
||||
|
||||
nvs_handle handle = 0;
|
||||
size_t h_count_entries;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle, &h_count_entries), ESP_ERR_NVS_INVALID_HANDLE);
|
||||
TEST_ASSERT_TRUE(h_count_entries == 0);
|
||||
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
|
||||
ESP_LOGW(TAG, "nvs_flash_init failed (0x%x), erasing partition and retrying", err);
|
||||
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) );
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( err );
|
||||
|
||||
// erase if have any namespace
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
if(stat1.namespace_count != 0) {
|
||||
TEST_ESP_OK(nvs_flash_erase());
|
||||
TEST_ESP_OK(nvs_flash_deinit());
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
}
|
||||
|
||||
// after erase. empty partition
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
TEST_ASSERT_TRUE(stat1.free_entries != 0);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 0);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries != 0);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 0);
|
||||
|
||||
// create namespace test_k1
|
||||
nvs_handle handle_1;
|
||||
TEST_ESP_OK(nvs_open("test_k1", NVS_READWRITE, &handle_1));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
|
||||
TEST_ASSERT_TRUE(stat2.namespace_count == 1);
|
||||
TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
|
||||
TEST_ASSERT_TRUE(stat2.used_entries == 1);
|
||||
|
||||
// create pair key-value com
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x12345678));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
TEST_ASSERT_TRUE(stat1.free_entries + 1 == stat2.free_entries);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 1);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 2);
|
||||
|
||||
// change value in com
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x01234567));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
TEST_ASSERT_TRUE(stat2.free_entries == stat1.free_entries);
|
||||
TEST_ASSERT_TRUE(stat2.namespace_count == 1);
|
||||
TEST_ASSERT_TRUE(stat2.total_entries != 0);
|
||||
TEST_ASSERT_TRUE(stat2.used_entries == 2);
|
||||
|
||||
// create pair key-value ru
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "ru", 0x00FF00FF));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
TEST_ASSERT_TRUE(stat1.free_entries + 1 == stat2.free_entries);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 1);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries != 0);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 3);
|
||||
|
||||
// amount valid pair in namespace 1
|
||||
size_t h1_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_1, &h1_count_entries));
|
||||
TEST_ASSERT_TRUE(h1_count_entries == 2);
|
||||
|
||||
nvs_handle handle_2;
|
||||
// create namespace test_k2
|
||||
TEST_ESP_OK(nvs_open("test_k2", NVS_READWRITE, &handle_2));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
|
||||
TEST_ASSERT_TRUE(stat2.namespace_count == 2);
|
||||
TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
|
||||
TEST_ASSERT_TRUE(stat2.used_entries == 4);
|
||||
|
||||
// create pair key-value
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "su1", 0x00000001));
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "su2", 0x00000002));
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "sus", 0x00000003));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
TEST_ASSERT_TRUE(stat1.free_entries + 3 == stat2.free_entries);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 2);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 7);
|
||||
|
||||
TEST_ASSERT_TRUE(stat1.total_entries == (stat1.used_entries + stat1.free_entries));
|
||||
|
||||
// amount valid pair in namespace 2
|
||||
size_t h2_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_2, &h2_count_entries));
|
||||
TEST_ASSERT_TRUE(h2_count_entries == 3);
|
||||
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == (h1_count_entries + h2_count_entries + stat1.namespace_count));
|
||||
|
||||
nvs_close(handle_1);
|
||||
nvs_close(handle_2);
|
||||
|
||||
size_t temp = h2_count_entries;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle_1, &h2_count_entries), ESP_ERR_NVS_INVALID_HANDLE);
|
||||
TEST_ASSERT_TRUE(h2_count_entries == 0);
|
||||
h2_count_entries = temp;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle_1, NULL), ESP_ERR_INVALID_ARG);
|
||||
|
||||
nvs_handle handle_3;
|
||||
// create namespace test_k3
|
||||
TEST_ESP_OK(nvs_open("test_k3", NVS_READWRITE, &handle_3));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
TEST_ASSERT_TRUE(stat2.free_entries + 1 == stat1.free_entries);
|
||||
TEST_ASSERT_TRUE(stat2.namespace_count == 3);
|
||||
TEST_ASSERT_TRUE(stat2.total_entries == stat1.total_entries);
|
||||
TEST_ASSERT_TRUE(stat2.used_entries == 8);
|
||||
|
||||
// create pair blobs
|
||||
uint32_t blob[12];
|
||||
TEST_ESP_OK(nvs_set_blob(handle_3, "bl1", &blob, sizeof(blob)));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
TEST_ASSERT_TRUE(stat1.free_entries + 3 == stat2.free_entries);
|
||||
TEST_ASSERT_TRUE(stat1.namespace_count == 3);
|
||||
TEST_ASSERT_TRUE(stat1.total_entries == stat2.total_entries);
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == 11);
|
||||
|
||||
// amount valid pair in namespace 2
|
||||
size_t h3_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_3, &h3_count_entries));
|
||||
TEST_ASSERT_TRUE(h3_count_entries == 3);
|
||||
|
||||
TEST_ASSERT_TRUE(stat1.used_entries == (h1_count_entries + h2_count_entries + h3_count_entries + stat1.namespace_count));
|
||||
|
||||
nvs_close(handle_3);
|
||||
|
||||
TEST_ESP_OK(nvs_flash_erase());
|
||||
TEST_ESP_OK(nvs_flash_deinit());
|
||||
}
|
||||
|
@ -132,14 +132,14 @@ TEST_CASE("when writing and erasing, used/erased counts are updated correctly",
|
||||
CHECK(page.getErasedEntryCount() == 1);
|
||||
for (size_t i = 0; i < Page::ENTRY_COUNT - 2; ++i) {
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "i%ld", i);
|
||||
snprintf(name, sizeof(name), "i%ld", (long int)i);
|
||||
CHECK(page.writeItem(1, name, i) == ESP_OK);
|
||||
}
|
||||
CHECK(page.getUsedEntryCount() == Page::ENTRY_COUNT - 1);
|
||||
CHECK(page.getErasedEntryCount() == 1);
|
||||
for (size_t i = 0; i < Page::ENTRY_COUNT - 2; ++i) {
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "i%ld", i);
|
||||
snprintf(name, sizeof(name), "i%ld", (long int)i);
|
||||
CHECK(page.eraseItem(1, itemTypeOf<size_t>(), name) == ESP_OK);
|
||||
}
|
||||
CHECK(page.getUsedEntryCount() == 1);
|
||||
@ -153,7 +153,7 @@ TEST_CASE("when page is full, adding an element fails", "[nvs]")
|
||||
CHECK(page.load(0) == ESP_OK);
|
||||
for (size_t i = 0; i < Page::ENTRY_COUNT; ++i) {
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "i%ld", i);
|
||||
snprintf(name, sizeof(name), "i%ld", (long int)i);
|
||||
CHECK(page.writeItem(1, name, i) == ESP_OK);
|
||||
}
|
||||
CHECK(page.writeItem(1, "foo", 64UL) == ESP_ERR_NVS_PAGE_FULL);
|
||||
@ -1123,7 +1123,7 @@ TEST_CASE("crc errors in item header are handled", "[nvs]")
|
||||
// add more items to make the page full
|
||||
for (size_t i = 0; i < Page::ENTRY_COUNT; ++i) {
|
||||
char item_name[Item::MAX_KEY_LENGTH + 1];
|
||||
snprintf(item_name, sizeof(item_name), "item_%ld", i);
|
||||
snprintf(item_name, sizeof(item_name), "item_%ld", (long int)i);
|
||||
TEST_ESP_OK(storage.writeItem(1, item_name, static_cast<uint32_t>(i)));
|
||||
}
|
||||
|
||||
@ -1252,3 +1252,137 @@ TEST_CASE("dump all performance data", "[nvs]")
|
||||
std::cout << s_perf.str() << std::endl;
|
||||
std::cout << "====================" << std::endl;
|
||||
}
|
||||
|
||||
TEST_CASE("calculate used and free space", "[nvs]")
|
||||
{
|
||||
SpiFlashEmulator emu(6);
|
||||
TEST_ESP_ERR(nvs_get_stats(NULL, NULL), ESP_ERR_INVALID_ARG);
|
||||
nvs_stats_t stat1;
|
||||
nvs_stats_t stat2;
|
||||
TEST_ESP_ERR(nvs_get_stats(NULL, &stat1), ESP_ERR_NVS_NOT_INITIALIZED);
|
||||
CHECK(stat1.free_entries == 0);
|
||||
CHECK(stat1.namespace_count == 0);
|
||||
CHECK(stat1.total_entries == 0);
|
||||
CHECK(stat1.used_entries == 0);
|
||||
|
||||
nvs_handle handle = 0;
|
||||
size_t h_count_entries;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle, &h_count_entries), ESP_ERR_NVS_INVALID_HANDLE);
|
||||
CHECK(h_count_entries == 0);
|
||||
|
||||
// init nvs
|
||||
TEST_ESP_OK(nvs_flash_init_custom(NVS_DEFAULT_PART_NAME, 0, 6));
|
||||
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle, &h_count_entries), ESP_ERR_NVS_INVALID_HANDLE);
|
||||
CHECK(h_count_entries == 0);
|
||||
|
||||
Page p;
|
||||
// after erase. empty partition
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
CHECK(stat1.free_entries != 0);
|
||||
CHECK(stat1.namespace_count == 0);
|
||||
CHECK(stat1.total_entries == 6 * p.ENTRY_COUNT);
|
||||
CHECK(stat1.used_entries == 0);
|
||||
|
||||
// create namespace test_k1
|
||||
nvs_handle handle_1;
|
||||
TEST_ESP_OK(nvs_open("test_k1", NVS_READWRITE, &handle_1));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
CHECK(stat2.free_entries + 1 == stat1.free_entries);
|
||||
CHECK(stat2.namespace_count == 1);
|
||||
CHECK(stat2.total_entries == stat1.total_entries);
|
||||
CHECK(stat2.used_entries == 1);
|
||||
|
||||
// create pair key-value com
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x12345678));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
CHECK(stat1.free_entries + 1 == stat2.free_entries);
|
||||
CHECK(stat1.namespace_count == 1);
|
||||
CHECK(stat1.total_entries == stat2.total_entries);
|
||||
CHECK(stat1.used_entries == 2);
|
||||
|
||||
// change value in com
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "com", 0x01234567));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
CHECK(stat2.free_entries == stat1.free_entries);
|
||||
CHECK(stat2.namespace_count == 1);
|
||||
CHECK(stat2.total_entries != 0);
|
||||
CHECK(stat2.used_entries == 2);
|
||||
|
||||
// create pair key-value ru
|
||||
TEST_ESP_OK(nvs_set_i32(handle_1, "ru", 0x00FF00FF));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
CHECK(stat1.free_entries + 1 == stat2.free_entries);
|
||||
CHECK(stat1.namespace_count == 1);
|
||||
CHECK(stat1.total_entries != 0);
|
||||
CHECK(stat1.used_entries == 3);
|
||||
|
||||
// amount valid pair in namespace 1
|
||||
size_t h1_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_1, &h1_count_entries));
|
||||
CHECK(h1_count_entries == 2);
|
||||
|
||||
nvs_handle handle_2;
|
||||
// create namespace test_k2
|
||||
TEST_ESP_OK(nvs_open("test_k2", NVS_READWRITE, &handle_2));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
CHECK(stat2.free_entries + 1 == stat1.free_entries);
|
||||
CHECK(stat2.namespace_count == 2);
|
||||
CHECK(stat2.total_entries == stat1.total_entries);
|
||||
CHECK(stat2.used_entries == 4);
|
||||
|
||||
// create pair key-value
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "su1", 0x00000001));
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "su2", 0x00000002));
|
||||
TEST_ESP_OK(nvs_set_i32(handle_2, "sus", 0x00000003));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
CHECK(stat1.free_entries + 3 == stat2.free_entries);
|
||||
CHECK(stat1.namespace_count == 2);
|
||||
CHECK(stat1.total_entries == stat2.total_entries);
|
||||
CHECK(stat1.used_entries == 7);
|
||||
|
||||
CHECK(stat1.total_entries == (stat1.used_entries + stat1.free_entries));
|
||||
|
||||
// amount valid pair in namespace 2
|
||||
size_t h2_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_2, &h2_count_entries));
|
||||
CHECK(h2_count_entries == 3);
|
||||
|
||||
CHECK(stat1.used_entries == (h1_count_entries + h2_count_entries + stat1.namespace_count));
|
||||
|
||||
nvs_close(handle_1);
|
||||
nvs_close(handle_2);
|
||||
|
||||
size_t temp = h2_count_entries;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle_1, &h2_count_entries), ESP_ERR_NVS_INVALID_HANDLE);
|
||||
CHECK(h2_count_entries == 0);
|
||||
h2_count_entries = temp;
|
||||
TEST_ESP_ERR(nvs_get_used_entry_count(handle_1, NULL), ESP_ERR_INVALID_ARG);
|
||||
|
||||
nvs_handle handle_3;
|
||||
// create namespace test_k3
|
||||
TEST_ESP_OK(nvs_open("test_k3", NVS_READWRITE, &handle_3));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat2));
|
||||
CHECK(stat2.free_entries + 1 == stat1.free_entries);
|
||||
CHECK(stat2.namespace_count == 3);
|
||||
CHECK(stat2.total_entries == stat1.total_entries);
|
||||
CHECK(stat2.used_entries == 8);
|
||||
|
||||
// create pair blobs
|
||||
uint32_t blob[12];
|
||||
TEST_ESP_OK(nvs_set_blob(handle_3, "bl1", &blob, sizeof(blob)));
|
||||
TEST_ESP_OK(nvs_get_stats(NULL, &stat1));
|
||||
CHECK(stat1.free_entries + 3 == stat2.free_entries);
|
||||
CHECK(stat1.namespace_count == 3);
|
||||
CHECK(stat1.total_entries == stat2.total_entries);
|
||||
CHECK(stat1.used_entries == 11);
|
||||
|
||||
// amount valid pair in namespace 2
|
||||
size_t h3_count_entries;
|
||||
TEST_ESP_OK(nvs_get_used_entry_count(handle_3, &h3_count_entries));
|
||||
CHECK(h3_count_entries == 3);
|
||||
|
||||
CHECK(stat1.used_entries == (h1_count_entries + h2_count_entries + h3_count_entries + stat1.namespace_count));
|
||||
|
||||
nvs_close(handle_3);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user