The Flash Service provides a centralized interface for userspace applications to interact with on-chip and external flash memory. This is achieved via an IPC-based client-server architecture.
Applications interact with flash through the Flash trait, typically using the FlashIpcClient implementation. All operations are blocking from the perspective of the caller.
FlashAddress system that abstracts hardware-specific bank and page layouts.To use the flash service, initialize a FlashIpcClient with a handle to the flash service:
use hal_flash::{Flash, FlashAddress}; use services_flash_client::FlashIpcClient; use util_ipc::IpcHandle; // 1. Connect to the flash service let mut flash = FlashIpcClient::new(IpcHandle::new(FLASH_SERVICE_HANDLE))?; // 2. Retrieve device geometry let (total_size, page_size, erasable_bitmap) = flash.geometry(); // 3. Erase a block (using the default page size) let addr = FlashAddress::new(0x1000); flash.erase(addr, page_size)?; // 4. Program data flash.program(addr, b"Hello, Flash!")?; // 5. Read data back let mut buf = [0u8; 13]; flash.read(addr, &mut buf)?;
Flash TraitThe primary interface for flash operations:
geometry() -> (NonZero<usize>, PowerOf2Usize, u32): Returns the total capacity, the default/smallest page size, and a bitmap of all supported erase block sizes.read(addr, buf): Reads data from the specified address.erase(addr, size): Erases a block of the specified size. The size must be one of the values supported in the erasable_bitmap.program(addr, data): Writes data to the specified address. Flash must be erased before programming.erasable_bitmapThe erasable_bitmap is a u32 where each set bit i indicates that an erase block size of 2^i bytes is supported.
0x800) -> 2048-byte erase supported.0x10000) -> 64KB erase supported.Flash memory is addressed using the FlashAddress type, which wraps a single 32-bit offset.
On platforms like Earlgrey, the most significant bit (MSB) of this offset is used to distinguish between different partitions:
The EarlgreyFlashAddress trait (from earlgrey_util) provides helper methods to construct and inspect addresses:
FlashAddress::data(offset): Accesses the main data partition.FlashAddress::info(bank, page, offset): Accesses specific info pages.The service is built on several layers of abstraction:
FlashIpcServer: Wraps a hardware-backed Flash implementation and dispatches IPC requests.FlashIpcClient: Implements the Flash trait by proxying calls to the server.FlashDriver Trait: Defines the low-level, often asynchronous, interface for hardware drivers.BlockingFlash: A wrapper that converts a FlashDriver into a synchronous Flash implementation using a provided blocking mechanism.graph TD Client[Userspace Application] -- "Flash Trait" --> IPC_Client[FlashIpcClient] IPC_Client -- "IPC" --> IPC_Server[FlashIpcServer] IPC_Server -- "Flash Trait" --> BlockingFlash[BlockingFlash] BlockingFlash -- "FlashDriver Trait" --> HardwareDriver[e.g., EmbeddedFlash] HardwareDriver --> HW[Flash Controller]