64typedef enum : uintptr_t {
69typedef enum : uint32_t {
112static const char*
const s_tag =
"ra8_ftl_demo";
182 uint32_t cpuclk0_hz = 0U;
183 uint32_t pclka_hz = 0U;
197 .pclk_hz = pclka_hz};
229 .ecc_encoder_enable =
true,
230 .ecc_decoder_enable =
true};
238 "mram blockdev init");
282 if (
memcmp(got, blk,
sizeof(blk)) != 0) {
484 if (
memcmp(got, want,
sizeof(want)) != 0) {
491 if (phys != want_phys) {
519 demo_print(
"ra8_ftl_demo: wear stats unavailable\r\n");
522 demo_print(
"ra8_ftl_demo: wear erase-count max ");
550 uint32_t migrations = 0U;
551 uint16_t last_phys = 0U;
554 if (migrations == 0U) {
559 demo_print(
"ra8_ftl_demo: naive re-open lost the mapping (reads erase value)\r\n");
596 demo_print(
"ra8_ftl_demo: wear-level + power-cycle-survive on extra MRAM PASS\r\n");
void main(void)
Secure fallback main entry point.
demo_const_t
Console + volume + payload knobs (no magic numbers).
@ k_demo_uart_baud
Console baud.
@ k_demo_uart_chan
SCI8 J-Link OB console.
@ k_demo_pin_shift
Port byte position in ra8_port_pin_t.
@ k_demo_seed_mul
Test-pattern multiplier.
static ra8_io_stream_uart_state_t s_ust
static ra8_io_stream_t s_uart
UART output stream + its sink state.
static uint8_t s_scratch[(size_t) k_ra8_compress_scratch_bytes]
Compressor scratch (one miniz tdefl_compressor) in SRAM.
static ra8_io_blockdev_t s_bd
Block-device handle + its RAM backend state.
static const ra8_port_pin_t k_demo_txd
SCI8 console TXD = PD02.
static void demo_print(const char *msg)
Print a NUL-terminated string on the demo's UART stream.
static const ra8_port_pin_t k_demo_rxd
SCI8 console RXD = PD03.
static void demo_setup_or_halt(void)
Bring up CGC + SysTick + the SCI8 console; halt forever on any failure.
static ra8_err_t demo_run(void)
Bring up the OSPI block device, then run the shared FAT round-trip.
static ra8_err_t demo_write_verify(uint32_t lbn, uint32_t tag, uint16_t *out_phys)
Write one generation of the test pattern and read it back verified.
static void demo_report_wear(void)
Print the FTL wear spread (max/min erase counts across physical blocks).
static ra8_io_blockdev_mram_state_t s_mstate
demo_addr_t
Extra-MRAM window base address.
@ k_demo_mram_base
Extra-MRAM OTP window base (0x02E07600).
static uint8_t s_ckbuf[(size_t) k_demo_block]
One-block checkpoint buffer (the reserved MRAM slot holds this).
static ra8_ftl_pblock_t s_pblocks[(size_t) k_demo_ftl_phys]
static uint16_t s_map[(size_t) k_demo_ftl_logical]
FTL caller storage: map, per-physical metadata, copy scratch.
static ra8_io_blockdev_t s_present
@ k_demo_test_lbn
Logical block written repeatedly.
@ k_demo_mrefreq_mhz
Extra-MRAM advertised clock (MHz).
@ k_demo_tag_base
First generation tag.
@ k_demo_block
Bytes per block.
@ k_demo_meta_lba
Reserved raw block for the checkpoint.
@ k_demo_writes
Repeated overwrites of the test block.
@ k_demo_lbn_mul
Test-pattern logical-block bias.
@ k_demo_ftl_logical
Logical blocks the FTL presents.
@ k_demo_ftl_phys
Physical blocks handed to the FTL.
@ k_demo_mrcfreq_mhz
Code-MRAM advertised clock (MHz).
@ k_demo_total_blocks
Whole extra MRAM (12 KiB).
@ k_demo_one_block
Single-block transfer count.
static void demo_report_map(uint32_t lbn, uint16_t phys)
Print logical L now at physical P for one relocation observation.
static ra8_err_t demo_open(void)
Bring up the MRAM controller and bind the raw MRAM block device.
static ra8_err_t demo_reopen_naive(void)
Act 3a: model a reset and prove the naive re-open lost the mapping.
static ra8_ftl_t s_ftl
FTL handle + the presented free-overwrite block device.
static ra8_err_t demo_wear_phase(uint32_t *migrations, uint16_t *last_phys)
Act 1: init the FTL and hammer one logical block to show migration.
static ra8_err_t demo_restore(uint32_t want_tag, uint16_t want_phys)
Act 3b: reload the checkpoint and prove data + mapping survived.
static ra8_err_t demo_checkpoint(void)
Act 2: serialise the FTL mapping into the reserved MRAM block.
static const char * s_tag
Logging / check tag.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
@ k_ra8_clock_id_pclka
PCLKA.
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_checksum_mismatch
Stored / transmitted checksum does not match computed value.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Code MRAM + Extra MRAM + Option-Setting driver – DANGEROUS, brick-capable.
ra8_err_t ra8_flash_init(const ra8_flash_cfg_t *cfg)
Initialise the MRAM controller for safe read access.
@ k_ra8_flash_extra_start
First legal Program target (FSBL setting).
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
Flash Translation Layer – free overwrite over erase-before-write media.
@ k_ra8_ftl_unmapped
map[] sentinel: logical block unwritten.
ra8_err_t ra8_ftl_checkpoint_load(ra8_ftl_t *ftl, const uint8_t *buf, uint32_t buf_len)
Restore FTL mapping state from a checkpoint produced by save.
ra8_err_t ra8_ftl_checkpoint_save(const ra8_ftl_t *ftl, uint8_t *buf, uint32_t buf_len)
Serialise the FTL's mapping state into a caller buffer.
ra8_err_t ra8_ftl_wear_stats(const ra8_ftl_t *ftl, uint32_t *max_out, uint32_t *min_out)
Report the highest per-physical-block erase count seen so far.
ra8_err_t ra8_ftl_init(ra8_ftl_t *bd, const ra8_io_blockdev_t *raw, uint16_t *map, uint32_t logical_blocks, ra8_ftl_pblock_t *pblocks, uint32_t physical_blocks, uint8_t *scratch)
Initialise an FTL over an erase-before-write block device.
ra8_err_t ra8_ftl_checkpoint_size(const ra8_ftl_t *ftl, uint32_t *size_out)
Report the buffer size a checkpoint of this FTL requires, in bytes.
ra8_err_t ra8_ftl_as_blockdev(ra8_ftl_t *ftl, ra8_io_blockdev_t *out)
Expose an initialised FTL as a free-overwrite ra8_io_blockdev_t.
ra8_err_t ra8_ftl_phys_of(const ra8_ftl_t *ftl, uint32_t lbn, uint16_t *phys_out)
Report the physical block currently backing a logical block.
@ k_ra8_psel_sci_async
00100b: SCI async serial (UART).
ra8_io – unified peripheral-agnostic I/O fabric (umbrella header).
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.
@ k_ra8_io_erase_value_ones
Block reads back as 0xFF after erase.
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_mram_init(ra8_io_blockdev_t *bd, ra8_io_blockdev_mram_state_t *state, uintptr_t base_addr, uint32_t block_count, bool read_only)
Bind a hard-fenced MRAM block-device backend into a caller handle.
ra8_err_t ra8_io_log_attach(ra8_io_stream_t *s)
Route ra8_log output to a bound ra8_io stream.
ra8_err_t ra8_io_stream_puts(ra8_io_stream_t *s, const char *str)
Write a NUL-terminated string (without the NUL) to the bound sink.
ra8_err_t ra8_io_stream_put_u32(ra8_io_stream_t *s, uint32_t value)
Write value as unsigned decimal ASCII (no leading zeros).
ra8_err_t ra8_io_stream_uart_init(ra8_io_stream_t *s, ra8_io_stream_uart_state_t *state, uint8_t channel)
Bind a UART stream sink into a caller-owned stream handle.
Lightweight Logging Interface for ra8-firmware.
void ra8_log_init(void)
Initialise the logging backend.
Typed Port / Pin Constants for the RA8D2 IOPORT Module.
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
@ k_ra8_port_13
RA8 port 13.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_pfs_route_peripheral(ra8_port_pin_t pin, ra8_psel_t psel, const char *owner)
Route a pin to a non-IRQ peripheral function via PFS.PSEL.
Full-featured Serial Communications Interface driver.
@ k_ra8_sci_stop_1
RA8 SCI stop 1.
@ k_ra8_sci_parity_none
RA8 SCI parity none.
ra8_err_t ra8_sci_init(uint8_t channel, const ra8_sci_cfg_t *cfg)
Initialise an SCI channel using the descriptor.
@ k_ra8_sci_data_8
RA8 SCI data 8.
ra8_err_t ra8_sci_flush(uint8_t channel)
Block until the channel's transmit shift register is empty.
SysTick-based tick counter, delay and timestamp helpers.
ra8_err_t ra8_time_init(uint32_t cpu_hz)
Initialise SysTick for a 1 kHz tick interrupt.
Initialisation descriptor for ra8_flash_init.
Caller-owned metadata for one physical erase block.
Caller-allocated FTL handle binding the wrapper to the raw device.
Caller-owned private state for an MRAM block device.
Caller-allocated block-device handle binding a backend to its context.
Caller-allocated byte-stream handle binding a sink to its context.
Caller-owned private state for a UART stream sink.
Configuration descriptor for ra8_sci_init.