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:
parent
01c03a27d7
commit
8cd4a817d9
7 changed files with 123 additions and 22 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)>;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE=4
|
|
|
@ -1 +0,0 @@
|
||||||
CONFIG_FLASH_NATIVE_POSIX_SECTOR_SIZE=4
|
|
Loading…
Add table
Add a link
Reference in a new issue