@@ -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
}
@@ -385,3 +389,132 @@ where
385
389
Ok ( ( ) )
386
390
}
387
391
}
392
+
393
+ /// Simple RAM-backed flash storage implementation for tests
394
+ #[ derive( Clone , Copy , Debug ) ]
395
+ pub struct MockFlash <
396
+ const CAPACITY : usize ,
397
+ const READ_SIZE : usize = 1 ,
398
+ const WRITE_SIZE : usize = 1 ,
399
+ const ERASE_SIZE : usize = { 1 << 10 } ,
400
+ const ERASE_BYTE : u8 = 0xff ,
401
+ const MULTI_WRITE : bool = false,
402
+ > {
403
+ data : [ u8 ; CAPACITY ] ,
404
+ }
405
+
406
+ impl <
407
+ const CAPACITY : usize ,
408
+ const READ_SIZE : usize ,
409
+ const WRITE_SIZE : usize ,
410
+ const ERASE_SIZE : usize ,
411
+ const ERASE_BYTE : u8 ,
412
+ const MULTI_WRITE : bool ,
413
+ > Default for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
414
+ {
415
+ fn default ( ) -> Self {
416
+ Self {
417
+ data : [ ERASE_BYTE ; CAPACITY ] ,
418
+ }
419
+ }
420
+ }
421
+
422
+ impl <
423
+ const CAPACITY : usize ,
424
+ const READ_SIZE : usize ,
425
+ const WRITE_SIZE : usize ,
426
+ const ERASE_SIZE : usize ,
427
+ const ERASE_BYTE : u8 ,
428
+ const MULTI_WRITE : bool ,
429
+ > core:: ops:: Deref
430
+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
431
+ {
432
+ type Target = [ u8 ; CAPACITY ] ;
433
+
434
+ fn deref ( & self ) -> & Self :: Target {
435
+ & self . data
436
+ }
437
+ }
438
+
439
+ impl <
440
+ const CAPACITY : usize ,
441
+ const READ_SIZE : usize ,
442
+ const WRITE_SIZE : usize ,
443
+ const ERASE_SIZE : usize ,
444
+ const ERASE_BYTE : u8 ,
445
+ const MULTI_WRITE : bool ,
446
+ > core:: ops:: DerefMut
447
+ for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
448
+ {
449
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
450
+ & mut self . data
451
+ }
452
+ }
453
+
454
+ impl <
455
+ const CAPACITY : usize ,
456
+ const READ_SIZE : usize ,
457
+ const WRITE_SIZE : usize ,
458
+ const ERASE_SIZE : usize ,
459
+ const ERASE_BYTE : u8 ,
460
+ const MULTI_WRITE : bool ,
461
+ > ErrorType for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
462
+ {
463
+ type Error = NorFlashErrorKind ;
464
+ }
465
+
466
+ impl <
467
+ const CAPACITY : usize ,
468
+ const READ_SIZE : usize ,
469
+ const WRITE_SIZE : usize ,
470
+ const ERASE_SIZE : usize ,
471
+ const ERASE_BYTE : u8 ,
472
+ const MULTI_WRITE : bool ,
473
+ > ReadNorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
474
+ {
475
+ const READ_SIZE : usize = READ_SIZE ;
476
+
477
+ fn read ( & mut self , offset : u32 , bytes : & mut [ u8 ] ) -> Result < ( ) , Self :: Error > {
478
+ check_read ( self , offset, bytes. len ( ) ) ?;
479
+ bytes. copy_from_slice ( & self . data [ offset as usize ..] [ ..bytes. len ( ) ] ) ;
480
+ Ok ( ( ) )
481
+ }
482
+
483
+ fn capacity ( & self ) -> usize {
484
+ CAPACITY
485
+ }
486
+ }
487
+
488
+ impl <
489
+ const CAPACITY : usize ,
490
+ const READ_SIZE : usize ,
491
+ const WRITE_SIZE : usize ,
492
+ const ERASE_SIZE : usize ,
493
+ const ERASE_BYTE : u8 ,
494
+ const MULTI_WRITE : bool ,
495
+ > NorFlash for MockFlash < CAPACITY , READ_SIZE , WRITE_SIZE , ERASE_SIZE , ERASE_BYTE , MULTI_WRITE >
496
+ {
497
+ const WRITE_SIZE : usize = WRITE_SIZE ;
498
+ const ERASE_SIZE : usize = ERASE_SIZE ;
499
+ const ERASE_BYTE : u8 = ERASE_BYTE ;
500
+
501
+ fn write ( & mut self , offset : u32 , bytes : & [ u8 ] ) -> Result < ( ) , Self :: Error > {
502
+ check_write ( self , offset, bytes. len ( ) ) ?;
503
+ for ( dst, src) in self . data [ offset as usize ..] . iter_mut ( ) . zip ( bytes) {
504
+ if !MULTI_WRITE && * dst != ERASE_BYTE {
505
+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
506
+ }
507
+ * dst &= * src;
508
+ if * src != * dst {
509
+ return Err ( NorFlashErrorKind :: DirtyWrite ) ;
510
+ }
511
+ }
512
+ Ok ( ( ) )
513
+ }
514
+
515
+ fn erase ( & mut self , from : u32 , to : u32 ) -> Result < ( ) , Self :: Error > {
516
+ check_erase ( self , from, to) ?;
517
+ self . data [ from as usize ..to as usize ] . fill ( ERASE_BYTE ) ;
518
+ Ok ( ( ) )
519
+ }
520
+ }
0 commit comments