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 <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-06-22 13:52:30 +02:00 committed by Carles Cufí
parent 5a4fd10624
commit 2d3c53f705
5 changed files with 167 additions and 84 deletions

View file

@ -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

View file

@ -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)

View file

@ -19,18 +19,9 @@
#ifdef CONFIG_ARCH_POSIX
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#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)

View file

@ -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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <nsi_tracing.h>
/*
* 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);
}
}

View file

@ -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 */