@@ -34,6 +34,9 @@ pub enum NorFlashErrorKind {
34
34
/// The arguments are out of bounds.
35
35
OutOfBounds ,
36
36
37
+ /// The cell already was written or cannot be written properly with provided value
38
+ DirtyWrite ,
39
+
37
40
/// Error specific to the implementation.
38
41
Other ,
39
42
}
@@ -49,6 +52,7 @@ impl core::fmt::Display for NorFlashErrorKind {
49
52
match self {
50
53
Self :: NotAligned => write ! ( f, "Arguments are not properly aligned" ) ,
51
54
Self :: OutOfBounds => write ! ( f, "Arguments are out of bounds" ) ,
55
+ Self :: DirtyWrite => write ! ( f, "Dirty write operation" ) ,
52
56
Self :: Other => write ! ( f, "An implementation specific error occurred" ) ,
53
57
}
54
58
}
@@ -379,3 +383,132 @@ where
379
383
Ok ( ( ) )
380
384
}
381
385
}
386
+
387
+ /// Simple RAM-backed flash storage implementation for tests
388
+ #[ derive( Clone , Copy , Debug ) ]
389
+ pub struct MockFlash <
390
+ const CAPACITY : usize ,
391
+ const READ_SIZE : usize = 1 ,
392
+ const WRITE_SIZE : usize = 1 ,
393
+ const ERASE_SIZE : usize = { 1 << 10 } ,
394
+ const ERASE_BYTE : u8 = 0xff ,
395
+ const MULTI_WRITE : bool = false,
396
+ > {
397
+ data : [ u8 ; CAPACITY ] ,
398
+ }
399
+
400
+ impl <
401
+ const CAPACITY : usize ,
402
+ const READ_SIZE : usize ,
403
+ const WRITE_SIZE : usize ,
404
+ const ERASE_SIZE : usize ,
405
+ const ERASE_BYTE : u8 ,
406
+ const MULTI_WRITE : bool ,
407
+ > Default for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
408
+ {
409
+ fn default ( ) -> Self {
410
+ Self {
411
+ data : [ ERASE_BYTE ; CAPACITY ] ,
412
+ }
413
+ }
414
+ }
415
+
416
+ impl <
417
+ const CAPACITY : usize ,
418
+ const READ_SIZE : usize ,
419
+ const WRITE_SIZE : usize ,
420
+ const ERASE_SIZE : usize ,
421
+ const ERASE_BYTE : u8 ,
422
+ const MULTI_WRITE : bool ,
423
+ > core:: ops:: Deref
424
+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
425
+ {
426
+ type Target = [ u8 ; CAPACITY ] ;
427
+
428
+ fn deref ( & self ) -> & Self :: Target {
429
+ & self . data
430
+ }
431
+ }
432
+
433
+ impl <
434
+ const CAPACITY : usize ,
435
+ const READ_SIZE : usize ,
436
+ const WRITE_SIZE : usize ,
437
+ const ERASE_SIZE : usize ,
438
+ const ERASE_BYTE : u8 ,
439
+ const MULTI_WRITE : bool ,
440
+ > core:: ops:: DerefMut
441
+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
442
+ {
443
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
444
+ & mut self . data
445
+ }
446
+ }
447
+
448
+ impl <
449
+ const CAPACITY : usize ,
450
+ const READ_SIZE : usize ,
451
+ const WRITE_SIZE : usize ,
452
+ const ERASE_SIZE : usize ,
453
+ const ERASE_BYTE : u8 ,
454
+ const MULTI_WRITE : bool ,
455
+ > ErrorType for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
456
+ {
457
+ type Error = NorFlashErrorKind ;
458
+ }
459
+
460
+ impl <
461
+ const CAPACITY : usize ,
462
+ const READ_SIZE : usize ,
463
+ const WRITE_SIZE : usize ,
464
+ const ERASE_SIZE : usize ,
465
+ const ERASE_BYTE : u8 ,
466
+ const MULTI_WRITE : bool ,
467
+ > ReadNorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
468
+ {
469
+ const READ_SIZE : usize = READ_SIZE ;
470
+
471
+ fn read ( & mut self , offset : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
472
+ check_read ( self , offset, bytes. len ( ) ) ?;
473
+ bytes. copy_from_slice ( & self . data [ offset as usize ..] [ ..bytes. len ( ) ] ) ;
474
+ Ok ( ( ) )
475
+ }
476
+
477
+ fn capacity ( & self ) -> usize {
478
+ CAPACITY
479
+ }
480
+ }
481
+
482
+ impl <
483
+ const CAPACITY : usize ,
484
+ const READ_SIZE : usize ,
485
+ const WRITE_SIZE : usize ,
486
+ const ERASE_SIZE : usize ,
487
+ const ERASE_BYTE : u8 ,
488
+ const MULTI_WRITE : bool ,
489
+ > NorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
490
+ {
491
+ const WRITE_SIZE : usize = WRITE_SIZE ;
492
+ const ERASE_SIZE : usize = ERASE_SIZE ;
493
+
494
+ fn write ( & mut self , offset : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
495
+ check_write ( self , offset, bytes. len ( ) ) ?;
496
+ for ( dst, src) in self . data [ offset as usize ..] . iter_mut ( ) . zip ( bytes) {
497
+ if !MULTI_WRITE && * dst != ERASE_BYTE {
498
+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
499
+ }
500
+ * dst &= * src;
501
+ if * src != * dst {
502
+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
503
+ }
504
+ }
505
+ Ok ( ( ) )
506
+ }
507
+
508
+ fn erase ( & mut self , from : u32 , to : u32 ) -> Result < ( ) , Self :: Error > {
509
+ check_erase ( self , from, to) ?;
510
+ self . data [ from as usize ..to as usize ] . fill ( ERASE_BYTE ) ;
511
+ Ok ( ( ) )
512
+ }
513
+ }
514
+
0 commit comments