|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
ra8_io fabric capstone: two block-dev backends swapped behind one interface, a VFS open/read/write/close round-trip, and stdio retargeted to both a UART and a RAM stream (epic #155, issue #264). More...
#include <stddef.h>#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_io.h"#include "ra8_log.h"#include "ra8_port_constants.h"#include "ra8_port_utils.h"#include "ra8_sci.h"#include "ra8_time.h"#include "ra8_xspi.h"Go to the source code of this file.
Data Structures | |
| struct | swap_backend_t |
| One row of the drop-in block-device swap table. More... | |
Enumerations | |
| enum | swap_const_t : uint32_t { k_swap_uart_chan = 8U , k_swap_uart_baud = 115200U , k_swap_pin_shift = 8U , k_swap_ram_blocks = 256U , k_swap_xspi_inst = 0U , k_swap_xspi_base = 0U , k_swap_xspi_blocks = 512U , k_swap_payload = 96U , k_swap_log_cap = 512U , k_swap_backends = 2U } |
| Console, volume, and payload knobs (no magic numbers). More... | |
| enum | swap_pattern_t : uint32_t { k_swap_pat_mul = 7U , k_swap_pat_add = 3U , k_swap_pat_xor = 0x5AU } |
| Deterministic payload-pattern coefficients (no magic numbers). More... | |
Functions | |
| static void | internal_swap_uart_print (const char *msg) |
| Print a NUL-terminated string on the UART console stream. | |
| static void | internal_swap_fill (uint32_t len) |
| Fill s_payload with the deterministic linear byte pattern. | |
| static ra8_err_t | internal_swap_vfs_write (const char *path, uint32_t len) |
Open a VFS path for writing, write len bytes, and close it. | |
| static ra8_err_t | internal_swap_vfs_read_verify (const char *path, uint32_t len) |
| Re-open a VFS path for reading and byte-compare against s_payload. | |
| static ra8_err_t | internal_swap_run_one (const swap_backend_t *b, uint32_t len, ra8_io_stream_t *log) |
| Run the identical FAT/VFS round-trip over one pre-bound block device. | |
| static ra8_err_t | internal_swap_replay_capture (uint32_t *out_used) |
| Replay the RAM-captured stdio out of the UART console. | |
| static ra8_err_t | internal_swap_run_all (const char **out_failed) |
| Bind both block-device backends and run the swap over the table. | |
| static void | internal_demo_setup_or_halt (void) |
| Bring up CGC + SysTick + the SCI8 console; halt forever on any failure. | |
| void | main (void) |
| Firmware entry point. | |
Variables | |
| static const ra8_port_pin_t | s_swap_txd |
| SCI8 console transmit pin, PD02. | |
| static const ra8_port_pin_t | s_swap_rxd |
| SCI8 console receive pin, PD03. | |
| static uint8_t | s_ram_disk [(size_t) k_swap_ram_blocks *(size_t) k_ra8_io_block_size_bytes] |
| 128 KiB RAM-disk backing buffer (in SRAM .bss). | |
| static ra8_io_blockdev_t | s_ram_bd |
| RAM block-device handle + its backend state. | |
| static ra8_io_blockdev_ram_state_t | s_ram_state |
| static ra8_io_blockdev_t | s_xspi_bd |
| xSPI (OSPI NOR) block-device handle + its backend state. | |
| static ra8_io_blockdev_xspi_state_t | s_xspi_state |
| static ra8_fs_backend_t | s_be |
| Reusable ra8_fs bridge (one mount is live at a time; reused per row). | |
| static ra8_io_stream_t | s_uart |
| UART output stream + its sink state (the serial console target). | |
| static ra8_io_stream_uart_state_t | s_uart_state |
| static ra8_io_stream_t | s_ram_log |
| In-RAM stdio capture stream + its sink state and backing buffer. | |
| static ra8_io_stream_ram_state_t | s_ram_log_state |
| static uint8_t | s_ram_log_buf [k_swap_log_cap] |
| static uint8_t | s_payload [k_swap_payload] |
| Deterministic write payload + read-back scratch (no heap; NASA Rule 3). | |
| static uint8_t | s_readback [k_swap_payload] |
| static const char *const | s_tag = "ra8_io_swap_demo" |
| Module log tag. | |
ra8_io fabric capstone: two block-dev backends swapped behind one interface, a VFS open/read/write/close round-trip, and stdio retargeted to both a UART and a RAM stream (epic #155, issue #264).
Where the sibling ra8_io_*_demo apps each bind ONE backend, this app is the capstone that shows off every ra8_io abstraction in a single binary:
ra8_emulator models both the RAM region and the OSPI NOR array, so the run is headless and observable over the SCI8 / J-Link OB VCOM console: a successful run prints ra8_io_swap_demo: two-backend swap (ram + xs) PASS. The OSPI RMW is slow in the emulator, so give ra8_emulator a generous instruction budget (see this app's README). It lives under hw_pending because the xSPI leg writes the non-volatile on-board NOR and has not yet been captured on the bench; the RAM, VFS, and stdio legs are fully exercised in ra8_emulator and in the host unit test tests/mocks/src/test_app_ra8_io_swap_demo.c.
Definition in file main.c.
| enum swap_const_t : uint32_t |
Console, volume, and payload knobs (no magic numbers).
Collects every literal the app uses so the magic-number gate stays silent and the sizing reads symbolically. The RAM volume is kept small (in-SRAM .bss) and the xSPI volume matches the sibling ra8_io_xspi_demo window; the payload fits inside one NOR sector so the erase-before-write round-trip stays cheap.
| Enumerator | |
|---|---|
| k_swap_uart_chan | SCI8 J-Link OB console. |
| k_swap_uart_baud | Console baud. |
| k_swap_pin_shift | Port byte position in ra8_port_pin_t. |
| k_swap_ram_blocks | 128 KiB in-SRAM RAM disk (FAT12). |
| k_swap_xspi_inst | xSPI controller instance index. |
| k_swap_xspi_base | Flash byte offset of logical block 0. |
| k_swap_xspi_blocks | 256 KiB OSPI NOR window (FAT12). |
| k_swap_payload | Bytes written + read back per backend. |
| k_swap_log_cap | RAM stdio-capture buffer capacity. |
| k_swap_backends | Number of block-device backends swapped. |
| enum swap_pattern_t : uint32_t |
Deterministic payload-pattern coefficients (no magic numbers).
The written bytes follow byte[i] = (i * mul + add) ^ xor so the read-back compare is a strong end-to-end check of the whole stack; a swapped or truncated buffer is caught byte-for-byte.
| Enumerator | |
|---|---|
| k_swap_pat_mul | Linear pattern multiplier. |
| k_swap_pat_add | Linear pattern additive bias. |
| k_swap_pat_xor | Linear pattern XOR mask. |
|
static |
Bring up CGC + SysTick + the SCI8 console; halt forever on any failure.
Initialises clocks, reads CPU/PCLKA rates, starts the millisecond time base, routes the SCI8 console pins, and opens the SCI8 UART. Any failure spins forever so a debugger can inspect the halt (there is no console yet to report on).
Definition at line 481 of file main.c.
References k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, k_ra8_psel_sci_async, k_ra8_sci_data_8, k_ra8_sci_parity_none, k_ra8_sci_stop_1, k_swap_uart_baud, k_swap_uart_chan, ra8_cgc_get_clock_hz(), ra8_cgc_init(), RA8_INTERNAL, ra8_pfs_route_peripheral(), ra8_sci_init(), ra8_time_init(), s_swap_rxd, and s_swap_txd.
|
static |
Fill s_payload with the deterministic linear byte pattern.
Writes byte[i] = (i * k_swap_pat_mul + k_swap_pat_add) ^ k_swap_pat_xor over the first len bytes so the read-back compare validates the whole fabric path with reproducible content.
| [in] | len | Number of bytes to fill (must be <= k_swap_payload). |
len is at most k_swap_payload. len bytes of s_payload hold the reproducible pattern. Definition at line 219 of file main.c.
References k_swap_pat_add, k_swap_pat_mul, k_swap_pat_xor, RA8_INTERNAL, and s_payload.
Referenced by internal_swap_run_one().
|
static |
Replay the RAM-captured stdio out of the UART console.
Reads the byte count captured by the in-RAM stdio sink and writes the captured bytes to the UART sink, bracketed by human-readable markers. This is the visible proof that the engine's identical stream calls were retargeted into RAM and can be re-emitted to a second destination.
| [out] | out_used | Receives the captured byte count on success. |
| k_ra8_ok | The capture was replayed and its length reported. |
| k_ra8_err_null_ptr | out_used was NULL. |
| (other) | The first failing stream step's code. |
Definition at line 387 of file main.c.
References internal_swap_uart_print(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_io_stream_ram_used(), ra8_io_stream_write(), RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, s_ram_log_buf, s_ram_log_state, s_tag, and s_uart.
Referenced by main().
|
static |
Bind both block-device backends and run the swap over the table.
Binds the in-SRAM RAM device and the OSPI NOR device (the only two per-medium bring-up lines), builds the two-row swap_backend_t table, and runs internal_swap_run_one over each row with the in-RAM stdio sink as the progress log. Stops at the first failing backend and reports which one.
| [out] | out_failed | Receives the name of the first failing backend, or NULL when every backend passed. |
| k_ra8_ok | Both backends round-tripped through the identical engine. |
| k_ra8_err_* | The first failing bind / round-trip step's code. |
out_failed is non-NULL. Definition at line 424 of file main.c.
References internal_swap_run_one(), k_ra8_ok, k_ra8_xspi_lio_1s1s1s, k_swap_backends, k_swap_payload, k_swap_ram_blocks, k_swap_xspi_base, k_swap_xspi_blocks, k_swap_xspi_inst, swap_backend_t::name, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_io_blockdev_ram_init(), ra8_io_blockdev_xspi_init(), RA8_RETURN_ON_ERROR, ra8_xspi_init(), s_ram_bd, s_ram_disk, s_ram_log, s_ram_state, s_tag, s_xspi_bd, and s_xspi_state.
Referenced by main().
|
static |
Run the identical FAT/VFS round-trip over one pre-bound block device.
The backend-agnostic engine, called once per swap_backend_t row. Bridges b->bd to ra8_fs, formats a FAT12 volume with b->label, mounts it, registers it in the VFS under b->name, writes then reads back len bytes at b->file, then unregisters and unmounts so the two shared mount slots are free for the next backend. Progress is emitted to log – the SAME calls land wherever log is bound.
| [in] | b | Backend row (device handle + FAT/VFS identity). |
| [in] | len | Payload length to round-trip (<= k_swap_payload). |
| [out] | log | Stream to write human-readable progress into. |
| k_ra8_ok | The volume mounted and the payload round-tripped. |
| k_ra8_err_null_ptr | b or log was NULL. |
| (other) | The first failing fabric step's code. |
b, b->bd, and log are non-NULL and the device is reachable. len is at most k_swap_payload. b->file holds the verified payload, then the mount is torn down (VFS name released, ra8_fs unmounted). Definition at line 334 of file main.c.
References internal_swap_fill(), internal_swap_vfs_read_verify(), internal_swap_vfs_write(), k_ra8_fs_type_fat12, k_ra8_ok, ra8_fs_format_opts_t::label, RA8_CHECK_NULL_PTR, ra8_fs_format(), ra8_fs_mount(), ra8_fs_unmount(), ra8_io_blockdev_as_fs_backend(), ra8_io_stream_put_u32(), ra8_io_stream_puts(), ra8_io_vfs_mount(), ra8_io_vfs_unmount(), RA8_RETURN_ON_ERROR, s_be, s_tag, and ra8_fs_format_opts_t::type.
Referenced by internal_swap_run_all().
|
static |
Print a NUL-terminated string on the UART console stream.
Thin wrapper over ra8_io_stream_puts bound to s_uart so call sites do not repeat the sink handle. Used only for the boot banner, the replay of the RAM capture, and the final verdict lines.
| [in] | msg | NUL-terminated ASCII string (CR/LF supplied by the caller). |
msg is non-NULL and NUL-terminated. msg are queued on the UART stream. Definition at line 195 of file main.c.
References RA8_INTERNAL, ra8_io_stream_puts(), and s_uart.
Referenced by internal_swap_replay_capture(), and main().
|
static |
Re-open a VFS path for reading and byte-compare against s_payload.
Read-back half of the round-trip: ra8_io_vfs_open(read) -> ra8_fs_read -> ra8_fs_close, then a single compound verdict on both the returned length and the byte content. The handle is closed on every path.
| [in] | path | Full "<name>:/..." VFS path to read. |
| [in] | len | Expected byte count (the length just written). |
| k_ra8_ok | Length and content both matched. |
| k_ra8_err_null_ptr | path was NULL. |
| k_ra8_err_checksum_mismatch | The read-back length or bytes differed. |
| (other) | The first failing VFS / ra8_fs step's code. |
path is non-NULL and its volume is mounted. len is at most k_swap_payload. path. Definition at line 287 of file main.c.
References k_ra8_err_checksum_mismatch, k_ra8_err_invalid_size, k_ra8_fs_mode_read, k_ra8_ok, k_swap_payload, memcmp(), memset(), RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, ra8_fs_close(), ra8_fs_read(), RA8_INTERNAL, ra8_io_vfs_open(), RA8_RETURN_ON_ERROR, s_payload, s_readback, and s_tag.
Referenced by internal_swap_run_one().
|
static |
Open a VFS path for writing, write len bytes, and close it.
Streaming write half of the round-trip: ra8_io_vfs_open(write) -> ra8_fs_write -> ra8_fs_close. The handle is closed on every path so no slot leaks even when the write itself fails.
| [in] | path | Full "<name>:/..." VFS path to create/truncate. |
| [in] | len | Byte count to write from s_payload. |
| k_ra8_ok | The payload was written and the handle closed. |
| k_ra8_err_null_ptr | path was NULL. |
| (other) | The first failing VFS / ra8_fs step's code. |
path is non-NULL and its volume is mounted. len is at most k_swap_payload. path holds the s_payload bytes. Definition at line 250 of file main.c.
References k_ra8_err_invalid_size, k_ra8_fs_mode_write, k_swap_payload, RA8_CHECK_NULL_PTR, RA8_CHECK_RANGE_TAG, ra8_fs_close(), ra8_fs_write(), RA8_INTERNAL, ra8_io_vfs_open(), RA8_RETURN_ON_ERROR, s_payload, and s_tag.
Referenced by internal_swap_run_one().
| void main | ( | void | ) |
Firmware entry point.
The application entry point Reset_Handler hands control to.
Brings up the console and both stdio sinks, retargets the engine's stdio to the in-RAM capture sink, runs the two-backend swap, replays the RAM capture out of the UART, and prints a single PASS/FAIL verdict per abstraction before parking in an infinite loop.
Definition at line 521 of file main.c.
References internal_demo_setup_or_halt(), internal_swap_replay_capture(), internal_swap_run_all(), internal_swap_uart_print(), k_ra8_ok, k_swap_log_cap, k_swap_uart_chan, ra8_io_log_attach(), ra8_io_stream_put_u32(), ra8_io_stream_ram_init(), ra8_io_stream_uart_init(), ra8_log_init(), ra8_sci_flush(), s_ram_log, s_ram_log_buf, s_ram_log_state, s_uart, and s_uart_state.
|
static |
|
static |
|
static |
RAM block-device handle + its backend state.
Definition at line 153 of file main.c.
Referenced by internal_swap_run_all().
|
static |
128 KiB RAM-disk backing buffer (in SRAM .bss).
Definition at line 151 of file main.c.
Referenced by internal_swap_run_all().
|
static |
In-RAM stdio capture stream + its sink state and backing buffer.
Definition at line 165 of file main.c.
Referenced by internal_swap_run_all(), and main().
|
static |
Definition at line 167 of file main.c.
Referenced by internal_swap_replay_capture(), and main().
|
static |
Definition at line 166 of file main.c.
Referenced by internal_swap_replay_capture(), and main().
|
static |
Definition at line 154 of file main.c.
Referenced by internal_swap_run_all().
|
static |
|
static |
SCI8 console receive pin, PD03.
Encodes the board port and pin in the HAL's packed pin identifier.
Definition at line 147 of file main.c.
Referenced by internal_demo_setup_or_halt().
|
static |
SCI8 console transmit pin, PD02.
Encodes the board port and pin in the HAL's packed pin identifier.
Definition at line 138 of file main.c.
Referenced by internal_demo_setup_or_halt().
|
static |
|
static |
|
static |
|
static |
xSPI (OSPI NOR) block-device handle + its backend state.
Definition at line 156 of file main.c.
Referenced by internal_swap_run_all().
|
static |