feat(nvs_flash): Implemented basic nvs_flash support for bootloader

This commit is contained in:
radek.tandler
2024-06-26 11:50:14 +02:00
parent c2ae806661
commit 4e8bb8a082
41 changed files with 1980 additions and 70 deletions

View File

@@ -0,0 +1,7 @@
idf_component_register(SRCS "test_app_main.c" "test_nvs_bootloader.c"
INCLUDE_DIRS "."
REQUIRES unity nvs_flash
WHOLE_ARCHIVE
)
nvs_create_partition_image(nvs ../partition_nvs_data.csv FLASH_IN_PROJECT)

View File

@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_runner.h"
#include "esp_heap_caps.h"
// There should be no memory allocated during the test.
#define TEST_MEMORY_INITIAL_LEAK_THRESHOLD (-700)
static size_t before_free_8bit;
static size_t before_free_32bit;
static size_t actual_leak_threshold = TEST_MEMORY_INITIAL_LEAK_THRESHOLD;
static void check_leak(size_t before_free, size_t after_free, const char *type)
{
ssize_t delta = after_free - before_free;
printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta);
TEST_ASSERT_MESSAGE(delta >= actual_leak_threshold, "memory leak");
}
void setUp(void)
{
// load the partition table before measuring the initial free heap size.
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
check_leak(before_free_8bit, after_free_8bit, "8BIT");
check_leak(before_free_32bit, after_free_32bit, "32BIT");
// Reset the threshold to the zero after initial check
actual_leak_threshold = 0;
}
void app_main(void)
{
printf("Running nvs bootloader support component tests\n");
unity_run_menu();
}

View File

@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "string.h"
#include "esp_err.h"
#include "unity.h"
#include "nvs_bootloader.h"
TEST_CASE("Verify nvs bootloader read_list result_code and value if bootloader read is successful", "[nvs_bootloader]")
{
nvs_bootloader_read_list_t read_list[] = {
// {namespace_name, key_name, value_type, result_code, value, namespace_index}}
{ .namespace_name = "storage", .key_name = "u8_key", .value_type = NVS_TYPE_U8 }, //0 OK
{ .namespace_name = "storage", .key_name = "u16_key", .value_type = NVS_TYPE_U16 }, //1 OK
{ .namespace_name = "storage", .key_name = "u32_key", .value_type = NVS_TYPE_U32 }, //2 OK
{ .namespace_name = "storage", .key_name = "i32_key", .value_type = NVS_TYPE_I32 }, //3 OK
{ .namespace_name = "storage", .key_name = "i8_key", .value_type = NVS_TYPE_U8 }, //4 Type mismatch
{ .namespace_name = "storage", .key_name = "i16_key", .value_type = NVS_TYPE_I16 }, //5 Not found
};
uint8_t size = sizeof(read_list) / sizeof(read_list[0]);
TEST_ESP_OK(nvs_bootloader_read("nvs", size, read_list));
TEST_ASSERT_EQUAL(ESP_OK, read_list[0].result_code);
TEST_ASSERT_EQUAL(ESP_OK, read_list[1].result_code);
TEST_ASSERT_EQUAL(ESP_OK, read_list[2].result_code);
TEST_ASSERT_EQUAL(ESP_OK, read_list[3].result_code);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_TYPE_MISMATCH, read_list[4].result_code);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, read_list[5].result_code);
TEST_ASSERT_EQUAL(255, read_list[0].value.u8_val);
TEST_ASSERT_EQUAL(65535, read_list[1].value.u16_val);
TEST_ASSERT_EQUAL(4294967295, read_list[2].value.u32_val);
TEST_ASSERT_EQUAL(-2147483648, read_list[3].value.i32_val);
}
TEST_CASE("Verify nvs bootloader read_list result_code if bootloader read fails", "[nvs_bootloader]")
{
nvs_bootloader_read_list_t read_list[] = {
// {namespace_name, key_name, value_type, result_code, value, namespace_index}}
{ .namespace_name = "too_long_namespace", .key_name = "i32_key", .value_type = NVS_TYPE_I32 }, //0 Invalid name
{ .namespace_name = "nvs", .key_name = "too_long_key_name", .value_type = NVS_TYPE_I32 }, //1 Key too long
{ .namespace_name = "nvs", .key_name = "str_key", .value_type = NVS_TYPE_BLOB }, //2 Invalid arg
{ .namespace_name = "nvs", .key_name = "i32_key", .value_type = NVS_TYPE_I32 }, //3 Not found
};
uint8_t size = sizeof(read_list) / sizeof(read_list[0]);
esp_err_t ret = nvs_bootloader_read("nvs", size, read_list);
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, ret);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_INVALID_NAME, read_list[0].result_code);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_KEY_TOO_LONG, read_list[1].result_code);
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, read_list[2].result_code);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_NOT_FOUND, read_list[3].result_code);
}
TEST_CASE("Verify nvs_bootloader_read failure cases", "[nvs_bootloader]")
{
nvs_bootloader_read_list_t read_list[] = {
// {namespace_name, key_name, value_type, result_code, value, namespace_index}}
{ "nvs", "i32_key", NVS_TYPE_I32, ESP_OK, {0}, 0}
};
uint8_t size = sizeof(read_list) / sizeof(read_list[0]);
esp_err_t ret = nvs_bootloader_read("nvs_partition_name_too_long", size, read_list);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_INVALID_NAME, ret);
ret = nvs_bootloader_read("nvs_part", size, read_list);
TEST_ASSERT_EQUAL(ESP_ERR_NVS_PART_NOT_FOUND, ret);
}