1- //! M2 Bootloader RUST
1+ //! M2 Bootloader RUST
22//! ------------------
33//! License : Dual License
44//! - Apache 2.0 for open-source / personal use
55//! - Commercial license required for closed-source use
66//! Author : Md Mahbubur Rahman
77//! URL : <https://m-a-h-b-u-b.github.io>
8- //! GitHub : <https://github.com/m-a-h-b-u-b/M2-Bootloader-RUST>
8+ //! GitHub : <https://github.com/m-a-h-b-u-b/M2-Bootloader-Rust>
9+ //!
10+ //! High‑level verification utilities for firmware images stored in MCU flash.
11+ //!
12+ //! This module provides routines to verify that a written firmware image
13+ //! matches an expected CRC or raw byte slice. It builds on the [`Flash`] trait
14+ //! and is meant to be MCU‑agnostic.
915
10- pub fn firmware_valid ( ) -> bool {
11- true
12- }
16+ use crate :: flash:: { Flash , FlashError , InternalFlash , Result } ;
17+
18+ /// Verify that the CRC32 of a flash region matches the expected value.
19+ ///
20+ /// * `addr` - Absolute start address of the region to verify.
21+ /// * `len` - Length in bytes of the region to verify.
22+ /// * `expected_crc` - Expected CRC32 value.
23+ ///
24+ /// Returns `Ok(true)` if the CRC matches, `Ok(false)` if it does not,
25+ /// or a `FlashError` on read/driver failures.
26+ pub fn verify_crc ( flash : & mut dyn Flash , addr : usize , len : usize , expected_crc : u32 ) -> Result < bool > {
27+ let crc = flash. crc32 ( addr, len) ?;
28+ Ok ( crc == expected_crc)
29+ }
30+
31+ /// Verify that the bytes in flash match a reference buffer.
32+ ///
33+ /// This is slower than CRC comparison but can pinpoint the first mismatching
34+ /// offset when `stop_on_mismatch` is `true`.
35+ pub fn verify_bytes (
36+ flash : & mut dyn Flash ,
37+ addr : usize ,
38+ reference : & [ u8 ] ,
39+ stop_on_mismatch : bool ,
40+ ) -> Result < bool > {
41+ let mut buf = [ 0u8 ; 256 ] ;
42+ let mut offset = 0 ;
43+ while offset < reference. len ( ) {
44+ let chunk = core:: cmp:: min ( buf. len ( ) , reference. len ( ) - offset) ;
45+ flash. read ( addr + offset, & mut buf[ ..chunk] ) ?;
46+ if stop_on_mismatch && & buf[ ..chunk] != & reference[ offset..offset + chunk] {
47+ return Ok ( false ) ;
48+ }
49+ offset += chunk;
50+ }
51+ if stop_on_mismatch {
52+ Ok ( true )
53+ } else {
54+ // For full comparison we already returned false on mismatch, so true.
55+ Ok ( true )
56+ }
57+ }
58+
59+ /// Convenience function to verify a region using the global internal flash driver.
60+ /// Adjust `FLASH_*` constants in `flash.rs` to your MCU's memory map.
61+ #[ allow( dead_code) ]
62+ pub fn verify_region_crc_internal ( addr : usize , len : usize , expected_crc : u32 ) -> Result < bool > {
63+ // SAFETY: INTERNAL_FLASH is a global static mut, access must be single‑threaded.
64+ unsafe { super :: flash:: INTERNAL_FLASH . crc32 ( addr, len) . map ( |c| c == expected_crc) }
65+ }
66+
67+ #[ cfg( test) ]
68+ mod tests {
69+ use super :: * ;
70+ use crate :: flash:: MockFlash ;
71+
72+ #[ test]
73+ fn test_verify_crc_and_bytes ( ) {
74+ let mut mock = MockFlash :: new ( 1024 , 256 , 256 ) ;
75+ let data = [ 0x55u8 ; 512 ] ;
76+ mock. write_region ( 0 , & data) . unwrap ( ) ;
77+
78+ // Compute CRC directly from mock.
79+ let crc = mock. crc32 ( 0 , 512 ) . unwrap ( ) ;
80+ assert ! ( verify_crc( & mut mock, 0 , 512 , crc) . unwrap( ) ) ;
81+
82+ // Verify bytes match.
83+ assert ! ( verify_bytes( & mut mock, 0 , & data, true ) . unwrap( ) ) ;
84+
85+ // Mismatch case.
86+ let wrong_data = [ 0xAAu8 ; 512 ] ;
87+ assert ! ( !verify_bytes( & mut mock, 0 , & wrong_data, true ) . unwrap( ) ) ;
88+ }
89+ }
0 commit comments