1717#include <zephyr/stats/stats.h>
1818#include <string.h>
1919
20+ #include <zephyr/drivers/flash/flash_simulator.h>
21+
2022#ifdef CONFIG_ARCH_POSIX
2123
2224#include "flash_simulator_native.h"
@@ -170,6 +172,23 @@ static const struct flash_parameters flash_sim_parameters = {
170172 },
171173};
172174
175+ #ifdef CONFIG_ARCH_POSIX
176+ static struct flash_simulator_params flash_sim_params = {
177+ #else
178+ static const struct flash_simulator_params flash_sim_params = {
179+ .memory = mock_flash ,
180+ #endif
181+ .memory_size = FLASH_SIMULATOR_FLASH_SIZE ,
182+ .base_offset = FLASH_SIMULATOR_BASE_OFFSET ,
183+ .erase_unit = FLASH_SIMULATOR_ERASE_UNIT ,
184+ .prog_unit = FLASH_SIMULATOR_PROG_UNIT ,
185+ .explicit_erase = IS_ENABLED (CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE ),
186+ .erase_value = FLASH_SIMULATOR_ERASE_VALUE ,
187+ };
188+
189+ static const struct flash_simulator_cb * flash_simulator_cbs ;
190+
191+
173192static int flash_range_is_valid (const struct device * dev , off_t offset ,
174193 size_t len )
175194{
@@ -264,6 +283,13 @@ static int flash_sim_write(const struct device *dev, const off_t offset,
264283 }
265284#endif
266285
286+ flash_simulator_write_byte_cb_t write_cb = NULL ;
287+ const struct flash_simulator_cb * cb = flash_simulator_cbs ;
288+
289+ if (cb != NULL ) {
290+ write_cb = cb -> write_byte ;
291+ }
292+
267293 for (uint32_t i = 0 ; i < len ; i ++ ) {
268294#ifdef CONFIG_FLASH_SIMULATOR_STATS
269295 if (data_part_ignored ) {
@@ -273,16 +299,26 @@ static int flash_sim_write(const struct device *dev, const off_t offset,
273299 }
274300#endif /* CONFIG_FLASH_SIMULATOR_STATS */
275301
276- /* only pull bits to zero */
302+ uint8_t data_val = * ((const uint8_t * )data + i );
303+
277304#if defined(CONFIG_FLASH_SIMULATOR_EXPLICIT_ERASE )
278305#if FLASH_SIMULATOR_ERASE_VALUE == 0xFF
279- * (MOCK_FLASH (offset + i )) &= * ((uint8_t * )data + i );
306+ /* only pull bits to zero */
307+ data_val &= * (MOCK_FLASH (offset + i ));
280308#else
281- * (MOCK_FLASH (offset + i )) |= * ((uint8_t * )data + i );
309+ /* only pull bits to one */
310+ data_val |= * (MOCK_FLASH (offset + i ));
282311#endif
283- #else
284- * (MOCK_FLASH (offset + i )) = * ((uint8_t * )data + i );
285312#endif
313+ if (write_cb != NULL ) {
314+ int ret = write_cb (dev , & flash_sim_params ,
315+ offset + i , data_val );
316+ if (ret < 0 ) {
317+ return ret ;
318+ }
319+ data_val = (uint8_t )ret ;
320+ }
321+ * (MOCK_FLASH (offset + i )) = data_val ;
286322 }
287323
288324 FLASH_SIM_STATS_INCN (flash_sim_stats , bytes_written , len );
@@ -297,20 +333,28 @@ static int flash_sim_write(const struct device *dev, const off_t offset,
297333 return 0 ;
298334}
299335
300- static void unit_erase (const uint32_t unit )
336+ static int unit_erase (const struct device * dev , const uint32_t unit )
301337{
302338 const off_t unit_addr = unit * FLASH_SIMULATOR_ERASE_UNIT ;
339+ flash_simulator_erase_unit_cb_t erase_cb = NULL ;
340+ const struct flash_simulator_cb * cb = flash_simulator_cbs ;
341+
342+ if (cb != NULL ) {
343+ erase_cb = cb -> erase_unit ;
344+ }
345+ if (erase_cb != NULL ) {
346+ return erase_cb (dev , & flash_sim_params , unit_addr );
347+ }
303348
304349 /* erase the memory unit by setting it to erase value */
305350 memset (MOCK_FLASH (unit_addr ), FLASH_SIMULATOR_ERASE_VALUE ,
306351 FLASH_SIMULATOR_ERASE_UNIT );
352+ return 0 ;
307353}
308354
309355static int flash_sim_erase (const struct device * dev , const off_t offset ,
310356 const size_t len )
311357{
312- ARG_UNUSED (dev );
313-
314358 if (!flash_range_is_valid (dev , offset , len )) {
315359 return - EINVAL ;
316360 }
@@ -335,8 +379,13 @@ static int flash_sim_erase(const struct device *dev, const off_t offset,
335379
336380 /* erase as many units as necessary and increase their erase counter */
337381 for (uint32_t i = 0 ; i < len / FLASH_SIMULATOR_ERASE_UNIT ; i ++ ) {
382+ int ret ;
383+
338384 ERASE_CYCLES_INC (unit_start + i );
339- unit_erase (unit_start + i );
385+ ret = unit_erase (dev , unit_start + i );
386+ if (ret < 0 ) {
387+ return ret ;
388+ }
340389 }
341390
342391#ifdef CONFIG_FLASH_SIMULATOR_SIMULATE_TIMING
@@ -405,6 +454,7 @@ static int flash_mock_init(const struct device *dev)
405454 rc = flash_mock_init_native (flash_in_ram , & mock_flash , FLASH_SIMULATOR_FLASH_SIZE ,
406455 & flash_fd , flash_file_path , FLASH_SIMULATOR_ERASE_VALUE ,
407456 flash_erase_at_start );
457+ flash_sim_params .memory = mock_flash ;
408458
409459 if (rc < 0 ) {
410460 return - EIO ;
@@ -498,6 +548,13 @@ void *z_impl_flash_simulator_get_memory(const struct device *dev,
498548 return mock_flash ;
499549}
500550
551+ void z_impl_flash_simulator_set_callbacks (const struct device * dev ,
552+ const struct flash_simulator_cb * cb )
553+ {
554+ ARG_UNUSED (dev );
555+ flash_simulator_cbs = cb ;
556+ }
557+
501558#ifdef CONFIG_USERSPACE
502559
503560#include <zephyr/internal/syscall_handler.h>
@@ -510,6 +567,14 @@ void *z_vrfy_flash_simulator_get_memory(const struct device *dev,
510567 return z_impl_flash_simulator_get_memory (dev , mock_size );
511568}
512569
570+ void z_vrfy_flash_simulator_set_callbacks (const struct device * dev ,
571+ const struct flash_simulator_cb * cb )
572+ {
573+ K_OOPS (K_SYSCALL_SPECIFIC_DRIVER (dev , K_OBJ_DRIVER_FLASH , & flash_sim_api ));
574+
575+ z_impl_flash_simulator_set_callbacks (dev , cb );
576+ }
577+
513578#include <zephyr/syscalls/flash_simulator_get_memory_mrsh.c>
514579
515580#endif /* CONFIG_USERSPACE */
0 commit comments