From 2d3c53f705cc11ae0c2a1b2d43016a030fffdce6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 22 Jun 2023 13:52:30 +0200 Subject: [PATCH] flash simulator: Refactor native part so it works with emb libC Refactor the part of the flash simulator that interacts with the host when build for native platforms, so it is possible to use it also with the embedded libCs. Signed-off-by: Alberto Escolar Piedras --- boards/posix/native_sim/doc/index.rst | 2 +- drivers/flash/CMakeLists.txt | 9 +- drivers/flash/flash_simulator.c | 97 ++++---------------- drivers/flash/flash_simulator_native.c | 117 +++++++++++++++++++++++++ drivers/flash/flash_simulator_native.h | 26 ++++++ 5 files changed, 167 insertions(+), 84 deletions(-) create mode 100644 drivers/flash/flash_simulator_native.c create mode 100644 drivers/flash/flash_simulator_native.h diff --git a/boards/posix/native_sim/doc/index.rst b/boards/posix/native_sim/doc/index.rst index 2f524829b72..7c692e2affc 100644 --- a/boards/posix/native_sim/doc/index.rst +++ b/boards/posix/native_sim/doc/index.rst @@ -112,7 +112,7 @@ host libC (:kconfig:option:`CONFIG_EXTERNAL_LIBC`). entropy, native posix entropy, :kconfig:option:`CONFIG_FAKE_ENTROPY_NATIVE_POSIX`, all eprom, eprom emulator, :kconfig:option:`CONFIG_EEPROM_EMULATOR`, host libC ethernet, eth native_posix, :kconfig:option:`CONFIG_ETH_NATIVE_POSIX`, host libC - flash, flash simulator, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, host libC + flash, flash simulator, :kconfig:option:`CONFIG_FLASH_SIMULATOR`, all flash, host based flash access, :kconfig:option:`CONFIG_FUSE_FS_ACCESS`, host libC gpio, GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL`, all gpio, SDL GPIO emulator, :kconfig:option:`CONFIG_GPIO_EMUL_SDL`, all diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 181f16101db..8266c8c1619 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -18,7 +18,14 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_CC13XX_CC26XX soc_flash_cc13xx_cc2 zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_TELINK_B91 soc_flash_b91.c) zephyr_library_sources_ifdef(CONFIG_SPI_NOR spi_nor.c) zephyr_library_sources_ifdef(CONFIG_NORDIC_QSPI_NOR nrf_qspi_nor.c) -zephyr_library_sources_ifdef(CONFIG_FLASH_SIMULATOR flash_simulator.c) +if(CONFIG_FLASH_SIMULATOR) + zephyr_library_sources(flash_simulator.c) + if(CONFIG_NATIVE_LIBRARY) + target_sources(native_simulator INTERFACE flash_simulator_native.c) + elseif(CONFIG_ARCH_POSIX) + zephyr_library_sources(flash_simulator_native.c) + endif() +endif() zephyr_library_sources_ifdef(CONFIG_SPI_FLASH_AT45 spi_flash_at45.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ITE_IT8XXX2 flash_ite_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF soc_flash_nrf.c) diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 1f9aa83c395..9fe5d230207 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -19,18 +19,9 @@ #ifdef CONFIG_ARCH_POSIX -#include -#include -#include -#include -#include -#include -#include -#include - +#include "flash_simulator_native.h" #include "cmdline.h" #include "soc.h" - #define DEFAULT_FLASH_FILE_PATH "flash.bin" #endif /* CONFIG_ARCH_POSIX */ @@ -384,64 +375,22 @@ static const struct flash_driver_api flash_sim_api = { static int flash_mock_init(const struct device *dev) { - struct stat f_stat; int rc; - ARG_UNUSED(dev); - if (flash_in_ram == true) { - mock_flash = (uint8_t *)malloc(FLASH_SIMULATOR_FLASH_SIZE); - if (mock_flash == NULL) { - posix_print_warning("Could not allocate flash in the process heap %s\n", - strerror(errno)); - return -EIO; - } + if (flash_in_ram == false && flash_file_path == NULL) { + flash_file_path = DEFAULT_FLASH_FILE_PATH; + } + + rc = flash_mock_init_native(flash_in_ram, &mock_flash, FLASH_SIMULATOR_FLASH_SIZE, + &flash_fd, flash_file_path, FLASH_SIMULATOR_ERASE_VALUE, + flash_erase_at_start); + + if (rc < 0) { + return -EIO; } else { - - if (flash_file_path == NULL) { - flash_file_path = DEFAULT_FLASH_FILE_PATH; - } - - flash_fd = open(flash_file_path, O_RDWR | O_CREAT, (mode_t)0600); - if (flash_fd == -1) { - posix_print_warning("Failed to open flash device file " - "%s: %s\n", - flash_file_path, strerror(errno)); - return -EIO; - } - - rc = fstat(flash_fd, &f_stat); - if (rc) { - posix_print_warning("Failed to get status of flash device file " - "%s: %s\n", - flash_file_path, strerror(errno)); - return -EIO; - } - - if (ftruncate(flash_fd, FLASH_SIMULATOR_FLASH_SIZE) == -1) { - posix_print_warning("Failed to resize flash device file " - "%s: %s\n", - flash_file_path, strerror(errno)); - return -EIO; - } - - mock_flash = mmap(NULL, FLASH_SIMULATOR_FLASH_SIZE, - PROT_WRITE | PROT_READ, MAP_SHARED, flash_fd, 0); - if (mock_flash == MAP_FAILED) { - posix_print_warning("Failed to mmap flash device file " - "%s: %s\n", - flash_file_path, strerror(errno)); - return -EIO; - } + return 0; } - - if ((flash_erase_at_start == true) || (flash_in_ram == true) || (f_stat.st_size == 0)) { - /* Erase the memory unit by pulling all bits to the configured erase value */ - (void)memset(mock_flash, FLASH_SIMULATOR_ERASE_VALUE, - FLASH_SIMULATOR_FLASH_SIZE); - } - - return 0; } #else @@ -477,25 +426,9 @@ DEVICE_DT_INST_DEFINE(0, flash_init, NULL, static void flash_native_posix_cleanup(void) { - if (flash_in_ram == true) { - if (mock_flash != NULL) { - free(mock_flash); - } - return; - } - - if ((mock_flash != MAP_FAILED) && (mock_flash != NULL)) { - munmap(mock_flash, FLASH_SIMULATOR_FLASH_SIZE); - } - - if (flash_fd != -1) { - close(flash_fd); - } - - if ((flash_rm_at_exit == true) && (flash_file_path != NULL)) { - /* We try to remove the file but do not error out if we can't */ - (void) remove(flash_file_path); - } + flash_mock_cleanup_native(flash_in_ram, flash_fd, mock_flash, + FLASH_SIMULATOR_FLASH_SIZE, flash_file_path, + flash_rm_at_exit); } static void flash_native_posix_options(void) diff --git a/drivers/flash/flash_simulator_native.c b/drivers/flash/flash_simulator_native.c new file mode 100644 index 00000000000..b31e42c05e0 --- /dev/null +++ b/drivers/flash/flash_simulator_native.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + * + * Part of flash simulator which interacts with the host OS + * + * When building for the native simulator, this file is built in the + * native simulator runner/host context, and not in Zephyr/embedded context. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Initialize the flash buffer. + * And, if the content is to be kept on disk map it to the the buffer to the file. + * + * Returns -1 on failure + * 0 on success + */ +int flash_mock_init_native(bool flash_in_ram, uint8_t **mock_flash, unsigned int size, + int *flash_fd, const char *flash_file_path, + unsigned int erase_value, bool flash_erase_at_start) +{ + struct stat f_stat; + int rc; + + if (flash_in_ram == true) { + *mock_flash = (uint8_t *)malloc(size); + if (*mock_flash == NULL) { + nsi_print_warning("Could not allocate flash in the process heap %s\n", + strerror(errno)); + return -1; + } + } else { + *flash_fd = open(flash_file_path, O_RDWR | O_CREAT, (mode_t)0600); + if (*flash_fd == -1) { + nsi_print_warning("Failed to open flash device file " + "%s: %s\n", + flash_file_path, strerror(errno)); + return -1; + } + + rc = fstat(*flash_fd, &f_stat); + if (rc) { + nsi_print_warning("Failed to get status of flash device file " + "%s: %s\n", + flash_file_path, strerror(errno)); + return -1; + } + + if (ftruncate(*flash_fd, size) == -1) { + nsi_print_warning("Failed to resize flash device file " + "%s: %s\n", + flash_file_path, strerror(errno)); + return -1; + } + + *mock_flash = mmap(NULL, size, + PROT_WRITE | PROT_READ, MAP_SHARED, *flash_fd, 0); + if (*mock_flash == MAP_FAILED) { + nsi_print_warning("Failed to mmap flash device file " + "%s: %s\n", + flash_file_path, strerror(errno)); + return -1; + } + } + + if ((flash_erase_at_start == true) || (flash_in_ram == true) || (f_stat.st_size == 0)) { + /* Erase the memory unit by pulling all bits to the configured erase value */ + (void)memset(*mock_flash, erase_value, size); + } + + return 0; +} + +/* + * If in RAM: Free the mock buffer + * If in disk: unmap the flash file from RAM, close the file, and if configured to do so, + * delete the file. + */ +void flash_mock_cleanup_native(bool flash_in_ram, int flash_fd, uint8_t *mock_flash, + unsigned int size, const char *flash_file_path, + bool flash_rm_at_exit) +{ + + if (flash_in_ram == true) { + if (mock_flash != NULL) { + free(mock_flash); + } + return; + } + + if ((mock_flash != MAP_FAILED) && (mock_flash != NULL)) { + munmap(mock_flash, size); + } + + if (flash_fd != -1) { + close(flash_fd); + } + + if ((flash_rm_at_exit == true) && (flash_file_path != NULL)) { + /* We try to remove the file but do not error out if we can't */ + (void) remove(flash_file_path); + } +} diff --git a/drivers/flash/flash_simulator_native.h b/drivers/flash/flash_simulator_native.h new file mode 100644 index 00000000000..a59136c1c20 --- /dev/null +++ b/drivers/flash/flash_simulator_native.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef DRIVERS_FLASH_FLASH_SIMULATOR_NATIVE_H +#define DRIVERS_FLASH_FLASH_SIMULATOR_NATIVE_H + +#ifdef __cplusplus +extern "C" { +#endif + +int flash_mock_init_native(bool flash_in_ram, uint8_t **mock_flash, unsigned int size, + int *flash_fd, const char *flash_file_path, + unsigned int erase_value, bool flash_erase_at_start); + +void flash_mock_cleanup_native(bool flash_in_ram, int flash_fd, uint8_t *mock_flash, + unsigned int size, const char *flash_file_path, + bool flash_rm_at_exit); + +#ifdef __cplusplus +} +#endif + +#endif /* DRIVERS_FLASH_FLASH_SIMULATOR_NATIVE_H */