From aad5528191874fa5ea3ed281b2f5c81def27ef97 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:19:05 +0000 Subject: [PATCH 1/5] drivers/flash: Add API call returning flash parameters Adds flash_get_parameters call to API that returns pointer to structure describing flash parameters. Currently only erase_value parameter is provided via the structure. Signed-off-by: Dominik Ermel --- include/drivers/flash.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/include/drivers/flash.h b/include/drivers/flash.h index 336c863410faa..62e68302b96cd 100644 --- a/include/drivers/flash.h +++ b/include/drivers/flash.h @@ -36,12 +36,22 @@ struct flash_pages_layout { }; #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +/** + * Flash memory parameters. Contents of this structure suppose to be + * filled in during flash device initialization and stay constant + * through a runtime. + */ +struct flash_parameters { + uint8_t erase_value; /* Byte value of erased flash */ +}; + typedef int (*flash_api_read)(struct device *dev, off_t offset, void *data, size_t len); typedef int (*flash_api_write)(struct device *dev, off_t offset, const void *data, size_t len); typedef int (*flash_api_erase)(struct device *dev, off_t offset, size_t size); typedef int (*flash_api_write_protection)(struct device *dev, bool enable); +typedef const struct flash_parameters* (*flash_api_get_parameters)(const struct device *dev); #if defined(CONFIG_FLASH_PAGE_LAYOUT) /** @@ -75,6 +85,7 @@ __subsystem struct flash_driver_api { flash_api_write write; flash_api_erase erase; flash_api_write_protection write_protection; + flash_api_get_parameters get_parameters; #if defined(CONFIG_FLASH_PAGE_LAYOUT) flash_api_pages_layout page_layout; #endif /* CONFIG_FLASH_PAGE_LAYOUT */ @@ -296,6 +307,28 @@ static inline size_t z_impl_flash_get_write_block_size(struct device *dev) return api->write_block_size; } + +/** + * @brief Get pointer to flash_parameters structure + * + * Returned pointer points to a structure that should be considered + * constant through a runtime, regardless if it is defined in RAM or + * Flash. + * Developer is free to cache the structure pointer or copy its contents. + * + * @return pointer to flash_parameters structure characteristic for + * the device. + */ +__syscall const struct flash_parameters *flash_get_parameters(const struct device *dev); + +static inline const struct flash_parameters *z_impl_flash_get_parameters(const struct device *dev) +{ + const struct flash_driver_api *api = + (const struct flash_driver_api *)dev->driver_api; + + return api->get_parameters(dev); +} + #ifdef __cplusplus } #endif From 4e9e14d216908b5c2495803104b9de66a6d97837 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:30:32 +0000 Subject: [PATCH 2/5] drivers/flash: Add support for flash_get_parameters to drivers With addition of flash_get_parameters API call, it is needed to provide support for the API to flash drivers. Signed-off-by: Dominik Ermel --- boards/posix/native_posix/native_posix.dts | 1 + boards/x86/qemu_x86/qemu_x86.dts | 1 + drivers/flash/flash_gecko.c | 14 +++++++++++ drivers/flash/flash_sam.c | 13 +++++++++++ drivers/flash/flash_sam0.c | 13 +++++++++++ drivers/flash/flash_simulator.c | 23 +++++++++++++++---- drivers/flash/flash_stm32.c | 14 +++++++++++ drivers/flash/nrf_qspi_nor.c | 13 +++++++++++ drivers/flash/soc_flash_mcux.c | 17 ++++++++++++-- drivers/flash/soc_flash_nios2_qspi.c | 13 +++++++++++ drivers/flash/soc_flash_nrf.c | 13 +++++++++++ drivers/flash/soc_flash_rv32m1.c | 13 +++++++++++ drivers/flash/spi_flash_at45.c | 13 +++++++++++ drivers/flash/spi_flash_w25qxxdv.c | 13 +++++++++++ drivers/flash/spi_nor.c | 13 +++++++++++ .../flash_controller/zephyr,sim-flash.yaml | 6 +++++ tests/drivers/flash_simulator/src/main.c | 15 +++++++++++- 17 files changed, 201 insertions(+), 7 deletions(-) diff --git a/boards/posix/native_posix/native_posix.dts b/boards/posix/native_posix/native_posix.dts index 17a8cc62333b8..35cb1649c94fb 100644 --- a/boards/posix/native_posix/native_posix.dts +++ b/boards/posix/native_posix/native_posix.dts @@ -30,6 +30,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; label = "flash_ctrl"; diff --git a/boards/x86/qemu_x86/qemu_x86.dts b/boards/x86/qemu_x86/qemu_x86.dts index 7a998d1c9932b..19332989980e6 100644 --- a/boards/x86/qemu_x86/qemu_x86.dts +++ b/boards/x86/qemu_x86/qemu_x86.dts @@ -54,6 +54,7 @@ #address-cells = <1>; #size-cells = <1>; + erase-value = <0xff>; flash_sim0: flash_sim@0 { compatible = "soc-nv-flash"; diff --git a/drivers/flash/flash_gecko.c b/drivers/flash/flash_gecko.c index 9fb7a2f4e4cd0..57abd4ea610f4 100644 --- a/drivers/flash/flash_gecko.c +++ b/drivers/flash/flash_gecko.c @@ -24,6 +24,11 @@ struct flash_gecko_data { struct k_sem mutex; }; + +static const struct flash_parameters flash_gecko_parameters = { + .erase_value = 0xff, +}; + #define DEV_NAME(dev) ((dev)->name) #define DEV_DATA(dev) \ ((struct flash_gecko_data *const)(dev)->driver_data) @@ -178,6 +183,14 @@ void flash_gecko_page_layout(struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_gecko_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_gecko_parameters; +} + static int flash_gecko_init(struct device *dev) { struct flash_gecko_data *const dev_data = DEV_DATA(dev); @@ -199,6 +212,7 @@ static const struct flash_driver_api flash_gecko_driver_api = { .write = flash_gecko_write, .erase = flash_gecko_erase, .write_protection = flash_gecko_write_protection, + .get_parameters = flash_gecko_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_gecko_page_layout, #endif diff --git a/drivers/flash/flash_sam.c b/drivers/flash/flash_sam.c index c2f923edfd754..0e88216f85936 100644 --- a/drivers/flash/flash_sam.c +++ b/drivers/flash/flash_sam.c @@ -46,6 +46,10 @@ struct flash_sam_dev_data { struct k_sem sem; }; +static const struct flash_parameters flash_sam_parameters = { + .erase_value = 0xff, +}; + #define DEV_CFG(dev) \ ((const struct flash_sam_dev_cfg *const)(dev)->config_info) @@ -330,6 +334,14 @@ void flash_sam_page_layout(struct device *dev, } #endif +static const struct flash_parameters * +flash_sam_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_sam_parameters; +} + static int flash_sam_init(struct device *dev) { struct flash_sam_dev_data *const data = DEV_DATA(dev); @@ -344,6 +356,7 @@ static const struct flash_driver_api flash_sam_api = { .erase = flash_sam_erase, .write = flash_sam_write, .read = flash_sam_read, + .get_parameters = flash_sim_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sam_page_layout, #endif diff --git a/drivers/flash/flash_sam0.c b/drivers/flash/flash_sam0.c index b611b64d38c69..24289bcf5f35f 100644 --- a/drivers/flash/flash_sam0.c +++ b/drivers/flash/flash_sam0.c @@ -61,6 +61,10 @@ static const struct flash_pages_layout flash_sam0_pages_layout = { }; #endif +static const struct flash_parameters flash_sam0_parameters = { + .erase_value = 0xff, +}; + static inline void flash_sam0_sem_take(struct device *dev) { struct flash_sam0_data *ctx = dev->driver_data; @@ -388,6 +392,14 @@ void flash_sam0_page_layout(struct device *dev, } #endif +static const struct flash_parameters * +flash_sam0_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_sam0_parameters; +} + static int flash_sam0_init(struct device *dev) { struct flash_sam0_data *ctx = dev->driver_data; @@ -414,6 +426,7 @@ static const struct flash_driver_api flash_sam0_api = { .erase = flash_sam0_erase, .write = flash_sam0_write, .read = flash_sam0_read, + .get_parameters = flash_sam0_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sam0_page_layout, #endif diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 263dd5de1278e..511db4661db23 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -42,6 +42,8 @@ #define FLASH_SIMULATOR_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) #define FLASH_SIMULATOR_DEV_NAME DT_INST_LABEL(0) +#define FLASH_SIMULATOR_ERASE_VALUE \ + DT_PROP(DT_PARENT(SOC_NV_FLASH_NODE), erase_value) #define FLASH_SIMULATOR_PAGE_COUNT (FLASH_SIMULATOR_FLASH_SIZE / \ FLASH_SIMULATOR_ERASE_UNIT) @@ -139,6 +141,10 @@ static bool write_protection; static const struct flash_driver_api flash_sim_api; +static const struct flash_parameters flash_sim_parameters = { + .erase_value = FLASH_SIMULATOR_ERASE_VALUE +}; + static int flash_range_is_valid(struct device *dev, off_t offset, size_t len) { ARG_UNUSED(dev); @@ -219,7 +225,7 @@ static int flash_sim_write(struct device *dev, const off_t offset, uint8_t buf[FLASH_SIMULATOR_PROG_UNIT]; - memset(buf, 0xFF, sizeof(buf)); + memset(buf, FLASH_SIMULATOR_ERASE_VALUE, sizeof(buf)); if (memcmp(buf, FLASH(offset + i), sizeof(buf))) { STATS_INC(flash_sim_stats, double_writes); #if !CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES @@ -273,9 +279,9 @@ static void unit_erase(const uint32_t unit) (unit * FLASH_SIMULATOR_ERASE_UNIT); /* byte pattern to fill the flash with */ - uint8_t byte_pattern = 0xFF; + uint8_t byte_pattern = FLASH_SIMULATOR_ERASE_VALUE; - /* erase the memory unit by pulling all bits to one */ + /* erase the memory unit by setting it to erase value */ memset(FLASH(unit_addr), byte_pattern, FLASH_SIMULATOR_ERASE_UNIT); } @@ -343,12 +349,21 @@ static void flash_sim_page_layout(struct device *dev, } #endif +static const struct flash_parameters * +flash_sim_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_sim_parameters; +} + static const struct flash_driver_api flash_sim_api = { .read = flash_sim_read, .write = flash_sim_write, .erase = flash_sim_erase, .write_protection = flash_wp_set, .write_block_size = FLASH_SIMULATOR_PROG_UNIT, + .get_parameters = flash_sim_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sim_page_layout, #endif @@ -409,7 +424,7 @@ static int flash_mock_init(struct device *dev) static int flash_mock_init(struct device *dev) { - memset(mock_flash, 0xFF, ARRAY_SIZE(mock_flash)); + memset(mock_flash, FLASH_SIMULATOR_ERASE_VALUE, ARRAY_SIZE(mock_flash)); return 0; } diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index 483ce52fe6550..50b066326d6e6 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -57,6 +57,11 @@ LOG_MODULE_REGISTER(flash_stm32, CONFIG_FLASH_LOG_LEVEL); #define CFG_HW_FLASH_SEMID 2 +static const struct flash_parameters flash_stm32_parameters = { + /* WARNING: This value may be not valid for L0/L1 chips */ + .erase_value = 0xff, +}; + #if defined(CONFIG_MULTITHREADING) /* * This is named flash_stm32_sem_take instead of flash_stm32_lock (and @@ -281,6 +286,14 @@ static int flash_stm32_write_protection(struct device *dev, bool enable) return rc; } +static const struct flash_parameters * +flash_stm32_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_stm32_parameters; +} + static struct flash_stm32_priv flash_data = { .regs = (FLASH_TypeDef *) DT_INST_REG_ADDR(0), #if defined(CONFIG_SOC_SERIES_STM32L4X) || \ @@ -299,6 +312,7 @@ static const struct flash_driver_api flash_stm32_api = { .erase = flash_stm32_erase, .write = flash_stm32_write, .read = flash_stm32_read, + .get_parameters = flash_stm32_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_stm32_page_layout, #endif diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index dc85538edd7f1..88a8cc6e81cea 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -33,6 +33,10 @@ LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL); +static const struct flash_parameters qspi_flash_parameters = { + .erase_value = 0xff, +}; + /** * @brief QSPI buffer structure * Structure used both for TX and RX purposes. @@ -757,6 +761,14 @@ static const struct flash_pages_layout dev_layout = { }; #undef LAYOUT_PAGES_COUNT +static const struct flash_parameters * +qspi_flash_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &qspi_flash_parameters; +} + static void qspi_nor_pages_layout(struct device *dev, const struct flash_pages_layout **layout, size_t *layout_size) @@ -771,6 +783,7 @@ static const struct flash_driver_api qspi_nor_api = { .write = qspi_nor_write, .erase = qspi_nor_erase, .write_protection = qspi_nor_write_protection_set, + .get_parameters = qspi_flash_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = qspi_nor_pages_layout, #endif diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 369b122751abf..30dfff5f68030 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -43,6 +43,10 @@ struct flash_priv { uint32_t pflash_block_base; }; +static const struct flash_parameters flash_mcux_parameters = { + .erase_value = 0xff, +}; + /* * Interrupt vectors could be executed from flash hence the need for locking. * The underlying MCUX driver takes care of copying the functions to SRAM. @@ -137,14 +141,22 @@ static const struct flash_pages_layout dev_layout = { }; static void flash_mcux_pages_layout(struct device *dev, - const struct flash_pages_layout **layout, - size_t *layout_size) + const struct flash_pages_layout **layout, + size_t *layout_size) { *layout = &dev_layout; *layout_size = 1; } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_mcux_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_mcux_parameters; +} + static struct flash_priv flash_data; static const struct flash_driver_api flash_mcux_api = { @@ -152,6 +164,7 @@ static const struct flash_driver_api flash_mcux_api = { .erase = flash_mcux_erase, .write = flash_mcux_write, .read = flash_mcux_read, + .get_parameters = flash_mcux_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_mcux_pages_layout, #endif diff --git a/drivers/flash/soc_flash_nios2_qspi.c b/drivers/flash/soc_flash_nios2_qspi.c index c44222e62bacf..8beb36ea0ebf1 100644 --- a/drivers/flash/soc_flash_nios2_qspi.c +++ b/drivers/flash/soc_flash_nios2_qspi.c @@ -61,6 +61,10 @@ struct flash_nios2_qspi_config { struct k_sem sem_lock; }; +static const struct flash_parameters flash_nios2_qspi_parameters = { + .erase_value = 0xff, +}; + static int flash_nios2_qspi_erase(struct device *dev, off_t offset, size_t len) { struct flash_nios2_qspi_config *flash_cfg = dev->driver_data; @@ -449,11 +453,20 @@ static int flash_nios2_qspi_write_protection(struct device *dev, bool enable) return rc; } +static const struct flash_parameters * +flash_nios2_qspi_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_nios2_qspi_parameters; +} + static const struct flash_driver_api flash_nios2_qspi_api = { .write_protection = flash_nios2_qspi_write_protection, .erase = flash_nios2_qspi_erase, .write = flash_nios2_qspi_write, .read = flash_nios2_qspi_read, + .get_parameters = flash_nios2_qspi_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = (flash_api_pages_layout) flash_page_layout_not_implemented, diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index 2cedcd0c40f38..857865ea617a5 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -105,6 +105,10 @@ static int erase_op(void *context); /* instance of flash_op_handler_t */ static int erase_in_timeslice(uint32_t addr, uint32_t size); #endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */ +static const struct flash_parameters flash_nrf_parameters = { + .erase_value = 0xff, +}; + #if defined(CONFIG_MULTITHREADING) /* semaphore for locking flash resources (tickers) */ static struct k_sem sem_lock; @@ -278,11 +282,20 @@ static void flash_nrf_pages_layout(struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_nrf_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_nrf_parameters; +} + static const struct flash_driver_api flash_nrf_api = { .read = flash_nrf_read, .write = flash_nrf_write, .erase = flash_nrf_erase, .write_protection = flash_nrf_write_protection, + .get_parameters = flash_nrf_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_nrf_pages_layout, #endif diff --git a/drivers/flash/soc_flash_rv32m1.c b/drivers/flash/soc_flash_rv32m1.c index cad81bc4f6afa..56b1617bc4315 100644 --- a/drivers/flash/soc_flash_rv32m1.c +++ b/drivers/flash/soc_flash_rv32m1.c @@ -28,6 +28,10 @@ struct flash_priv { uint32_t pflash_block_base; }; +static const struct flash_parameters flash_mcux_parameters = { + .erase_value = 0xff, +}; + /* * Interrupt vectors could be executed from flash hence the need for locking. * The underlying MCUX driver takes care of copying the functions to SRAM. @@ -131,6 +135,14 @@ static void flash_mcux_pages_layout( } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_mcux_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_mcux_parameters; +} + static struct flash_priv flash_data; static const struct flash_driver_api flash_mcux_api = { @@ -138,6 +150,7 @@ static const struct flash_driver_api flash_mcux_api = { .erase = flash_mcux_erase, .write = flash_mcux_write, .read = flash_mcux_read, + .get_parameters = flash_mcux_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_mcux_pages_layout, #endif diff --git a/drivers/flash/spi_flash_at45.c b/drivers/flash/spi_flash_at45.c index cbac368934868..4e7d644b8d0db 100644 --- a/drivers/flash/spi_flash_at45.c +++ b/drivers/flash/spi_flash_at45.c @@ -76,6 +76,10 @@ struct spi_flash_at45_config { uint8_t jedec_id[3]; }; +static const struct flash_parameters flash_at45_parameters = { + .erase_value = 0xff, +}; + static struct spi_flash_at45_data *get_dev_data(struct device *dev) { return dev->driver_data; @@ -624,11 +628,20 @@ static int spi_flash_at45_pm_control(struct device *dev, uint32_t ctrl_command, } #endif /* IS_ENABLED(CONFIG_DEVICE_POWER_MANAGEMENT) */ +static const struct flash_parameters * +flash_at45_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_at45_parameters; +} + static const struct flash_driver_api spi_flash_at45_api = { .read = spi_flash_at45_read, .write = spi_flash_at45_write, .erase = spi_flash_at45_erase, .write_protection = spi_flash_at45_write_protection, + .get_parameters = flash_at45_get_parameters, #if IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = spi_flash_at45_pages_layout, #endif diff --git a/drivers/flash/spi_flash_w25qxxdv.c b/drivers/flash/spi_flash_w25qxxdv.c index 8e6c228e1c74f..8bdd6f40b3bd2 100644 --- a/drivers/flash/spi_flash_w25qxxdv.c +++ b/drivers/flash/spi_flash_w25qxxdv.c @@ -27,6 +27,10 @@ #define SYNC_UNLOCK() #endif +static const struct flash_parameters flash_wb_parameters = { + .erase_value = 0xff, +}; + static int spi_flash_wb_access(struct spi_flash_data *ctx, uint8_t cmd, bool addressed, off_t offset, void *data, size_t length, bool write) @@ -388,11 +392,20 @@ static void flash_wb_pages_layout(struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_wb_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_wb_parameters; +} + static const struct flash_driver_api spi_flash_api = { .read = spi_flash_wb_read, .write = spi_flash_wb_write, .erase = spi_flash_wb_erase, .write_protection = spi_flash_wb_write_protection_set, + .get_parameters = flash_wb_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_wb_pages_layout, #endif diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index 75e4e8f649036..b92f6672c8f55 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -84,6 +84,10 @@ struct spi_nor_data { struct k_sem sem; }; +static const struct flash_parameters flash_nor_parameters = { + .erase_value = 0xff, +}; + /* Capture the time at which the device entered deep power-down. */ static inline void record_entered_dpd(const struct device *const dev) { @@ -568,11 +572,20 @@ static void spi_nor_pages_layout(struct device *dev, } #endif /* CONFIG_FLASH_PAGE_LAYOUT */ +static const struct flash_parameters * +flash_nor_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_nor_parameters; +} + static const struct flash_driver_api spi_nor_api = { .read = spi_nor_read, .write = spi_nor_write, .erase = spi_nor_erase, .write_protection = spi_nor_write_protection_set, + .get_parameters = flash_nor_get_parameters, #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = spi_nor_pages_layout, #endif diff --git a/dts/bindings/flash_controller/zephyr,sim-flash.yaml b/dts/bindings/flash_controller/zephyr,sim-flash.yaml index e0a292c30e2f8..8050254339a70 100644 --- a/dts/bindings/flash_controller/zephyr,sim-flash.yaml +++ b/dts/bindings/flash_controller/zephyr,sim-flash.yaml @@ -9,3 +9,9 @@ include: base.yaml properties: label: required: true + +properties: + erase-value: + type: int + description: Value of erased flash cell + required: false diff --git a/tests/drivers/flash_simulator/src/main.c b/tests/drivers/flash_simulator/src/main.c index c8ac362c5a3ba..c3cb8b893d1a9 100644 --- a/tests/drivers/flash_simulator/src/main.c +++ b/tests/drivers/flash_simulator/src/main.c @@ -19,6 +19,9 @@ #define FLASH_SIMULATOR_PROG_UNIT DT_PROP(SOC_NV_FLASH_NODE, write_block_size) #define FLASH_SIMULATOR_FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) +#define FLASH_SIMULATOR_ERASE_VALUE \ + DT_PROP(DT_PARENT(SOC_NV_FLASH_NODE), erase_value) + /* Offset between pages */ #define TEST_SIM_FLASH_SIZE FLASH_SIMULATOR_FLASH_SIZE @@ -266,6 +269,15 @@ static void test_double_write(void) zassert_equal(-EIO, rc, "Unexpected error code (%d)", rc); } +static void test_get_erase_value(void) +{ + const struct flash_parameters *fp = flash_get_parameters(flash_dev); + + zassert_equal(fp->erase_value, FLASH_SIMULATOR_ERASE_VALUE, + "Expected erase value %x", + FLASH_SIMULATOR_ERASE_VALUE); +} + void test_main(void) { ztest_test_suite(flash_sim_api, @@ -275,7 +287,8 @@ void test_main(void) ztest_unit_test(test_access), ztest_unit_test(test_out_of_bounds), ztest_unit_test(test_align), - ztest_unit_test(test_double_write)); + ztest_unit_test(test_double_write), + ztest_unit_test(test_get_erase_value)); ztest_run_test_suite(flash_sim_api); } From c2736211aceb217780f725e45af4fca11dd481c1 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:33:09 +0000 Subject: [PATCH 3/5] subsys/fs/nvs: Use flash_get_parameters() to get erase value Use new flash API call to obtain erase value instead of relaying on hardcoded literals. Signed-off-by: Dominik Ermel --- include/fs/nvs.h | 1 + subsys/fs/nvs/nvs.c | 40 ++++++++++++------- .../fs/nvs/boards/qemu_x86_ev_0x00.overlay | 9 +++++ tests/subsys/fs/nvs/testcase.yaml | 3 ++ 4 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay diff --git a/include/fs/nvs.h b/include/fs/nvs.h index ae200ea82b32c..d58798b147e6b 100644 --- a/include/fs/nvs.h +++ b/include/fs/nvs.h @@ -57,6 +57,7 @@ struct nvs_fs { struct k_mutex nvs_lock; struct device *flash_device; + const struct flash_parameters *flash_parameters; }; /** diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 6cef3e42a0947..dd85b08271570 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -66,7 +66,9 @@ static int nvs_flash_al_wrt(struct nvs_fs *fs, uint32_t addr, const void *data, } if (len) { memcpy(buf, data8, len); - (void)memset(buf + len, 0xff, fs->write_block_size - len); + (void)memset(buf + len, fs->flash_parameters->erase_value, + fs->write_block_size - len); + rc = flash_write(fs->flash_device, offset, buf, fs->write_block_size); if (rc) { @@ -221,7 +223,8 @@ static int nvs_flash_erase_sector(struct nvs_fs *fs, uint32_t addr) off_t offset; addr &= ADDR_SECT_MASK; - rc = nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size); + rc = nvs_flash_cmp_const(fs, addr, fs->flash_parameters->erase_value, + fs->sector_size); if (rc <= 0) { /* flash error or empty sector */ return rc; @@ -351,7 +354,7 @@ static int nvs_prev_ate(struct nvs_fs *fs, uint32_t *addr, struct nvs_ate *ate) return rc; } - rc = nvs_ate_cmp_const(&close_ate, 0xff); + rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); /* at the end of filesystem */ if (!rc) { *addr = fs->ate_wra; @@ -460,7 +463,7 @@ static int nvs_gc(struct nvs_fs *fs) return rc; } - rc = nvs_ate_cmp_const(&close_ate, 0xff); + rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); if (!rc) { rc = nvs_flash_erase_sector(fs, sec_addr); if (rc) { @@ -545,6 +548,7 @@ static int nvs_startup(struct nvs_fs *fs) */ uint32_t addr = 0U; uint16_t i, closed_sectors = 0; + uint8_t erase_value = fs->flash_parameters->erase_value; k_mutex_lock(&fs->nvs_lock, K_FOREVER); @@ -555,14 +559,14 @@ static int nvs_startup(struct nvs_fs *fs) for (i = 0; i < fs->sector_count; i++) { addr = (i << ADDR_SECT_SHIFT) + (uint16_t)(fs->sector_size - ate_size); - rc = nvs_flash_cmp_const(fs, addr, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, erase_value, + sizeof(struct nvs_ate)); if (rc) { /* closed sector */ closed_sectors++; nvs_sector_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, erase_value, + sizeof(struct nvs_ate)); if (!rc) { /* open sector */ break; @@ -581,8 +585,8 @@ static int nvs_startup(struct nvs_fs *fs) * two sectors. Then we can only set it to the first sector if * the last sector contains no ate's. So we check this first */ - rc = nvs_flash_cmp_const(fs, addr - ate_size, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr - ate_size, erase_value, + sizeof(struct nvs_ate)); if (!rc) { /* empty ate */ nvs_sector_advance(fs, &addr); @@ -590,7 +594,7 @@ static int nvs_startup(struct nvs_fs *fs) } /* addr contains address of the last ate in the most recent sector - * search for the first ate containing all 0xff + * search for the first ate containing all cells erased. */ fs->ate_wra = addr - ate_size; fs->data_wra = addr & ADDR_SECT_MASK; @@ -601,7 +605,8 @@ static int nvs_startup(struct nvs_fs *fs) goto end; } - rc = nvs_ate_cmp_const(&last_ate, 0xff); + rc = nvs_ate_cmp_const(&last_ate, erase_value); + if (!rc) { /* found ff empty location */ break; @@ -630,7 +635,8 @@ static int nvs_startup(struct nvs_fs *fs) while (fs->ate_wra > fs->data_wra) { empty_len = fs->ate_wra - fs->data_wra; - rc = nvs_flash_cmp_const(fs, fs->data_wra, 0xff, empty_len); + rc = nvs_flash_cmp_const(fs, fs->data_wra, erase_value, + empty_len); if (rc < 0) { goto end; } @@ -647,7 +653,7 @@ static int nvs_startup(struct nvs_fs *fs) */ addr = fs->ate_wra & ADDR_SECT_MASK; nvs_sector_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size); + rc = nvs_flash_cmp_const(fs, addr, erase_value, fs->sector_size); if (rc < 0) { goto end; } @@ -706,6 +712,12 @@ int nvs_init(struct nvs_fs *fs, const char *dev_name) return -ENXIO; } + fs->flash_parameters = flash_get_parameters(fs->flash_device); + if (fs->flash_parameters == NULL) { + LOG_ERR("Could not obtain flash parameters"); + return -EINVAL; + } + write_block_size = flash_get_write_block_size(fs->flash_device); /* check that the write block size is supported */ diff --git a/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay b/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay new file mode 100644 index 0000000000000..0f122e3400752 --- /dev/null +++ b/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sim_flash { + erase-value = < 0x00 >; +}; diff --git a/tests/subsys/fs/nvs/testcase.yaml b/tests/subsys/fs/nvs/testcase.yaml index f9e94b4b4fca5..91aa32b3a2233 100644 --- a/tests/subsys/fs/nvs/testcase.yaml +++ b/tests/subsys/fs/nvs/testcase.yaml @@ -1,3 +1,6 @@ tests: filesystem.nvs: platform_whitelist: qemu_x86 + filesystem.nvs_0x00: + extra_args: DTC_OVERLAY_FILE=boards/qemu_x86_ev_0x00.overlay + platform_whitelist: qemu_x86 From 763a9ec7c88f961734be53cc3ffa5be0131ce058 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:33:09 +0000 Subject: [PATCH 4/5] drivers/flash: Move write_block_size into flash_parameters With addition of flash_parameters structure, and supporting API call to retrieve it, it is no longer needed to store write_block_size as a part of flash_driver_api and it should be part of flash_parameters. Signed-off-by: Dominik Ermel --- drivers/flash/flash_gecko.c | 2 +- drivers/flash/flash_sam.c | 2 +- drivers/flash/flash_sam0.c | 10 +++++----- drivers/flash/flash_simulator.c | 2 +- drivers/flash/flash_stm32.c | 16 ++++++++-------- drivers/flash/nrf_qspi_nor.c | 2 +- drivers/flash/soc_flash_mcux.c | 10 +++++----- drivers/flash/soc_flash_nios2_qspi.c | 2 +- drivers/flash/soc_flash_nrf.c | 10 +++++----- drivers/flash/soc_flash_rv32m1.c | 2 +- drivers/flash/spi_flash_at45.c | 2 +- drivers/flash/spi_flash_w25qxxdv.c | 2 +- drivers/flash/spi_nor.c | 2 +- include/drivers/flash.h | 4 ++-- subsys/storage/stream/stream_flash.c | 2 +- 15 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/flash/flash_gecko.c b/drivers/flash/flash_gecko.c index 57abd4ea610f4..0696ad1719ac1 100644 --- a/drivers/flash/flash_gecko.c +++ b/drivers/flash/flash_gecko.c @@ -26,6 +26,7 @@ struct flash_gecko_data { static const struct flash_parameters flash_gecko_parameters = { + .write_block_size = DT_PROP(SOC_NV_FLASH_NODE, write_block_size), .erase_value = 0xff, }; @@ -216,7 +217,6 @@ static const struct flash_driver_api flash_gecko_driver_api = { #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_gecko_page_layout, #endif - .write_block_size = DT_PROP(SOC_NV_FLASH_NODE, write_block_size), }; static struct flash_gecko_data flash_gecko_0_data; diff --git a/drivers/flash/flash_sam.c b/drivers/flash/flash_sam.c index 0e88216f85936..9bedaf28aee99 100644 --- a/drivers/flash/flash_sam.c +++ b/drivers/flash/flash_sam.c @@ -47,6 +47,7 @@ struct flash_sam_dev_data { }; static const struct flash_parameters flash_sam_parameters = { + .write_block_size = FLASH_WRITE_BLK_SZ, .erase_value = 0xff, }; @@ -360,7 +361,6 @@ static const struct flash_driver_api flash_sam_api = { #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sam_page_layout, #endif - .write_block_size = FLASH_WRITE_BLK_SZ, }; static const struct flash_sam_dev_cfg flash_sam_cfg = { diff --git a/drivers/flash/flash_sam0.c b/drivers/flash/flash_sam0.c index 24289bcf5f35f..407def5efb167 100644 --- a/drivers/flash/flash_sam0.c +++ b/drivers/flash/flash_sam0.c @@ -62,6 +62,11 @@ static const struct flash_pages_layout flash_sam0_pages_layout = { #endif static const struct flash_parameters flash_sam0_parameters = { +#if CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES + .write_block_size = 1, +#else + .write_block_size = FLASH_PAGE_SIZE, +#endif .erase_value = 0xff, }; @@ -430,11 +435,6 @@ static const struct flash_driver_api flash_sam0_api = { #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sam0_page_layout, #endif -#if CONFIG_SOC_FLASH_SAM0_EMULATE_BYTE_PAGES - .write_block_size = 1, -#else - .write_block_size = FLASH_PAGE_SIZE, -#endif }; static struct flash_sam0_data flash_sam0_data_0; diff --git a/drivers/flash/flash_simulator.c b/drivers/flash/flash_simulator.c index 511db4661db23..5d07df201147d 100644 --- a/drivers/flash/flash_simulator.c +++ b/drivers/flash/flash_simulator.c @@ -142,6 +142,7 @@ static bool write_protection; static const struct flash_driver_api flash_sim_api; static const struct flash_parameters flash_sim_parameters = { + .write_block_size = FLASH_SIMULATOR_PROG_UNIT, .erase_value = FLASH_SIMULATOR_ERASE_VALUE }; @@ -362,7 +363,6 @@ static const struct flash_driver_api flash_sim_api = { .write = flash_sim_write, .erase = flash_sim_erase, .write_protection = flash_wp_set, - .write_block_size = FLASH_SIMULATOR_PROG_UNIT, .get_parameters = flash_sim_get_parameters, #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_sim_page_layout, diff --git a/drivers/flash/flash_stm32.c b/drivers/flash/flash_stm32.c index 50b066326d6e6..4e15e40c39941 100644 --- a/drivers/flash/flash_stm32.c +++ b/drivers/flash/flash_stm32.c @@ -58,6 +58,13 @@ LOG_MODULE_REGISTER(flash_stm32, CONFIG_FLASH_LOG_LEVEL); #define CFG_HW_FLASH_SEMID 2 static const struct flash_parameters flash_stm32_parameters = { +#if DT_PROP(DT_INST(0, soc_nv_flash), write_block_size) + .write_block_size = DT_PROP(DT_INST(0, soc_nv_flash), write_block_size), +#else +#error Flash write block size not available + /* Flash Write block size is extracted from device tree */ + /* as flash node property 'write-block-size' */ +#endif /* WARNING: This value may be not valid for L0/L1 chips */ .erase_value = 0xff, }; @@ -316,13 +323,6 @@ static const struct flash_driver_api flash_stm32_api = { #ifdef CONFIG_FLASH_PAGE_LAYOUT .page_layout = flash_stm32_page_layout, #endif -#if DT_PROP(DT_INST(0, soc_nv_flash), write_block_size) - .write_block_size = DT_PROP(DT_INST(0, soc_nv_flash), write_block_size), -#else -#error Flash write block size not available - /* Flash Write block size is extracted from device tree */ - /* as flash node property 'write-block-size' */ -#endif }; static int stm32_flash_init(struct device *dev) @@ -362,7 +362,7 @@ static int stm32_flash_init(struct device *dev) flash_stm32_sem_init(dev); LOG_DBG("Flash initialized. BS: %zu", - flash_stm32_api.write_block_size); + flash_stm32_parameters.write_block_size); #if ((CONFIG_FLASH_LOG_LEVEL >= LOG_LEVEL_DBG) && CONFIG_FLASH_PAGE_LAYOUT) const struct flash_pages_layout *layout; diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 88a8cc6e81cea..6a86dbaaa9f11 100644 --- a/drivers/flash/nrf_qspi_nor.c +++ b/drivers/flash/nrf_qspi_nor.c @@ -34,6 +34,7 @@ LOG_MODULE_REGISTER(qspi_nor, CONFIG_FLASH_LOG_LEVEL); static const struct flash_parameters qspi_flash_parameters = { + .write_block_size = 1, .erase_value = 0xff, }; @@ -787,7 +788,6 @@ static const struct flash_driver_api qspi_nor_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = qspi_nor_pages_layout, #endif - .write_block_size = 1, }; diff --git a/drivers/flash/soc_flash_mcux.c b/drivers/flash/soc_flash_mcux.c index 30dfff5f68030..1897c6db98abe 100644 --- a/drivers/flash/soc_flash_mcux.c +++ b/drivers/flash/soc_flash_mcux.c @@ -44,6 +44,11 @@ struct flash_priv { }; static const struct flash_parameters flash_mcux_parameters = { +#if DT_NODE_HAS_PROP(SOC_NV_FLASH_NODE, write_block_size) + .write_block_size = DT_PROP(SOC_NV_FLASH_NODE, write_block_size), +#else + .write_block_size = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE, +#endif .erase_value = 0xff, }; @@ -168,11 +173,6 @@ static const struct flash_driver_api flash_mcux_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_mcux_pages_layout, #endif -#if DT_NODE_HAS_PROP(SOC_NV_FLASH_NODE, write_block_size) - .write_block_size = DT_PROP(SOC_NV_FLASH_NODE, write_block_size), -#else - .write_block_size = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE, -#endif }; static int flash_mcux_init(struct device *dev) diff --git a/drivers/flash/soc_flash_nios2_qspi.c b/drivers/flash/soc_flash_nios2_qspi.c index 8beb36ea0ebf1..51b7bf8799239 100644 --- a/drivers/flash/soc_flash_nios2_qspi.c +++ b/drivers/flash/soc_flash_nios2_qspi.c @@ -62,6 +62,7 @@ struct flash_nios2_qspi_config { }; static const struct flash_parameters flash_nios2_qspi_parameters = { + .write_block_size = NIOS2_WRITE_BLOCK_SIZE, .erase_value = 0xff, }; @@ -471,7 +472,6 @@ static const struct flash_driver_api flash_nios2_qspi_api = { .page_layout = (flash_api_pages_layout) flash_page_layout_not_implemented, #endif - .write_block_size = NIOS2_WRITE_BLOCK_SIZE, }; static int flash_nios2_qspi_init(struct device *dev) diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index 857865ea617a5..770673b712164 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -106,6 +106,11 @@ static int erase_in_timeslice(uint32_t addr, uint32_t size); #endif /* CONFIG_SOC_FLASH_NRF_RADIO_SYNC */ static const struct flash_parameters flash_nrf_parameters = { +#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS) + .write_block_size = 1, +#else + .write_block_size = 4, +#endif .erase_value = 0xff, }; @@ -299,11 +304,6 @@ static const struct flash_driver_api flash_nrf_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_nrf_pages_layout, #endif -#if IS_ENABLED(CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS) - .write_block_size = 1, -#else - .write_block_size = 4, -#endif }; static int nrf_flash_init(struct device *dev) diff --git a/drivers/flash/soc_flash_rv32m1.c b/drivers/flash/soc_flash_rv32m1.c index 56b1617bc4315..5c7defccc837b 100644 --- a/drivers/flash/soc_flash_rv32m1.c +++ b/drivers/flash/soc_flash_rv32m1.c @@ -29,6 +29,7 @@ struct flash_priv { }; static const struct flash_parameters flash_mcux_parameters = { + .write_block_size = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE, .erase_value = 0xff, }; @@ -154,7 +155,6 @@ static const struct flash_driver_api flash_mcux_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_mcux_pages_layout, #endif - .write_block_size = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE, }; static int flash_mcux_init(struct device *dev) diff --git a/drivers/flash/spi_flash_at45.c b/drivers/flash/spi_flash_at45.c index 4e7d644b8d0db..1f29f7c2f731e 100644 --- a/drivers/flash/spi_flash_at45.c +++ b/drivers/flash/spi_flash_at45.c @@ -77,6 +77,7 @@ struct spi_flash_at45_config { }; static const struct flash_parameters flash_at45_parameters = { + .write_block_size = 1, .erase_value = 0xff, }; @@ -645,7 +646,6 @@ static const struct flash_driver_api spi_flash_at45_api = { #if IS_ENABLED(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = spi_flash_at45_pages_layout, #endif - .write_block_size = 1, }; #define DT_DRV_COMPAT atmel_at45 diff --git a/drivers/flash/spi_flash_w25qxxdv.c b/drivers/flash/spi_flash_w25qxxdv.c index 8bdd6f40b3bd2..21187520545da 100644 --- a/drivers/flash/spi_flash_w25qxxdv.c +++ b/drivers/flash/spi_flash_w25qxxdv.c @@ -28,6 +28,7 @@ #endif static const struct flash_parameters flash_wb_parameters = { + .write_block_size = 1, .erase_value = 0xff, }; @@ -409,7 +410,6 @@ static const struct flash_driver_api spi_flash_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = flash_wb_pages_layout, #endif - .write_block_size = 1, }; static int spi_flash_wb_configure(struct device *dev) diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index b92f6672c8f55..fe888701bca3e 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -85,6 +85,7 @@ struct spi_nor_data { }; static const struct flash_parameters flash_nor_parameters = { + .write_block_size = 1, .erase_value = 0xff, }; @@ -589,7 +590,6 @@ static const struct flash_driver_api spi_nor_api = { #if defined(CONFIG_FLASH_PAGE_LAYOUT) .page_layout = spi_nor_pages_layout, #endif - .write_block_size = 1, }; static const struct spi_nor_config flash_id = { diff --git a/include/drivers/flash.h b/include/drivers/flash.h index 62e68302b96cd..1a197e1d82269 100644 --- a/include/drivers/flash.h +++ b/include/drivers/flash.h @@ -42,6 +42,7 @@ struct flash_pages_layout { * through a runtime. */ struct flash_parameters { + const size_t write_block_size; uint8_t erase_value; /* Byte value of erased flash */ }; @@ -89,7 +90,6 @@ __subsystem struct flash_driver_api { #if defined(CONFIG_FLASH_PAGE_LAYOUT) flash_api_pages_layout page_layout; #endif /* CONFIG_FLASH_PAGE_LAYOUT */ - const size_t write_block_size; }; /** @@ -304,7 +304,7 @@ static inline size_t z_impl_flash_get_write_block_size(struct device *dev) const struct flash_driver_api *api = (const struct flash_driver_api *)dev->driver_api; - return api->write_block_size; + return api->get_parameters(dev)->write_block_size; } diff --git a/subsys/storage/stream/stream_flash.c b/subsys/storage/stream/stream_flash.c index 4830753635263..0e7bd2ea77647 100644 --- a/subsys/storage/stream/stream_flash.c +++ b/subsys/storage/stream/stream_flash.c @@ -215,7 +215,7 @@ int stream_flash_init(struct stream_flash_ctx *ctx, struct device *fdev, } if ((offset + size) > total_size || - offset % api->write_block_size) { + offset % flash_get_write_block_size(fdev)) { LOG_ERR("Incorrect parameter"); return -EFAULT; } From a946de65205eae0825681221149e37def571e6b4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 16 Jun 2020 09:54:38 +0000 Subject: [PATCH 5/5] subsys/fs/nvs: Move write_block_size to flash_parameters Pointer to flash_parameters have been added to nvs_fs structure and it is no longer needed to store write_block_size within the nvs_fs. Signed-off-by: Dominik Ermel --- include/fs/nvs.h | 1 - subsys/fs/nvs/nvs.c | 27 ++++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/include/fs/nvs.h b/include/fs/nvs.h index d58798b147e6b..15087b0cf9c8a 100644 --- a/include/fs/nvs.h +++ b/include/fs/nvs.h @@ -52,7 +52,6 @@ struct nvs_fs { * sector size should be multiple of pagesize */ uint16_t sector_count; /* amount of sectors in the filesystem */ - uint8_t write_block_size; /* write block size for alignment */ bool ready; /* is the filesystem initialized ? */ struct k_mutex nvs_lock; diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index dd85b08271570..0b61eaa502a2f 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -16,15 +16,16 @@ #include LOG_MODULE_REGISTER(fs_nvs, CONFIG_NVS_LOG_LEVEL); - /* basic routines */ /* nvs_al_size returns size aligned to fs->write_block_size */ static inline size_t nvs_al_size(struct nvs_fs *fs, size_t len) { - if (fs->write_block_size <= 1U) { + uint8_t write_block_size = fs->flash_parameters->write_block_size; + + if (write_block_size <= 1U) { return len; } - return (len + (fs->write_block_size - 1U)) & ~(fs->write_block_size - 1U); + return (len + (write_block_size - 1U)) & ~(write_block_size - 1U); } /* end basic routines */ @@ -53,7 +54,7 @@ static int nvs_flash_al_wrt(struct nvs_fs *fs, uint32_t addr, const void *data, /* flash protection set error */ return rc; } - blen = len & ~(fs->write_block_size - 1U); + blen = len & ~(fs->flash_parameters->write_block_size - 1U); if (blen > 0) { rc = flash_write(fs->flash_device, offset, data8, blen); if (rc) { @@ -67,10 +68,10 @@ static int nvs_flash_al_wrt(struct nvs_fs *fs, uint32_t addr, const void *data, if (len) { memcpy(buf, data8, len); (void)memset(buf + len, fs->flash_parameters->erase_value, - fs->write_block_size - len); + fs->flash_parameters->write_block_size - len); rc = flash_write(fs->flash_device, offset, buf, - fs->write_block_size); + fs->flash_parameters->write_block_size); if (rc) { /* flash write error */ goto end; @@ -144,7 +145,9 @@ static int nvs_flash_block_cmp(struct nvs_fs *fs, uint32_t addr, const void *dat size_t bytes_to_cmp, block_size; uint8_t buf[NVS_BLOCK_SIZE]; - block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1U); + block_size = + NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); + while (len) { bytes_to_cmp = MIN(block_size, len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_cmp); @@ -173,7 +176,9 @@ static int nvs_flash_cmp_const(struct nvs_fs *fs, uint32_t addr, uint8_t value, size_t bytes_to_cmp, block_size; uint8_t cmp[NVS_BLOCK_SIZE]; - block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1U); + block_size = + NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); + (void)memset(cmp, value, block_size); while (len) { bytes_to_cmp = MIN(block_size, len); @@ -196,7 +201,8 @@ static int nvs_flash_block_move(struct nvs_fs *fs, uint32_t addr, size_t len) size_t bytes_to_copy, block_size; uint8_t buf[NVS_BLOCK_SIZE]; - block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1U); + block_size = + NVS_BLOCK_SIZE & ~(fs->flash_parameters->write_block_size - 1U); while (len) { bytes_to_copy = MIN(block_size, len); @@ -644,7 +650,7 @@ static int nvs_startup(struct nvs_fs *fs) break; } - fs->data_wra += fs->write_block_size; + fs->data_wra += fs->flash_parameters->write_block_size; } /* if the sector after the write sector is not empty gc was interrupted @@ -725,7 +731,6 @@ int nvs_init(struct nvs_fs *fs, const char *dev_name) LOG_ERR("Unsupported write block size"); return -EINVAL; } - fs->write_block_size = write_block_size; /* check that sector size is a multiple of pagesize */ rc = flash_get_page_info_by_offs(fs->flash_device, fs->offset, &info);