From e7778f2ee1761722e76c21e92d66e144718abc57 Mon Sep 17 00:00:00 2001 From: Anastasiia Stepanova Date: Wed, 14 Aug 2024 08:52:41 +0300 Subject: [PATCH] Add redundant page (#50) * add sim_params.yml generator on paramsSave for sitl * delete tests dir changes * fixed unit tests * initial commit * init commit * refundant include * fix rebase, integrated redundant storage feature into main functions of storage * fix offset issue * fix param_idxs overflow * adapted functions and addressing for redundant paging * paramsInitRedundantPage excluded from paramsInit fn * add explicit rom drivers pointers, fix bug in ubuntu version for application without redundant pages * fix standby rom erase * fix tests * extend storage tests * upd error msgs --- libparams/rom.h | 1 + libparams/storage.c | 126 ++++++++++++++---- libparams/storage.h | 6 + .../ubuntu/FlashMemoryLayout.hpp | 6 +- platform_specific/ubuntu/YamlParameters.cpp | 50 +++---- platform_specific/ubuntu/YamlParameters.hpp | 10 +- platform_specific/ubuntu/flash_driver.cpp | 23 ++-- tests/unit_tests/CMakeLists.txt | 11 +- tests/unit_tests/test_flash_driver.cpp | 7 - tests/unit_tests/test_rom.cpp | 2 +- tests/unit_tests/test_storage.cpp | 53 +++++++- tests/unit_tests/test_yaml_parameters.cpp | 2 +- 12 files changed, 221 insertions(+), 76 deletions(-) diff --git a/libparams/rom.h b/libparams/rom.h index fecb9a8..b4fb754 100644 --- a/libparams/rom.h +++ b/libparams/rom.h @@ -28,6 +28,7 @@ typedef struct { size_t total_size; size_t pages_amount; bool inited; + bool erased; } RomDriverInstance; diff --git a/libparams/storage.c b/libparams/storage.c index 6271904..f30c1c0 100644 --- a/libparams/storage.c +++ b/libparams/storage.c @@ -22,56 +22,96 @@ static ParamIndex_t strings_amount = 0; static ParamIndex_t all_params_amount = 0; static bool _isCorrectStringParamIndex(ParamIndex_t param_idx); -static uint32_t _getStringMemoryPoolAddress(); -static int8_t _save(); +static uint32_t _getStringMemoryPoolAddress(RomDriverInstance* rom_driver); +static int8_t _save(RomDriverInstance* rom_driver); +static int8_t _chooseRom(); #define INT_POOL_SIZE integers_amount * sizeof(IntegerParamValue_t) #define STR_POOL_SIZE MAX_STRING_LENGTH * strings_amount - ///< Default values correspond to the last page access only. -static RomDriverInstance rom = { +static RomDriverInstance primary_rom = { + .inited = false, +}; +static RomDriverInstance redundant_rom = { .inited = false, }; +RomDriverInstance* active_rom; +RomDriverInstance* standby_rom; int8_t paramsInit(ParamIndex_t int_num, ParamIndex_t str_num, int32_t first_page_idx, size_t pages_num) { + if (int_num > 512 || str_num > 512) { + return LIBPARAMS_WRONG_ARGS; + } uint32_t need_memory_bytes = sizeof(IntegerParamValue_t) * int_num +\ MAX_STRING_LENGTH * str_num; - rom = romInit(first_page_idx, pages_num); + primary_rom = romInit(first_page_idx, pages_num); - if (!rom.inited) { + if (!primary_rom.inited) { return LIBPARAMS_UNKNOWN_ERROR; } - if (romGetAvailableMemory(&rom) < need_memory_bytes) { + if (romGetAvailableMemory(&primary_rom) < need_memory_bytes) { return LIBPARAMS_WRONG_ARGS; } - integers_amount = int_num; strings_amount = str_num; all_params_amount = integers_amount + strings_amount; + active_rom = &primary_rom; + return LIBPARAMS_OK; +} + +int8_t paramsInitRedundantPage() { + redundant_rom = + romInit(primary_rom.first_page_idx - primary_rom.pages_amount, primary_rom.pages_amount); + if (!redundant_rom.inited) { + return LIBPARAMS_UNKNOWN_ERROR; + } + _chooseRom(); return LIBPARAMS_OK; } int8_t paramsLoad() { - romRead(&rom, 0, (uint8_t*)integer_values_pool, INT_POOL_SIZE); - romRead(&rom, _getStringMemoryPoolAddress(), (uint8_t*)&string_values_pool, STR_POOL_SIZE); + if (active_rom == NULL) { + return LIBPARAMS_NOT_INITIALIZED; + } + romRead(active_rom, 0, (uint8_t*)integer_values_pool, INT_POOL_SIZE); + romRead(active_rom, _getStringMemoryPoolAddress(active_rom), + (uint8_t*)&string_values_pool, STR_POOL_SIZE); - for (uint_fast8_t idx = 0; idx < integers_amount; idx++) { + for (uint_fast16_t idx = 0; idx < integers_amount; idx++) { IntegerParamValue_t val = integer_values_pool[idx]; if (val < integer_desc_pool[idx].min || val > integer_desc_pool[idx].max) { integer_values_pool[idx] = integer_desc_pool[idx].def; } } - for (uint_fast8_t idx = 0; idx < strings_amount; idx++) { + for (uint_fast16_t idx = 0; idx < strings_amount; idx++) { // 255 value is default value for stm32, '\0' for ubuntu if (string_values_pool[idx][0] == 255 || string_values_pool[idx][0] == '\0') { memcpy(string_values_pool[idx], string_desc_pool[idx].def, MAX_STRING_LENGTH); + } else { + break; + } + } + + return LIBPARAMS_OK; +} + +int8_t paramsLoadRom(RomDriverInstance* rom_instance) { + romRead(rom_instance, 0, (uint8_t*)integer_values_pool, INT_POOL_SIZE); + romRead(rom_instance, _getStringMemoryPoolAddress(rom_instance), + (uint8_t*)&string_values_pool, STR_POOL_SIZE); + + for (uint_fast16_t idx = 0; idx < integers_amount; idx++) { + IntegerParamValue_t val = integer_values_pool[idx]; + if (val < integer_desc_pool[idx].min || val > integer_desc_pool[idx].max) { + rom_instance->erased = true; + return LIBPARAMS_OK; } } @@ -82,10 +122,28 @@ int8_t paramsSave() { if (all_params_amount == 0) { return LIBPARAMS_NOT_INITIALIZED; } - - romBeginWrite(&rom); - int8_t res = _save(); - romEndWrite(&rom); + int8_t res = 0; + if (standby_rom != NULL) { + // write params to standby rom + romBeginWrite(standby_rom); + res = _save(standby_rom); + romEndWrite(standby_rom); + // if save was successful erase active rom + // and switch roms + if (res == 0) { + RomDriverInstance* buffer = standby_rom; + standby_rom = active_rom; + active_rom = buffer; + standby_rom->erased = true; + romBeginWrite(standby_rom); + romEndWrite(standby_rom); + } + return res; + } + romBeginWrite(active_rom); + active_rom->erased = true; + res = _save(active_rom); + romEndWrite(active_rom); return res; } @@ -95,7 +153,7 @@ int8_t paramsResetToDefault() { } for (ParamIndex_t idx = 0; idx < integers_amount; idx++) { - if (!integer_desc_pool[idx].is_required) { + if (!integer_desc_pool[idx].is_required || integer_desc_pool[idx].is_mutable) { integer_values_pool[idx] = integer_desc_pool[idx].def; } } @@ -191,8 +249,7 @@ StringParamValue_t* paramsGetStringValue(ParamIndex_t param_idx) { return str; } -uint8_t paramsSetStringValue(ParamIndex_t param_idx, - uint8_t str_len, +uint8_t paramsSetStringValue(ParamIndex_t param_idx, uint8_t str_len, const StringParamValue_t param_value) { if (str_len > MAX_STRING_LENGTH || _isCorrectStringParamIndex(param_idx)) { return 0; @@ -225,8 +282,8 @@ static bool _isCorrectStringParamIndex(ParamIndex_t param_idx) { return param_idx < integers_amount || param_idx >= all_params_amount; } -static uint32_t _getStringMemoryPoolAddress() { - return romGetAvailableMemory(&rom) - MAX_STRING_LENGTH * strings_amount; +static uint32_t _getStringMemoryPoolAddress(RomDriverInstance* rom_driver) { + return romGetAvailableMemory(rom_driver) - MAX_STRING_LENGTH * strings_amount; } /** @@ -234,17 +291,36 @@ static uint32_t _getStringMemoryPoolAddress() { * An error means either a library internal error or the provided flash driver is incorrect. * If such errir is detected, stop writing immediately to avoid doing something wrong. */ -static int8_t _save() { +static int8_t _save(RomDriverInstance* rom_driver) { if (INT_POOL_SIZE != 0 && - 0 == romWrite(&rom, 0, (uint8_t*)integer_values_pool, INT_POOL_SIZE)) { + 0 == romWrite(rom_driver, 0, (uint8_t*)integer_values_pool, INT_POOL_SIZE)) { return LIBPARAMS_UNKNOWN_ERROR; } - size_t offset = _getStringMemoryPoolAddress(); + size_t offset = _getStringMemoryPoolAddress(rom_driver); if (STR_POOL_SIZE != 0 && - 0 == romWrite(&rom, offset, (uint8_t*)string_values_pool, STR_POOL_SIZE)) { + 0 == romWrite(rom_driver, offset, (uint8_t*)string_values_pool, STR_POOL_SIZE)) { return LIBPARAMS_UNKNOWN_ERROR; } + rom_driver->erased = false; + return LIBPARAMS_OK; +} + +/** + * @brief Choose a rom which addreses a non-erased part of flash memory + * **/ +int8_t _chooseRom() { + paramsLoadRom(&primary_rom); + paramsLoadRom(&redundant_rom); + active_rom = &primary_rom; + standby_rom = &redundant_rom; + if (primary_rom.erased) { + if (!redundant_rom.erased) { + active_rom = &redundant_rom; + standby_rom = &primary_rom; + } + } return LIBPARAMS_OK; } + diff --git a/libparams/storage.h b/libparams/storage.h index 6a16ba7..5152bcd 100644 --- a/libparams/storage.h +++ b/libparams/storage.h @@ -84,6 +84,12 @@ typedef uint16_t ParamIndex_t; int8_t paramsInit(ParamIndex_t int_num, ParamIndex_t str_num, int32_t first_page_idx, size_t pages_num); +/** + * @brief Initialize the redundant parameters pages if the rom page_idx was 256, then the redundant pages will be allocated at (256 - rom.pages_num idx). Call this on paramsSave() to backup parameters. + * @return LIBPARAMS_OK on success, otherwise < 0. + */ +int8_t paramsInitRedundantPage(); + /** * @brief Load parameters from a persistent memory: flash for stm32 and file for ubuntu. * @return LIBPARAMS_OK on success, otherwise < 0. diff --git a/platform_specific/ubuntu/FlashMemoryLayout.hpp b/platform_specific/ubuntu/FlashMemoryLayout.hpp index f0d1b16..a6a8327 100644 --- a/platform_specific/ubuntu/FlashMemoryLayout.hpp +++ b/platform_specific/ubuntu/FlashMemoryLayout.hpp @@ -15,12 +15,12 @@ typedef struct { IntegerDesc_t* integer_desc_pool; StringDesc_t* string_desc_pool; - uint8_t num_int_params; - uint8_t num_str_params; + uint16_t num_int_params; + uint16_t num_str_params; } ParametersLayout_t; typedef struct { - const uint8_t* memory_ptr; + uint8_t* memory_ptr; uint16_t page_size; uint8_t num_pages; uint32_t flash_size = page_size * num_pages; diff --git a/platform_specific/ubuntu/YamlParameters.cpp b/platform_specific/ubuntu/YamlParameters.cpp index 4f32be9..c545c80 100644 --- a/platform_specific/ubuntu/YamlParameters.cpp +++ b/platform_specific/ubuntu/YamlParameters.cpp @@ -10,9 +10,9 @@ #include #include #include +#include #include "storage.h" -#include "libparams_error_codes.h" #include "YamlParameters.hpp" YamlParameters::YamlParameters(FlashMemoryLayout_t flash_desc, @@ -60,10 +60,10 @@ int8_t YamlParameters::read_from_dir(const std::string& path) { } int8_t res; char file_name[256]; - uint8_t int_param_idx = 0; - uint8_t str_param_idx = 0; + uint16_t int_param_idx = 0; + uint16_t str_param_idx = 0; // read params values for each page - for (uint8_t idx = 0; idx < flash.num_pages; idx++) { + for (uint16_t idx = 0; idx < flash.num_pages; idx++) { std::ifstream params_storage_file; // check if temp file for the page already exists, else read from init file @@ -83,7 +83,7 @@ int8_t YamlParameters::read_from_dir(const std::string& path) { logger.info("data read from ", file_name); if ((int_param_idx > params.num_int_params) || (str_param_idx > params.num_str_params)) { - break;; + break; } res = __read_page(params_storage_file, &int_param_idx, &str_param_idx); params_storage_file.close(); @@ -110,9 +110,9 @@ int8_t YamlParameters::write_to_dir(const std::string& path) { int8_t res; char file_name[256]; // remember last written indexes - uint8_t int_param_idx = 0; - uint8_t str_param_idx = 0; - for (uint8_t idx = 0; idx < flash.num_pages; idx++) { + uint16_t int_param_idx = 0; + uint16_t str_param_idx = 0; + for (uint16_t idx = 0; idx < flash.num_pages; idx++) { snprintf(file_name, sizeof(file_name), "%s/%s_%d.yaml", path.c_str(), temp_file_name.c_str(), idx); std::ofstream params_storage_file; @@ -127,16 +127,17 @@ int8_t YamlParameters::write_to_dir(const std::string& path) { if (int_param_idx != params.num_int_params || str_param_idx != params.num_str_params) { logger.error("Number of parameters in the file isn't equal", " to the one specified in the constructor", - "int real: ", (int)int_param_idx, " expected: ", (int)params.num_int_params, - "\n", - "str real: ", (int)str_param_idx, " expected: ", (int)params.num_str_params); + "int real: ", (int)int_param_idx + 1, + " expected: ", (int)params.num_int_params, "\n", + "str real: ", (int)str_param_idx + 1, + " expected: ", (int)params.num_str_params); return LIBPARAMS_WRONG_ARGS; } return LIBPARAMS_OK; } -int8_t YamlParameters::__read_page(std::ifstream& params_storage_file, uint8_t* int_param_idx, - uint8_t* str_param_idx) { +int8_t YamlParameters::__read_page(std::ifstream& params_storage_file, uint16_t* int_param_idx, + uint16_t* str_param_idx) { std::string line; std::string value; @@ -148,7 +149,7 @@ int8_t YamlParameters::__read_page(std::ifstream& params_storage_file, uint8_t* } value = line.substr(delimiter_pos + 1); try { - if (*int_param_idx > params.num_int_params) { + if ((*int_param_idx) > params.num_int_params) { logger.error("Got more integer params than defined by num_int_params"); return LIBPARAMS_WRONG_ARGS; } @@ -160,17 +161,18 @@ int8_t YamlParameters::__read_page(std::ifstream& params_storage_file, uint8_t* memcpy((void*)(flash.memory_ptr + 4 * (*int_param_idx)), &int_value, 4); *int_param_idx = *int_param_idx + 1; } catch (std::invalid_argument const& ex) { - int offset = flash.flash_size - MAX_STRING_LENGTH * - (params.num_str_params - (*str_param_idx )); - if (*str_param_idx + 1> params.num_str_params) { - logger.error("Wrong num_str_params\n"); + uint32_t offset = flash.flash_size - MAX_STRING_LENGTH * + (params.num_str_params - (*str_param_idx )); + if ((*str_param_idx) >= params.num_str_params) { + logger.error("Wrong num_str_params expected: ", params.num_str_params, + " got: ", (*str_param_idx) + 1); return LIBPARAMS_WRONG_ARGS; } size_t quote_pos = value.find('"'); size_t quote_end_pos = value.find('"', quote_pos + 1); std::string str_value = value.substr(quote_pos + 1, quote_end_pos - quote_pos - 1); - if (offset < *int_param_idx * 4) { + if (offset < (*int_param_idx) * 4) { logger.error("params overlap last int param addr", *int_param_idx * 4, ", str param offset ", offset); return LIBPARAMS_WRONG_ARGS; @@ -186,17 +188,17 @@ int8_t YamlParameters::__read_page(std::ifstream& params_storage_file, uint8_t* return LIBPARAMS_OK; } -int8_t YamlParameters::__write_page(std::ofstream& params_storage_file, uint8_t* int_param_idx, - uint8_t* str_param_idx) { +int8_t YamlParameters::__write_page(std::ofstream& params_storage_file, uint16_t* int_param_idx, + uint16_t* str_param_idx) { if (*int_param_idx > params.num_int_params || *str_param_idx > params.num_str_params) { logger.error("int_param_idx or str_param_idx is bigger than defined by num_int_params\n"); return LIBPARAMS_WRONG_ARGS; } uint32_t n_bytes = 0; - uint8_t param_idx = *int_param_idx; + uint16_t param_idx = *int_param_idx; - for (uint8_t index = param_idx; index < params.num_int_params; index++) { + for (uint16_t index = param_idx; index < params.num_int_params; index++) { int32_t int_param_value; const char* name = params.integer_desc_pool[index].name; memcpy(&int_param_value, flash.memory_ptr + index * 4, 4); @@ -218,7 +220,7 @@ int8_t YamlParameters::__write_page(std::ofstream& params_storage_file, uint8_t* if (available_str_params < str_params_remained) { last_str_param_idx = prev_str_idx + available_str_params; } - for (uint8_t index = prev_str_idx; index < last_str_param_idx; index++) { + for (uint16_t index = prev_str_idx; index < last_str_param_idx; index++) { const char* name = params.string_desc_pool[index].name; if (name == nullptr) { return LIBPARAMS_OK; diff --git a/platform_specific/ubuntu/YamlParameters.hpp b/platform_specific/ubuntu/YamlParameters.hpp index f622c38..a0db837 100644 --- a/platform_specific/ubuntu/YamlParameters.hpp +++ b/platform_specific/ubuntu/YamlParameters.hpp @@ -15,12 +15,12 @@ static SimpleLogger logger("YamlParameters"); class YamlParameters { - FlashMemoryLayout_t flash; ParametersLayout_t params; std::string init_file_name = "init_params"; std::string temp_file_name = "temp_params"; public: + FlashMemoryLayout_t flash; explicit YamlParameters(FlashMemoryLayout_t flash_desc, ParametersLayout_t params_desc); int8_t read_from_dir(const std::string& path); @@ -30,10 +30,10 @@ class YamlParameters { int8_t set_temp_file_name(std::string file_name); private: - int8_t __write_page(std::ofstream& params_storage_file, uint8_t* int_param_idx, - uint8_t* str_param_idx); - int8_t __read_page(std::ifstream& params_storage_file, uint8_t* int_param_idx, - uint8_t* str_param_idx); + int8_t __write_page(std::ofstream& params_storage_file, uint16_t* int_param_idx, + uint16_t* str_param_idx); + int8_t __read_page(std::ifstream& params_storage_file, uint16_t* int_param_idx, + uint16_t* str_param_idx); }; #endif // LIBPARAM_YAML_PARAMETERS_HPP_ diff --git a/platform_specific/ubuntu/flash_driver.cpp b/platform_specific/ubuntu/flash_driver.cpp index 36abb23..1d12263 100644 --- a/platform_specific/ubuntu/flash_driver.cpp +++ b/platform_specific/ubuntu/flash_driver.cpp @@ -18,17 +18,17 @@ constexpr uint16_t str_params_size = NUM_OF_STR_PARAMS * MAX_STRING_LENGTH constexpr uint16_t int_parms_size = IntParamsIndexes::INTEGER_PARAMS_AMOUNT * 4; constexpr uint32_t params_size_bytes = (str_params_size + int_parms_size); constexpr uint8_t n_flash_pages = (params_size_bytes / PAGE_SIZE_BYTES) + 1; - -static uint8_t flash_memory[PAGE_SIZE_BYTES * (n_flash_pages)]; +// Extend flash size for redundant pages +static uint8_t flash_memory[2 * PAGE_SIZE_BYTES * (n_flash_pages)]; static bool is_locked = true; extern IntegerDesc_t integer_desc_pool[]; extern StringDesc_t string_desc_pool[]; -static const FlashMemoryLayout_t mem_layout = { - .memory_ptr = flash_memory, +static FlashMemoryLayout_t mem_layout = { + .memory_ptr = flash_memory, .page_size = PAGE_SIZE_BYTES, - .num_pages = n_flash_pages, + .num_pages = n_flash_pages, }; static ParametersLayout_t params_layout = { @@ -51,6 +51,9 @@ void flashInit() { #ifdef LIBPARAMS_TEMP_PARAMS_FILE_NAME yaml_params.set_temp_file_name(LIBPARAMS_TEMP_PARAMS_FILE_NAME); #endif + // load parameters to the last suited pages + // (such that primary rom at always would be filled after initialization) + yaml_params.flash.memory_ptr = &flashGetPointer()[mem_layout.flash_size]; __read_from_files(); } @@ -63,7 +66,7 @@ void flashLock() { } int8_t flashErase(uint32_t start_page_idx, uint32_t num_of_pages) { - if (is_locked || start_page_idx + num_of_pages > n_flash_pages || num_of_pages == 0) { + if (is_locked || start_page_idx + num_of_pages > 2 * n_flash_pages || num_of_pages == 0) { return LIBPARAMS_WRONG_ARGS; } memset(flash_memory + start_page_idx * PAGE_SIZE_BYTES, 0x00, num_of_pages * PAGE_SIZE_BYTES); @@ -82,17 +85,21 @@ size_t flashRead(uint8_t* data, size_t offset, size_t bytes_to_read) { } int8_t flashWrite(const uint8_t* data, size_t offset, size_t bytes_to_write) { - if (is_locked || offset < FLASH_START_ADDR || offset >= FLASH_START_ADDR + PAGE_SIZE_BYTES) { + if (is_locked || offset < FLASH_START_ADDR || + offset >= FLASH_START_ADDR + sizeof(flash_memory)) { return LIBPARAMS_WRONG_ARGS; } uint8_t* rom = &(flashGetPointer()[offset - FLASH_START_ADDR]); memcpy(rom, data, bytes_to_write); + uint8_t redundant = (offset - FLASH_START_ADDR) / mem_layout.flash_size; + yaml_params.flash.memory_ptr = &flashGetPointer() + [redundant * mem_layout.flash_size]; return __save_to_files(); } uint16_t flashGetNumberOfPages() { - return n_flash_pages; + return 2 * n_flash_pages; } uint16_t flashGetPageSize() { diff --git a/tests/unit_tests/CMakeLists.txt b/tests/unit_tests/CMakeLists.txt index a25fc20..70362ff 100644 --- a/tests/unit_tests/CMakeLists.txt +++ b/tests/unit_tests/CMakeLists.txt @@ -27,9 +27,18 @@ include_directories(${GTEST_INCLUDE_DIR}) set(LIBPARAMS_PLATFORM ubuntu) include(${ROOT_DIR}/CMakeLists.txt) -add_definitions(-DLIBPARAMS_PARAMS_DIR="${TESTS_DIR}/params") +set(LIBPARAMS_PARAMS_DIR="${CMAKE_CURRENT_BINARY_DIR}/params") +add_definitions(-DLIBPARAMS_PARAMS_DIR="${CMAKE_CURRENT_BINARY_DIR}/params") function(gen_test app_name test_file) + execute_process( + COMMAND ${ROOT_DIR}/scripts/generate_default_params.py --out-dir ${CMAKE_CURRENT_BINARY_DIR}/params -f ${TESTS_DIR}/params/params.c + --out-file-name "init_params" + RESULT_VARIABLE ret + ) + if(NOT ret EQUAL 0) + message( FATAL_ERROR "Default Params Generator has been failed. Abort.") + endif() # Create the executable target add_executable(${app_name} ${test_file} diff --git a/tests/unit_tests/test_flash_driver.cpp b/tests/unit_tests/test_flash_driver.cpp index c18ae8e..83c70ae 100644 --- a/tests/unit_tests/test_flash_driver.cpp +++ b/tests/unit_tests/test_flash_driver.cpp @@ -36,13 +36,6 @@ TEST(TestFlashDriver, test_erase_error_locked) { ASSERT_TRUE(res < 0); } -TEST(TestFlashDriver, test_erase_error_bad_first_arg) { - flashUnlock(); - auto res = flashErase(1, 1); - flashLock(); - ASSERT_TRUE(res < 0); -} - TEST(TestFlashDriver, test_erase_error_bad_second_arg) { flashUnlock(); auto res = flashErase(0, 0); diff --git a/tests/unit_tests/test_rom.cpp b/tests/unit_tests/test_rom.cpp index bfd0f69..662441e 100644 --- a/tests/unit_tests/test_rom.cpp +++ b/tests/unit_tests/test_rom.cpp @@ -113,7 +113,7 @@ TEST_F(RomDriverMultiplePagesTest, writeDataExceedingBounds) { // 5. Offset and size out of bound romBeginWrite(&rom); - ASSERT_EQ(romWrite(&rom, 1500, SAMPLE_DATA, 1500), 0); + ASSERT_EQ(romWrite(&rom, 3000, SAMPLE_DATA, 3000), 0); romEndWrite(&rom); // 6. Without romBeginWrite() and romEndWrite() diff --git a/tests/unit_tests/test_storage.cpp b/tests/unit_tests/test_storage.cpp index 473a375..f10108e 100644 --- a/tests/unit_tests/test_storage.cpp +++ b/tests/unit_tests/test_storage.cpp @@ -24,8 +24,31 @@ typedef enum { #define STRING_PARAMS_AMOUNT ((ParamIndex_t)2) #define NUMBER_OF_PARAMS (INTEGER_PARAMS_AMOUNT + STRING_PARAMS_AMOUNT) +extern RomDriverInstance* active_rom; +extern RomDriverInstance* standby_rom; +extern IntegerParamValue_t integer_values_pool[]; +class RedundantRomStorageDriverTest : public ::testing::Test { +protected: + size_t primary_rom_addr; + size_t redundant_rom_addr; + void SetUp() override { + paramsInit(INTEGER_PARAMS_AMOUNT, STRING_PARAMS_AMOUNT, -1, 1); + EXPECT_NE(active_rom, nullptr); + paramsInitRedundantPage(); + EXPECT_NE(standby_rom, nullptr); + primary_rom_addr = active_rom->addr; + redundant_rom_addr = standby_rom->addr; + paramsLoad(); + } + + void TearDown() override { + active_rom = nullptr; + standby_rom = nullptr; + } +}; + class SinglePageStorageDriverTest : public ::testing::Test { protected: RomDriverInstance rom; @@ -68,7 +91,6 @@ TEST_F(EmptyStorageDriverTest, initializeWithInvalidaPageIndex) { ASSERT_EQ(LIBPARAMS_UNKNOWN_ERROR, paramsInit(INTEGER_PARAMS_AMOUNT, STRING_PARAMS_AMOUNT, -1, 2)); } - // Test Case 2: Load Parameters // Test 2.1: Load Parameters Successfully TEST_F(SinglePageStorageDriverTest, loadParametersSuccessfully) { @@ -124,6 +146,7 @@ TEST_F(EmptyStorageDriverTest, saveParametersSuccessfully) { ASSERT_EQ(LIBPARAMS_OK, paramsInit((ParamIndex_t)512, 0, -1, 1)); ASSERT_EQ(LIBPARAMS_OK, paramsSave()); } + // Test 3.2: Save Parameters with Uninitialized Parameters TEST_F(EmptyStorageDriverTest, saveParametersWithUninitializedParameters) { ASSERT_EQ(LIBPARAMS_NOT_INITIALIZED, paramsSave()); @@ -297,6 +320,34 @@ TEST_F(SinglePageStorageDriverTest, test_paramsSetStringValue) { ASSERT_EQ(0, paramsSetStringValue(NODE_NAME, MAX_STRING_LENGTH + 1, nullptr)); } +TEST_F(RedundantRomStorageDriverTest, pageSwitchAfterSave) { + ASSERT_EQ(active_rom->addr, primary_rom_addr); + ASSERT_EQ(standby_rom->addr, redundant_rom_addr); + + paramsSave(); + ASSERT_EQ(active_rom->addr, redundant_rom_addr); + ASSERT_EQ(standby_rom->addr, primary_rom_addr); + + ASSERT_TRUE(standby_rom->erased); +} + + +TEST_F(RedundantRomStorageDriverTest, pageEraseAfterSave) { + ASSERT_EQ(active_rom->addr, primary_rom_addr); + ASSERT_EQ(standby_rom->addr, redundant_rom_addr); + + paramsSave(); + ASSERT_EQ(active_rom->addr, redundant_rom_addr); + ASSERT_EQ(standby_rom->addr, primary_rom_addr); + // standby rom has to be erased + ASSERT_TRUE(standby_rom->erased); + romRead(standby_rom, 0, (uint8_t*)integer_values_pool, 4); + ASSERT_EQ(integer_values_pool[0], 0); + + romRead(active_rom, 0, (uint8_t*)integer_values_pool, 4); + ASSERT_NE(integer_values_pool[0], 0); +} + int main(int argc, char *argv[]) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/tests/unit_tests/test_yaml_parameters.cpp b/tests/unit_tests/test_yaml_parameters.cpp index 7aa719d..48e17b2 100644 --- a/tests/unit_tests/test_yaml_parameters.cpp +++ b/tests/unit_tests/test_yaml_parameters.cpp @@ -93,7 +93,7 @@ class YamlParamsTestBase : public ::testing::Test{ } }; -// Case 1. Check YamlParameters initialization with different parameters tuples +// Case 1. Check YamlParameters initialization with different parameters sets struct InitParameters { uint8_t* flash_ptr;