|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Persistent key(CRC32)->blob cache for compiled .rabook containers,built on the vendored, HIL-validated LevelX NOR wear-levelling layer (#201). More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_cache_store_entry_t |
| One RAM index slot: key -> {header sector, run length, payload len}. More... | |
| struct | ra8_cache_store_t |
| Caller-owned store handle. More... | |
| struct | ra8_cache_store_reader_t |
| Handle to an open entry that streams through ra8_cache_store_read. More... | |
| struct | ra8_cache_store_cfg_t |
| Injected dependencies + geometry for ra8_cache_store_init. More... | |
Typedefs | |
| typedef unsigned int(* | ra8_cache_store_nor_init_fn) (struct LX_NOR_FLASH_STRUCT *nor_flash) |
| LevelX NOR driver-initialise seam (the injected physical-flash bind). | |
Enumerations | |
| enum | ra8_cache_store_geom_t : uint16_t { k_ra8_cache_store_sector_bytes = 512U , k_ra8_cache_store_min_sectors = 8U , k_ra8_cache_store_overprov_pct = 20U , k_ra8_cache_store_max_overprov = 90U } |
| Fixed geometry + tuning constants for the store. More... | |
| enum | ra8_cache_store_flag_t : uint8_t { k_ra8_cache_store_flag_none = 0U , k_ra8_cache_store_flag_in_use = 1U << 0 , k_ra8_cache_store_flag_pinned = 1U << 1 } |
| Per-entry index-slot flag bits. More... | |
Functions | |
| ra8_err_t | ra8_cache_store_init (ra8_cache_store_t *store, const ra8_cache_store_cfg_t *cfg) |
| Bind a LevelX NOR flash instance and mount (or format) the store. | |
| ra8_err_t | ra8_cache_store_put (ra8_cache_store_t *store, uint32_t key, const uint8_t *data, uint32_t len) |
| Seal a new entry once: append data under key, atomically. | |
| ra8_err_t | ra8_cache_store_get (const ra8_cache_store_t *store, uint32_t key, ra8_cache_store_reader_t *out_reader) |
| Open a sealed entry for random reads through ra8_cache_store_read. | |
| ra8_err_t | ra8_cache_store_read (void *ctx, uint64_t offset, uint8_t *buf, uint32_t len) |
| ra8_vsource_read_fn-shaped random read over an open entry. | |
| ra8_err_t | ra8_cache_store_evict (ra8_cache_store_t *store, uint32_t key) |
| Drop an entry and reclaim its sectors (no write-back). | |
| ra8_err_t | ra8_cache_store_pin (ra8_cache_store_t *store, uint32_t key, bool pin) |
| Pin or unpin an entry (pinned entries are never evicted). | |
| ra8_err_t | ra8_cache_store_sync (ra8_cache_store_t *store) |
| Checkpoint the index to flash (directory + clean marker not set). | |
| ra8_err_t | ra8_cache_store_close (ra8_cache_store_t *store) |
| Checkpoint, set the clean-shutdown marker, and close the store. | |
Persistent key(CRC32)->blob cache for compiled .rabook containers,
built on the vendored, HIL-validated LevelX NOR wear-levelling layer (#201).
ra8_cache_store is the persistent-cache tier from the multi-GB book-streaming design (Decision 2): a small, flat put / get / evict store keyed by the source CRC-32, log-structured, living on the OSPI/NAND tier – NOT a second ra8_fs mount. It is the on-flash backing for a compiled .rabook so the reader can page a book straight out of NOR flash without touching the SD card (fast resume + a power-savings win on a battery handheld).
The wear-levelling / block-remapping / power-safe-sector-write machinery is the already-vendored Azure RTOS LevelX (libs/third_party/levelx/), run in standalone mode (LX_STANDALONE_ENABLE, no ThreadX). This module is only the thin key -> LevelX-logical-sector index + log/checkpoint bookkeeping on top of lx_nor_flash_sector_write / _read / _release. See issue #201 and recon/reports/disk-cache-design-review.md for the full rationale.
The bind to a physical flash is the injected ra8_cache_store_nor_init_fn driver-initialise callback – lx_nor_driver_ra8_xspi_initialize on the EK-RA8D2 Octo-SPI flash, or a RAM NOR fake under the host tests. This header therefore never includes lx_api.h; the LX_NOR_FLASH control block is passed as an opaque, forward-declared pointer the caller owns.
The caller supplies all storage: the LX_NOR_FLASH control block, this ra8_cache_store_t handle, the ra8_cache_store_entry_t index array, and a one-sector (>= k_ra8_cache_store_sector_bytes) staging buffer. The module allocates nothing.
ra8_cache_store_get fills a ra8_cache_store_reader_t and the caller wires ra8_cache_store_read (an ra8_vsource_read_fn-shaped read(ctx,off,buf,len)) into ra8_vsource_add_paged, so a cached .rabook demand-pages through the #204/#205 paged path – full residency is never required.
An entry is sealed by a single ra8_cache_store_put; there is deliberately no in-place-update call (the Liskov-clean shape). Because every cached blob is re-derivable from its SD source, eviction never writes anything back – it only releases sectors. GC is internal to LevelX plus this module's sector accounting.
Definition in file ra8_cache_store.h.
| typedef unsigned int(* ra8_cache_store_nor_init_fn) (struct LX_NOR_FLASH_STRUCT *nor_flash) |
LevelX NOR driver-initialise seam (the injected physical-flash bind).
Passed straight to lx_nor_flash_open() / lx_nor_flash_format(). Production binds lx_nor_driver_ra8_xspi_initialize; host tests bind a RAM NOR fake. The unsigned int return mirrors LevelX's UINT (LX_SUCCESS == 0) without needing the LevelX typedefs here.
| [in,out] | nor_flash | LevelX control block to populate (geometry + driver callbacks + sector buffer). |
Definition at line 95 of file ra8_cache_store.h.
| enum ra8_cache_store_flag_t : uint8_t |
Per-entry index-slot flag bits.
| Enumerator | |
|---|---|
| k_ra8_cache_store_flag_none | Empty slot. |
| k_ra8_cache_store_flag_in_use | Slot holds a live entry. |
| k_ra8_cache_store_flag_pinned | Never-evict (open book / metadata). |
Definition at line 117 of file ra8_cache_store.h.
| enum ra8_cache_store_geom_t : uint16_t |
Fixed geometry + tuning constants for the store.
k_ra8_cache_store_sector_bytes is the LevelX logical-sector size the module reads/writes a sector at a time; the staging buffer and every media record are sized against it.
Definition at line 105 of file ra8_cache_store.h.
|
nodiscard |
Checkpoint, set the clean-shutdown marker, and close the store.
Writes the directory checkpoint and stamps the clean marker so the next ra8_cache_store_init takes the fast (no-scan) mount path, then closes the LevelX partition. After this the handle must be re-init'd before reuse.
| [in,out] | store | Initialised store. |
| k_ra8_ok | Store checkpointed, marked clean, and closed. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write/close failed. |
Definition at line 548 of file ra8_cache_store.c.
References ra8_cache_store_t::flash, ra8_cache_store_t::inited, internal_checkpoint(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by cache_store_demo_run(), and internal_demo_phase_remount().
|
nodiscard |
Drop an entry and reclaim its sectors (no write-back).
Releases the entry's LevelX logical sectors (returning them to the free pool for GC) and clears its index slot. Because every cached blob is re-derivable from its SD source, nothing is ever written back on eviction – the write-once invariant makes eviction unconditionally cheap. A pinned entry is refused.
| [in,out] | store | Initialised store. |
| [in] | key | Content key to drop. |
| k_ra8_ok | Entry dropped and reclaimed. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
| k_ra8_err_busy | Entry is pinned (unpin first). |
| k_ra8_err_hw_init_failed | LevelX sector release failed. |
Definition at line 502 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::inited, internal_mark_dirty(), internal_release_run(), k_ra8_cache_store_flag_pinned, k_ra8_err_busy, k_ra8_err_not_found, k_ra8_ok, ra8_cache_store_t::live_sectors, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, s_tag, ra8_cache_store_entry_t::sector_count, and ra8_cache_store_entry_t::start_sector.
Referenced by internal_demo_phase_evict(), and internal_demo_phase_remount().
|
nodiscard |
Open a sealed entry for random reads through ra8_cache_store_read.
Looks key up in the index and fills out_reader so the caller can register it with ra8_vsource_add_paged(vs, ra8_cache_store_read,
out_reader, 0, out_reader->byte_len, &id). No data is copied here.
| [in] | store | Initialised store. |
| [in] | key | Content key to open. |
| [out] | out_reader | Receives the streaming handle (out-lives the vsource). |
| k_ra8_ok | Entry found; out_reader populated. |
| k_ra8_err_null_ptr | store or out_reader NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
Definition at line 424 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::byte_len, ra8_cache_store_t::index, ra8_cache_store_t::inited, k_ra8_err_not_found, k_ra8_ok, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, s_tag, ra8_cache_store_entry_t::sector_count, and ra8_cache_store_entry_t::start_sector.
Referenced by internal_demo_get_and_verify(), internal_demo_phase_evict(), internal_demo_phase_remount(), and internal_demo_put_and_verify().
|
nodiscard |
Bind a LevelX NOR flash instance and mount (or format) the store.
Opens the injected LevelX NOR partition (formatting first when cfg->format), then recovers the key index:
| [out] | store | Zero-initialised handle to populate. |
| [in] | cfg | Injected dependencies + geometry (see the struct). |
| k_ra8_ok | Store mounted (or formatted) and ready. |
| k_ra8_err_null_ptr | store, cfg, or a required cfg member NULL. |
| k_ra8_err_invalid_size | staging_bytes too small, index_cap zero, or logical_sectors too small for the layout. |
| k_ra8_err_invalid_arg | overprovision_pct out of range. |
| k_ra8_err_hw_init_failed | LevelX open/format failed. |
| k_ra8_err_invalid_state | On-flash checkpoint/superblock is corrupt. |
Definition at line 794 of file ra8_cache_store_mount.c.
References ra8_cache_store_t::inited, internal_bringup(), internal_init_fields(), internal_validate_cfg(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by cache_store_demo_run(), and internal_demo_phase_remount().
|
nodiscard |
Pin or unpin an entry (pinned entries are never evicted).
A pin marks the currently-open book's container or the shelf/library metadata as never-evict, buying fast resume without an SD-card wake. The pin state is persisted at the next ra8_cache_store_sync / ra8_cache_store_close.
| [in,out] | store | Initialised store. |
| [in] | key | Content key to (un)pin. |
| [in] | pin | True to pin, false to unpin. |
| k_ra8_ok | Pin state updated. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
pin. Definition at line 523 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::inited, internal_mark_dirty(), k_ra8_cache_store_flag_pinned, k_ra8_err_not_found, k_ra8_ok, pin, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by internal_demo_phase_evict().
|
nodiscard |
Seal a new entry once: append data under key, atomically.
Log-structured append with no in-place-update path: the payload sectors are written first, then the entry header last, so a power loss mid-append leaves an unreferenced (reclaimable) tail rather than a visible corrupt entry. Fails if key already exists (write-once; evict first to replace) or if the overprovisioned budget cannot fit the run.
| [in,out] | store | Initialised store. |
| [in] | key | Content key (source CRC-32). |
| [in] | data | Payload bytes (len readable). |
| [in] | len | Payload length in bytes (> 0). |
| k_ra8_ok | Entry sealed and indexed. |
| k_ra8_err_null_ptr | store or data NULL. |
| k_ra8_err_invalid_size | len is zero. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_exists | key already present (write-once). |
| k_ra8_err_no_mem | Index full or budget/free-run exhausted. |
| k_ra8_err_hw_init_failed | LevelX sector write failed. |
Definition at line 407 of file ra8_cache_store.c.
References internal_alloc_run(), internal_mark_dirty(), internal_put_check(), internal_write_entry(), k_ra8_ok, ra8_cache_store_t::live_sectors, ra8_cache_store_t::next_seq, priv_cache_store_index_add(), RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_demo_put_and_verify().
| ra8_err_t ra8_cache_store_read | ( | void * | ctx, |
| uint64_t | offset, | ||
| uint8_t * | buf, | ||
| uint32_t | len ) |
ra8_vsource_read_fn-shaped random read over an open entry.
Reads len bytes at offset from the entry's payload sectors, one LevelX logical sector at a time through the store staging buffer. Signature matches ra8_vsource_read_fn so it binds straight into ra8_vsource_add_paged.
| [in] | ctx | A ra8_cache_store_reader_t populated by ra8_cache_store_get. |
| [in] | offset | Byte offset within the payload (< byte_len). |
| [out] | buf | Destination (len writable bytes). |
| [in] | len | Bytes to read. |
| k_ra8_ok | Bytes copied. |
| k_ra8_err_null_ptr | ctx or buf NULL. |
| k_ra8_err_out_of_range | offset + len exceeds byte_len. |
| k_ra8_err_hw_init_failed | LevelX sector read failed. |
Definition at line 489 of file ra8_cache_store.c.
References ra8_cache_store_reader_t::byte_len, ra8_cache_store_reader_t::data_sectors, ra8_cache_store_reader_t::data_start, internal_read_stream(), k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, s_tag, and ra8_cache_store_reader_t::store.
Referenced by internal_demo_get_and_verify(), and internal_demo_put_and_verify().
|
nodiscard |
Checkpoint the index to flash (directory + clean marker not set).
Serialises the live index into the on-flash directory region and rewrites the superblock. Called internally by ra8_cache_store_close; exposed so a caller can periodically shorten the replay a future crash would need. The clean marker stays unset until close.
| [in,out] | store | Initialised store. |
| k_ra8_ok | Checkpoint written. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write failed. |
Definition at line 541 of file ra8_cache_store.c.
References ra8_cache_store_t::inited, internal_checkpoint(), RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, and s_tag.