88#include <zephyr/drivers/flash.h>
99#include <zephyr/device.h>
1010
11+ /* Warning: The test has been written for testing boards with single
12+ * instance of Flash Simulator device only.
13+ */
14+
1115/* configuration derived from DT */
1216#ifdef CONFIG_ARCH_POSIX
1317#define SOC_NV_FLASH_NODE DT_CHILD(DT_INST(0, zephyr_sim_flash), flash_0)
@@ -75,6 +79,44 @@ static void test_check_pattern32(off_t start, uint32_t (*pattern_gen)(void),
7579 }
7680}
7781
82+ /* ret < 0 is errno; ret == 1 is bad value in flash */
83+ static int test_check_erase (const struct device * dev , off_t offset , size_t size )
84+ {
85+ uint8_t buf [FLASH_SIMULATOR_PROG_UNIT ];
86+ int rc ;
87+ int i = 0 ;
88+
89+ BUILD_ASSERT (sizeof (buf ) >= FLASH_SIMULATOR_PROG_UNIT );
90+
91+ i = 0 ;
92+ while (i < size ) {
93+ size_t chunk = MIN (size - i , sizeof (buf ));
94+ /* The memset is done to set buf to something else than
95+ * FLASH_SIMULATOR_ERASE_VALUE, as we are trying to chek
96+ * whether that is what is now in the memory.
97+ */
98+ memset (buf , ~FLASH_SIMULATOR_ERASE_VALUE , sizeof (buf ));
99+ rc = flash_read (flash_dev , offset + i ,
100+ buf , chunk );
101+ if (rc < 0 ) {
102+ TC_PRINT ("Unexpected flash_read fail @ %ld" ,
103+ (long )(offset + i ));
104+ return rc ;
105+ }
106+ do {
107+ if ((uint8_t )buf [i & (sizeof (buf ) - 1 )] !=
108+ (uint8_t )FLASH_SIMULATOR_ERASE_VALUE ) {
109+ TC_PRINT ("Flash not erased at %ld\n" ,
110+ (long )(offset + i ));
111+ return 1 ;
112+ }
113+ ++ i ;
114+ -- chunk ;
115+ } while (chunk );
116+ }
117+ return 0 ;
118+ }
119+
78120/* Get access to the device and erase it ready for testing*/
79121static void test_init (void )
80122{
@@ -259,6 +301,8 @@ ZTEST(flash_sim_api, test_align)
259301 zassert_equal (- EINVAL , rc , "Unexpected error code (%d)" , rc );
260302}
261303
304+ #if !IS_ENABLED (CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES ) && \
305+ !IS_ENABLED (CONFIG_FLASH_SIMULATOR_RAMLIKE )
262306ZTEST (flash_sim_api , test_double_write )
263307{
264308 int rc ;
@@ -282,6 +326,122 @@ ZTEST(flash_sim_api, test_double_write)
282326 & data , sizeof (data ));
283327 zassert_equal (- EIO , rc , "Unexpected error code (%d)" , rc );
284328}
329+ #endif
330+
331+ #if IS_ENABLED (CONFIG_FLASH_SIMULATOR_RAMLIKE )
332+ ZTEST (flash_sim_api , test_ramlike )
333+ {
334+ /* Within code below there is assumption that the src size is
335+ * equal or greater than the FLASH_SIMULATOR_PROG_UNIT
336+ * (write-block-size) of device.
337+ */
338+ const uint8_t src [] = "Hello world! This is test string" ;
339+ uint8_t buf [FLASH_SIMULATOR_PROG_UNIT ];
340+ /* Round up to next write-block-size */
341+ int max = (sizeof (src ) + FLASH_SIMULATOR_PROG_UNIT - 1 ) &
342+ ~(FLASH_SIMULATOR_PROG_UNIT - 1 );
343+ int rc ;
344+ int i = 0 ;
345+ int is = 0 ; /* The index within src */
346+
347+ BUILD_ASSERT (sizeof (src ) >= FLASH_SIMULATOR_PROG_UNIT );
348+
349+ /* Scrub memory with something constant */
350+ memset (buf , FLASH_SIMULATOR_ERASE_VALUE , sizeof (buf ));
351+ while (i < max ) {
352+ rc = flash_write (flash_dev , FLASH_SIMULATOR_BASE_OFFSET + i ,
353+ buf , sizeof (buf ));
354+ zassert_equal (0 , rc , "flash_write should succeed" );
355+ i += sizeof (buf );
356+ }
357+
358+ /* Check the scrubbing */
359+ zassert_equal (0 , test_check_erase (flash_dev , FLASH_SIMULATOR_BASE_OFFSET , max ),
360+ "Area not erased" );
361+
362+ /* Now write something new */
363+ i = 0 ;
364+ while (i < max ) {
365+ do {
366+ buf [i & (sizeof (buf ) - 1 )] = src [is ];
367+ ++ i ;
368+ ++ is ;
369+
370+ /* Continue writing from the beginning of the src */
371+ if (is >= sizeof (src )) {
372+ is = 0 ;
373+ }
374+ } while (i & (sizeof (buf ) - 1 ));
375+ rc = flash_write (flash_dev , FLASH_SIMULATOR_BASE_OFFSET + i - sizeof (buf ),
376+ buf , sizeof (buf ));
377+ zassert_equal (0 , rc , "flash_write should succeed" );
378+ }
379+
380+ /* Check the write */
381+ i = 0 ;
382+ is = 0 ;
383+ while (i < max ) {
384+ rc = flash_read (flash_dev , FLASH_SIMULATOR_BASE_OFFSET + i ,
385+ buf , sizeof (buf ));
386+ zassert_equal (0 , rc , "flash_read should succeed" );
387+ do {
388+ zassert_equal ((uint8_t )src [is ], (uint8_t )buf [i & (sizeof (buf ) - 1 )],
389+ "Expected src and buf to match at index %d\n" , i );
390+ ++ i ;
391+ ++ is ;
392+ /* Src has wrapped around */
393+ if (is >= sizeof (src )) {
394+ is = 0 ;
395+ }
396+ } while (i & (sizeof (buf ) - 1 ));
397+ zassert_equal (0 , rc , "Unexpected value read" );
398+ }
399+
400+ /* Because we are checking random access writes, we are now going to
401+ * write binary not of the same data we have just written. If this would be
402+ * program-erase type memory, where you can only change from erase value
403+ * to opposite, such write would render incorrect data in memory,
404+ * but this is random access device so we should get exactly what we write.
405+ */
406+ i = 0 ;
407+ is = 0 ;
408+ while (i < max ) {
409+ do {
410+ buf [i & (sizeof (buf ) - 1 )] = ~src [is ];
411+ ++ i ;
412+ ++ is ;
413+
414+ /* Continue writing from the beginning of the src */
415+ if (is >= sizeof (src )) {
416+ is = 0 ;
417+ }
418+ } while (i & (sizeof (buf ) - 1 ));
419+ rc = flash_write (flash_dev , FLASH_SIMULATOR_BASE_OFFSET + i - sizeof (buf ),
420+ buf , sizeof (buf ));
421+ zassert_equal (0 , rc , "flash_write should succeed" );
422+ }
423+
424+ /* Check the write */
425+ i = 0 ;
426+ is = 0 ;
427+ while (i < max ) {
428+ rc = flash_read (flash_dev , FLASH_SIMULATOR_BASE_OFFSET + i ,
429+ buf , sizeof (buf ));
430+ zassert_equal (0 , rc , "flash_read should succeed" );
431+ do {
432+ zassert_equal ((uint8_t )~src [is ], (uint8_t )buf [i & (sizeof (buf ) - 1 )],
433+ "Expected src and buf to match at index %d\n" , i );
434+ ++ i ;
435+ ++ is ;
436+ /* Src has wrapped around */
437+ if (is >= sizeof (src )) {
438+ is = 0 ;
439+ }
440+ } while (i & (sizeof (buf ) - 1 ));
441+ zassert_equal (0 , rc , "Unexpected value read" );
442+ }
443+ }
444+ #endif
285445
286446ZTEST (flash_sim_api , test_get_erase_value )
287447{
0 commit comments