blob: 55823ea9f09f4186977db5ee10262fe19ffaff1c [file] [view]
# Blocking Flash HAL
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.
## Key Abstractions
### `FlashAddress`
A 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` Trait
Defines 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:
1. **Start**: Initiated via `start_erase` or `start_program`.
2. **Poll**: Check completion status via `is_busy`, or wait for a hardware interrupt.
3. **Complete**: Finalize the operation and retrieve any execution errors via `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` Trait
Provides a simplified, synchronous, blocking interface suitable for application use. It abstracts away the low-level start-poll-complete flow and hardware constraints (alignment, windows).
### `BlockingFlash`
A concrete implementation of the `Flash` trait that wraps a `FlashDriver` and a `Blocking` mechanism. It implements the blocking behavior and handles driver constraints automatically:
```mermaid
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
```
#### Read Alignment Handling
If a read request is not aligned to `TDriver::READ_ALIGNMENT`, `BlockingFlash::read` will:
1. Read the aligned block containing the unaligned start address into a temporary buffer.
2. Copy the requested bytes from the temporary buffer.
3. Read the remaining data in aligned chunks directly into the destination buffer.
#### Program Window Handling
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.