This HAL provides abstractions for interacting with flash memory. It defines traits for low-level drivers and high-level synchronous interfaces, along with a helper implementation to bridge them.
FlashAddressA transparent wrapper around a 32-bit offset (u32) representing a location in flash memory. It supports basic arithmetic operations (Add, AddAssign, BitAnd, BitAndAssign) to facilitate address calculations.
Platform-specific extension traits (like EarlgreyFlashAddress in earlgrey_util) may use the offset bits to encode additional information (e.g., distinguishing between DATA and INFO partitions using the MSB).
FlashDriver TraitDefines the low-level interface for flash hardware. It is designed to support both synchronous and asynchronous hardware controllers using a start-poll-complete execution model for erase and program operations:
start_erase or start_program.is_busy, or wait for a hardware interrupt.complete_op.Read operations (read) are synchronous for simplicity.
Drivers also define hardware-specific constraints as constants:
ERASABLE_SIZES_BITMAP: A bitmap where bit i is set if erasing blocks of size 2^i is supported.PROGRAM_WINDOW_SIZE: The maximum size of a single write, and the boundary alignment constraint for writes.MAX_READ_SIZE: The maximum size of a single read.READ_ALIGNMENT / PROGRAM_ALIGNMENT: Address and size alignment requirements.Flash TraitProvides a simplified, synchronous, blocking interface suitable for application use. It abstracts away the low-level start-poll-complete flow and hardware constraints (alignment, windows).
BlockingFlashA concrete implementation of the Flash trait that wraps a FlashDriver and a Blocking mechanism. It implements the blocking behavior and handles driver constraints automatically:
graph TD App[Application] -- "Flash::program()" --> BF[BlockingFlash] BF -- "1. start_program()" --> Driver[FlashDriver] BF -- "2. wait_for_notification()" --> Blocking[Blocking impl] Blocking -- "wakes up (IRQ/Poll)" --> BF BF -- "3. complete_op()" --> Driver
If a read request is not aligned to TDriver::READ_ALIGNMENT, BlockingFlash::read will:
Hardware flash controllers often cannot program data that crosses a write window boundary (typically 64 bytes). BlockingFlash::program automatically detects these boundaries and splits a large or unaligned write into multiple smaller writes that fit within the program windows.