|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
ra8_io block-device fabric – one LBA vtable across every storage medium. More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_io_blockdev_caps_t |
| Static properties a backend reports about its medium. More... | |
| struct | ra8_io_blockdev_t |
| Caller-allocated block-device handle binding a backend to its context. More... | |
Typedefs | |
| typedef struct ra8_io_blockdev_iface | ra8_io_blockdev_iface_t |
Enumerations | |
| enum | ra8_io_block_size_t : uint16_t { k_ra8_io_block_size_bytes = 512 } |
| Logical block size of the fabric. More... | |
| enum | ra8_io_erase_value_t : uint8_t { k_ra8_io_erase_value_zero = 0x00 , k_ra8_io_erase_value_ones = 0xFF } |
| Byte value a block reads back as after a successful erase. More... | |
Functions | |
| ra8_err_t | ra8_io_blockdev_read (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count, uint8_t *buf) |
| Read count logical blocks starting at lba into buf. | |
| ra8_err_t | ra8_io_blockdev_write (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count, const uint8_t *buf) |
| Write count logical blocks from buf starting at lba. | |
| ra8_err_t | ra8_io_blockdev_erase (const ra8_io_blockdev_t *bd, uint32_t lba, uint32_t count) |
| Erase count blocks starting at lba to the medium's erase value. | |
| ra8_err_t | ra8_io_blockdev_get_caps (const ra8_io_blockdev_t *bd, ra8_io_blockdev_caps_t *out) |
| Report the bound backend's medium capabilities. | |
| ra8_err_t | ra8_io_blockdev_sync (const ra8_io_blockdev_t *bd) |
| Flush any backend write buffering to the medium. | |
| ra8_err_t | ra8_io_blockdev_as_fs_backend (const ra8_io_blockdev_t *bd, ra8_fs_backend_t *out) |
| Expose a bound block device as an ra8_fs_backend_t for ra8_fs. | |
ra8_io block-device fabric – one LBA vtable across every storage medium.
A block device exposes fixed-size logical blocks (sectors) addressed by a Logical Block Address (LBA). This header defines the single block-device interface every storage backend implements – SD-over-SPI, native SDHI, OSPI NOR flash, MRAM, an SDRAM ramdisk, a hosted USB mass-storage device, and a pure-RAM scratch device – so the layers above (filesystem, cache, VFS) never name a peripheral.
The interface generalises the ra8_fs_backend_t seam the FAT filesystem already runs on: it keeps the same 512-byte logical block but adds an explicit capability query (erase granularity, program size, erase value, read-only, must-erase-before-write) so the filesystem and the write-back cache can do correct read-modify-write on flash media. ra8_io_blockdev_as_fs_backend() bridges any backend back to an ra8_fs_backend_t, so existing ra8_fs mounts unchanged on top of any medium.
The handle (ra8_io_blockdev_t) is caller-allocated – declare one per device and bind a backend into it with that backend's _init() helper (see ra8_io_blockdev_ram.h and friends). No dynamic allocation occurs; backends keep their state in caller-provided storage. Multiple devices coexist because each owns its own handle and context.
This block device is the read/write/erase storage seam at [Ring 4 / PAL]. It is deliberately distinct from ra8_vsource (ra8_vsource.h, [Ring 2 / Core]), the read-only byte-offset view that feeds the #147 page cache. The split is intentional, not drift: a Ring-2 source must not depend on this Ring-4 fabric, since that would invert ring ordering (see docs/RING_AND_WORLD.md). The sanctioned bridge is the Ring-4 adapter ra8_io_blockdev_vsource.h, which exposes a bound block device as a ra8_vsource_read_fn so it can be wired into the page cache via ra8_vsource_add_paged.
Definition in file ra8_io_blockdev.h.
| typedef struct ra8_io_blockdev_iface ra8_io_blockdev_iface_t |
Definition at line 158 of file ra8_io_blockdev.h.
| enum ra8_io_block_size_t : uint16_t |
Logical block size of the fabric.
The fabric, like ra8_fs, addresses storage in 512-byte logical blocks. A backend whose medium has a different native sector or page size adapts to this logical size internally (e.g. NOR flash buffers a program/erase unit).
| Enumerator | |
|---|---|
| k_ra8_io_block_size_bytes | Bytes per logical block (the only size). |
Definition at line 86 of file ra8_io_blockdev.h.
| enum ra8_io_erase_value_t : uint8_t |
Byte value a block reads back as after a successful erase.
RAM-backed media return zero after erase; NOR flash and MRAM return all-ones. The bridge to ra8_fs_backend_t consults this so it only advertises a zero-guaranteeing erase to the formatter (ra8_fs requires erased ranges to read back as 0x00).
| Enumerator | |
|---|---|
| k_ra8_io_erase_value_zero | Block reads back as 0x00 after erase. |
| k_ra8_io_erase_value_ones | Block reads back as 0xFF after erase. |
Definition at line 102 of file ra8_io_blockdev.h.
|
nodiscard |
Expose a bound block device as an ra8_fs_backend_t for ra8_fs.
Fills out with trampolines that forward ra8_fs's read_block / write_block / get_capacity / erase_blocks calls into this fabric, with out->ctx pointing at bd. The erase trampoline advertises itself to the formatter only when the medium erases to zero (ra8_fs requires erased ranges to read back as 0x00); on all-ones flash it returns k_ra8_err_not_supported so the formatter falls back to writing zeros. After this call any existing ra8_fs API (ra8_fs_mount, ra8_fs_format, ...) works on the bound medium.
| [in] | bd | Bound block-device handle (must out-live the filesystem use). |
| [out] | out | ra8_fs_backend_t to populate. |
| k_ra8_ok | *out wired to bd. |
| k_ra8_err_null_ptr | bd or out was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
Definition at line 307 of file ra8_io_blockdev.c.
References ra8_fs_backend_t::ctx, ra8_fs_backend_t::erase_blocks, ra8_fs_backend_t::get_capacity, internal_fs_erase(), internal_fs_get_capacity(), internal_fs_read(), internal_fs_write(), internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_backend_t::read_block, s_tag, and ra8_fs_backend_t::write_block.
Referenced by fileops_mount_volume(), internal_demo_mount(), internal_demo_mount(), internal_demo_probe_fat(), internal_demo_probe_foreign(), internal_swap_run_one(), ra8_io_roundtrip_mount(), sdhi_demo_mount_via_io(), selftest_mount_volume(), selftest_mount_volume(), selftest_mount_volume(), selftest_mount_volume(), and selftest_mount_volume().
|
nodiscard |
Erase count blocks starting at lba to the medium's erase value.
After a successful erase the range reads back as caps.erase_value (zero for RAM media, all-ones for NOR/MRAM). Backends whose medium has no erase concept may omit the operation, in which case this returns k_ra8_err_not_supported.
| [in] | bd | Bound block-device handle. |
| [in] | lba | First logical block address to erase. |
| [in] | count | Number of consecutive blocks to erase. |
| k_ra8_ok | Range erased. |
| k_ra8_err_null_ptr | bd was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
| k_ra8_err_not_supported | The backend has no erase primitive. |
| k_ra8_err_out_of_range | lba + count exceeds the device capacity. |
Definition at line 102 of file ra8_io_blockdev.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_iface::erase, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_err_not_supported, and k_ra8_ok.
Referenced by demo_checkpoint(), internal_alloc_blank(), internal_cache_erase(), internal_demo_roundtrip(), internal_fs_erase(), and internal_reclaim_stale().
|
nodiscard |
Report the bound backend's medium capabilities.
| [in] | bd | Bound block-device handle. |
| [out] | out | Capabilities snapshot. |
| k_ra8_ok | *out populated. |
| k_ra8_err_null_ptr | bd or out was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
Definition at line 114 of file ra8_io_blockdev.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_iface::get_caps, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_cache_get_caps(), internal_fs_erase(), internal_fs_get_capacity(), and ra8_ftl_init().
|
nodiscard |
Read count logical blocks starting at lba into buf.
Forwards to the bound backend's read primitive. buf must hold at least count * k_ra8_io_block_size_bytes bytes. Reading past the device capacity is rejected by the backend, not silently truncated.
| [in] | bd | Bound block-device handle. |
| [in] | lba | First logical block address to read. |
| [in] | count | Number of consecutive blocks to read. |
| [out] | buf | Destination buffer (>= count * 512 bytes). |
| k_ra8_ok | Blocks read into buf. |
| k_ra8_err_null_ptr | bd or buf was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
| k_ra8_err_out_of_range | lba + count exceeds the device capacity. |
| k_ra8_err_invalid_arg | Backend rejected the request. |
Definition at line 79 of file ra8_io_blockdev.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_io_blockdev_iface::read, and s_tag.
Referenced by demo_reopen_naive(), demo_restore(), demo_write_verify(), fileops_probe_layout(), internal_bd_read_middle(), internal_bd_read_sector(), internal_cache_read_block(), internal_demo_roundtrip(), internal_fs_read(), and internal_read_one().
|
nodiscard |
Flush any backend write buffering to the medium.
For buffered backends (e.g. a NOR write-coalescing shim) this commits pending data. Backends with no buffering treat it as a successful no-op.
| [in] | bd | Bound block-device handle. |
| k_ra8_ok | Pending writes committed (or none pending). |
| k_ra8_err_null_ptr | bd was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
Definition at line 125 of file ra8_io_blockdev.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, and ra8_io_blockdev_iface::sync.
Referenced by internal_cache_sync(), and internal_dev_sync().
|
nodiscard |
Write count logical blocks from buf starting at lba.
Forwards to the bound backend's write primitive. On media that require an erase before programming the backend performs the necessary read-modify-write or erase internally; callers that want erase-aligned efficiency should use ra8_io_blockdev_erase plus aligned writes.
| [in] | bd | Bound block-device handle. |
| [in] | lba | First logical block address to write. |
| [in] | count | Number of consecutive blocks to write. |
| [in] | buf | Source buffer (>= count * 512 bytes). |
| k_ra8_ok | Blocks written. |
| k_ra8_err_null_ptr | bd or buf was NULL. |
| k_ra8_err_not_initialized | No backend is bound to bd. |
| k_ra8_err_out_of_range | lba + count exceeds the device capacity. |
| k_ra8_err_not_supported | The device is read-only. |
Definition at line 91 of file ra8_io_blockdev.c.
References ra8_io_blockdev_t::ctx, ra8_io_blockdev_t::iface, internal_validate(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_tag, and ra8_io_blockdev_iface::write.
Referenced by demo_checkpoint(), demo_write_verify(), internal_bdsink_commit_sector(), internal_cache_write_block(), internal_demo_probe_foreign(), internal_demo_roundtrip(), internal_fs_write(), and internal_write_one().