drivers/flash/flash_simulator: Added file back end for posix arch

Extended flash simulator for posix architecture to read/write data
from a binary file on the host file system.

Further enable the flash simulator by default on native_posix(_64)
boards and updated the documentation accordingly.

Signed-off-by: Jan Van Winkel <jan.van_winkel@dxplore.eu>
This commit is contained in:
Jan Van Winkel 2019-11-10 02:16:54 +01:00 committed by Anas Nashif
commit 8cd4a817d9
7 changed files with 123 additions and 22 deletions

View file

@ -90,7 +90,7 @@ endif # TRACING_CTF
if FLASH if FLASH
config FLASH_NATIVE_POSIX config FLASH_SIMULATOR
default y default y
endif # FLASH endif # FLASH

View file

@ -537,17 +537,9 @@ The following peripherals are currently provided with this board:
**Flash driver**: **Flash driver**:
A flash driver is provided that accesses all flash data through a binary file A flash driver is provided that accesses all flash data through a binary file
on the host file system. on the host file system. The behavior of the flash device can be configured
through the native POSIX board devicetree or Kconfig settings under
The size of the flash device can be configured through the native POSIX board :option:`CONFIG_FLASH_SIMULATOR`.
devicetree and the sector size is configurable via the Kconfig option
:option:`CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE`. The sector size will only be
used to return flash page layout related information and no restrictions are
imposed by the driver based on the configured sector size. As such an erase
operation of arbitrary size will succeed on the emulated flash device.
Further the emulated device will not impose any write restriction that are
applicable for a regular flash device, including changing the state of a bit
from zero to one.
By default the binary data is located in the file *flash.bin* in the current By default the binary data is located in the file *flash.bin* in the current
working directory. The location of this file can be changed through the working directory. The location of this file can be changed through the

View file

@ -4,6 +4,6 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define DT_FLASH_DEV_NAME DT_INST_0_ZEPHYR_NATIVE_POSIX_FLASH_CONTROLLER_LABEL #define DT_FLASH_DEV_NAME DT_INST_0_ZEPHYR_SIM_FLASH_LABEL
#define DT_UART_0_DEV_NAME DT_ZEPHYR_NATIVE_POSIX_UART_UART_LABEL #define DT_UART_0_DEV_NAME DT_ZEPHYR_NATIVE_POSIX_UART_UART_LABEL

View file

@ -23,7 +23,7 @@
}; };
flashcontroller0: flash-controller@0 { flashcontroller0: flash-controller@0 {
compatible = "zephyr,native-posix-flash-controller"; compatible = "zephyr,sim-flash";
reg = <0x00000000 DT_SIZE_K(2048)>; reg = <0x00000000 DT_SIZE_K(2048)>;
#address-cells = <1>; #address-cells = <1>;
@ -35,7 +35,7 @@
status = "okay"; status = "okay";
compatible = "soc-nv-flash"; compatible = "soc-nv-flash";
label = "flash"; label = "flash";
erase-block-size = <1>; erase-block-size = <4096>;
write-block-size = <1>; write-block-size = <1>;
reg = <0x00000000 DT_SIZE_K(2048)>; reg = <0x00000000 DT_SIZE_K(2048)>;

View file

@ -13,11 +13,34 @@
#include <stats/stats.h> #include <stats/stats.h>
#include <string.h> #include <string.h>
#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 "cmdline.h"
#include "soc.h"
#endif /* CONFIG_ARCH_POSIX */
/* configuration derived from DT */ /* configuration derived from DT */
#ifdef CONFIG_ARCH_POSIX
#define FLASH_SIMULATOR_BASE_OFFSET DT_FLASH_BASE_ADDRESS
#define FLASH_SIMULATOR_ERASE_UNIT DT_FLASH_ERASE_BLOCK_SIZE
#define FLASH_SIMULATOR_PROG_UNIT DT_FLASH_WRITE_BLOCK_SIZE
#define FLASH_SIMULATOR_FLASH_SIZE (DT_FLASH_SIZE * 1024)
#define FLASH_SIMULATOR_DEV_NAME DT_FLASH_DEV_NAME
#else
#define FLASH_SIMULATOR_BASE_OFFSET DT_FLASH_SIM_BASE_ADDRESS #define FLASH_SIMULATOR_BASE_OFFSET DT_FLASH_SIM_BASE_ADDRESS
#define FLASH_SIMULATOR_ERASE_UNIT DT_FLASH_SIM_ERASE_BLOCK_SIZE #define FLASH_SIMULATOR_ERASE_UNIT DT_FLASH_SIM_ERASE_BLOCK_SIZE
#define FLASH_SIMULATOR_PROG_UNIT DT_FLASH_SIM_WRITE_BLOCK_SIZE #define FLASH_SIMULATOR_PROG_UNIT DT_FLASH_SIM_WRITE_BLOCK_SIZE
#define FLASH_SIMULATOR_FLASH_SIZE DT_FLASH_SIM_SIZE #define FLASH_SIMULATOR_FLASH_SIZE DT_FLASH_SIM_SIZE
#define FLASH_SIMULATOR_DEV_NAME "FLASH_SIMULATOR"
#endif /* CONFIG_ARCH_POSIX */
#define FLASH_SIMULATOR_PAGE_COUNT (FLASH_SIMULATOR_FLASH_SIZE / \ #define FLASH_SIMULATOR_PAGE_COUNT (FLASH_SIMULATOR_FLASH_SIZE / \
FLASH_SIMULATOR_ERASE_UNIT) FLASH_SIMULATOR_ERASE_UNIT)
@ -102,7 +125,15 @@ STATS_NAME(flash_sim_thresholds, max_erase_calls)
STATS_NAME(flash_sim_thresholds, max_len) STATS_NAME(flash_sim_thresholds, max_len)
STATS_NAME_END(flash_sim_thresholds); STATS_NAME_END(flash_sim_thresholds);
#ifdef CONFIG_ARCH_POSIX
static u8_t *mock_flash;
static int flash_fd = -1;
static const char *flash_file_path;
static const char default_flash_file_path[] = "flash.bin";
#else
static u8_t mock_flash[FLASH_SIMULATOR_FLASH_SIZE]; static u8_t mock_flash[FLASH_SIMULATOR_FLASH_SIZE];
#endif /* CONFIG_ARCH_POSIX */
static bool write_protection; static bool write_protection;
static const struct flash_driver_api flash_sim_api; static const struct flash_driver_api flash_sim_api;
@ -322,16 +353,96 @@ static const struct flash_driver_api flash_sim_api = {
#endif #endif
}; };
#ifdef CONFIG_ARCH_POSIX
static int flash_mock_init(struct device *dev)
{
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;
}
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;
}
#else
static int flash_mock_init(struct device *dev)
{
memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash));
return 0;
}
#endif /* CONFIG_ARCH_POSIX */
static int flash_init(struct device *dev) static int flash_init(struct device *dev)
{ {
STATS_INIT_AND_REG(flash_sim_stats, STATS_SIZE_32, "flash_sim_stats"); STATS_INIT_AND_REG(flash_sim_stats, STATS_SIZE_32, "flash_sim_stats");
STATS_INIT_AND_REG(flash_sim_thresholds, STATS_SIZE_32, STATS_INIT_AND_REG(flash_sim_thresholds, STATS_SIZE_32,
"flash_sim_thresholds"); "flash_sim_thresholds");
memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash)); return flash_mock_init(dev);
return 0;
} }
DEVICE_AND_API_INIT(flash_simulator, "FLASH_SIMULATOR", flash_init, NULL, NULL, DEVICE_AND_API_INIT(flash_simulator, FLASH_SIMULATOR_DEV_NAME, flash_init,
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL, NULL, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&flash_sim_api); &flash_sim_api);
#ifdef CONFIG_ARCH_POSIX
static void flash_native_posix_cleanup(void)
{
if ((mock_flash != MAP_FAILED) && (mock_flash != NULL)) {
munmap(mock_flash, FLASH_SIMULATOR_FLASH_SIZE);
}
if (flash_fd != -1) {
close(flash_fd);
}
}
static void flash_native_posix_options(void)
{
static struct args_struct_t flash_options[] = {
{ .manual = false,
.is_mandatory = false,
.is_switch = false,
.option = "flash",
.name = "path",
.type = 's',
.dest = (void *)&flash_file_path,
.call_when_found = NULL,
.descript = "Path to binary file to be used as flash" },
ARG_TABLE_ENDMARKER
};
native_add_command_line_opts(flash_options);
}
NATIVE_TASK(flash_native_posix_options, PRE_BOOT_1, 1);
NATIVE_TASK(flash_native_posix_cleanup, ON_EXIT, 1);
#endif /* CONFIG_ARCH_POSIX */

View file

@ -1 +0,0 @@
CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE=4

View file

@ -1 +0,0 @@
CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE=4