ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1
37
38#include <stdint.h>
39#include <string.h>
40
41#include "ra8_board_ek_ra8d2.h"
42#include "ra8_boot_entry.h"
43#include "ra8_cgc.h"
44#include "ra8_err.h"
45#include "ra8_fs.h"
46#include "ra8_isr.h"
47#include "ra8_time.h"
48
49/*
50 * The host unit-test build (RA8_OFF_TARGET) does not link the ThreadX /
51 * LevelX vendor trees, so their headers are unreachable when clang-tidy
52 * walks this file. Pull them in only on the cross-compile target.
53 */
54#ifndef RA8_OFF_TARGET
55#include "lx_api.h"
56#include "lx_fs_backend.h"
58#include "tx_api.h"
59#endif
60
62typedef enum : uint32_t {
63 k_demo_baud = 115200U,
67
68#ifndef RA8_OFF_TARGET
70static const char s_readme_text[] = "ra8_fs FAT on OSPI flash via LevelX.\r\n";
71
73static const char s_readme_path[] = "/readme.txt";
74
76static const char s_scratch_path[] = "/scratch.txt";
77
78/* Statically-allocated control blocks (NASA P10 Rule 3 -- no dynamic memory). */
79static LX_NOR_FLASH s_nor_flash;
80
83
86
87/* Mutable name -- the ThreadX/LevelX APIs take non-const CHAR*. */
88static char s_lx_flash_name[] = "ra8_xspi_nor";
89#endif /* !RA8_OFF_TARGET */
90
98static void demo_panic_halt(void)
99{
100 while (1) {
101 __asm__ volatile("wfi");
102 }
103}
104
112static void demo_setup_or_halt(void)
113{
114 uint32_t cpuclk0_hz = 0U;
115
116 if (ra8_cgc_init() != k_ra8_ok) {
118 }
121 }
122 if (ra8_time_init(cpuclk0_hz) != k_ra8_ok) {
124 }
127 }
128}
129
137static void demo_print(const char* s)
138{
139 if (s == (const char*)0) {
140 return;
141 }
142 size_t len = strlen(s);
143 (void)ra8_board_uart_console_write((const uint8_t*)s, len);
144}
145
146#ifndef RA8_OFF_TARGET
155static void demo_fs_lock_acquire(void* ctx)
156{
158}
159
168static void demo_fs_lock_release(void* ctx)
169{
170 (void)tx_mutex_put((TX_MUTEX*)ctx);
171}
172
186static bool demo_lx_open(void)
187{
188 if (lx_nor_flash_format(&s_nor_flash,
191 LX_NULL) != LX_SUCCESS) {
192 demo_print("[fs] lx_nor_flash_format failed\r\n");
193 return false;
194 }
196 LX_SUCCESS) {
197 demo_print("[fs] lx_nor_flash_open failed\r\n");
198 return false;
199 }
200 return true;
201}
202
219static bool demo_fs_format_mount(ra8_fs_backend_t* out_backend, ra8_fs_mount_t** out_mount)
220{
221 if (lx_fs_backend_bind(&s_nor_flash, out_backend) != k_ra8_ok) {
222 demo_print("[fs] lx_fs_backend_bind failed\r\n");
223 return false;
224 }
225 ra8_fs_format_opts_t opts = {};
227 opts.label = "RA8FS";
228 if (ra8_fs_format(out_backend, &opts) != k_ra8_ok) {
229 demo_print("[fs] ra8_fs_format failed\r\n");
230 return false;
231 }
232 if (ra8_fs_mount(out_backend, out_mount) != k_ra8_ok) {
233 demo_print("[fs] ra8_fs_mount failed\r\n");
234 return false;
235 }
236 return true;
237}
238
250static bool demo_read_verify(ra8_fs_mount_t* mount, const char* path, const char* expected)
251{
252 ra8_fs_file_t* file = nullptr;
253 if (ra8_fs_open(mount, path, k_ra8_fs_mode_read, &file) != k_ra8_ok) {
254 demo_print("[fs] ra8_fs_open(read) failed\r\n");
255 return false;
256 }
257 uint8_t buf[k_demo_file_chunk];
258 uint32_t off = 0U;
259 bool ok = true;
260 uint32_t got = 0U;
261 do {
262 got = 0U;
263 if (ra8_fs_read(file, buf, (uint32_t)k_demo_file_chunk, &got) != k_ra8_ok) {
264 ok = false;
265 break;
266 }
267 if (got > 0U) {
268 if (memcmp(buf, &expected[off], (size_t)got) != 0) {
269 ok = false;
270 }
271 off += got;
272 }
273 } while (got > 0U);
274 (void)ra8_fs_close(file);
275 ok = ok && (off == (uint32_t)strlen(expected));
276 return ok;
277}
278
290static void demo_list_entry(const char* name, uint8_t attr, uint64_t size, void* ctx)
291{
292 (void)attr;
293 (void)size;
294 (void)ctx;
295 demo_print(" ");
296 demo_print(name);
297 demo_print("\r\n");
298}
299
311static void demo_file_ops(ra8_fs_mount_t* mount)
312{
313 const uint8_t* payload = (const uint8_t*)s_readme_text;
314 uint32_t len = (uint32_t)strlen(s_readme_text);
315 if (ra8_fs_write_file(mount, s_readme_path, payload, len) != k_ra8_ok) {
316 demo_print("[fs] ra8_fs_write_file failed\r\n");
317 return;
318 }
319 if (ra8_fs_write_file(mount, s_scratch_path, payload, len) != k_ra8_ok) {
320 demo_print("[fs] ra8_fs_write_file failed\r\n");
321 return;
322 }
323 demo_print("[fs] root listing:\r\n");
324 if (ra8_fs_listdir(mount, "/", demo_list_entry, nullptr) != k_ra8_ok) {
325 demo_print("[fs] ra8_fs_listdir failed\r\n");
326 return;
327 }
329 demo_print("[fs] readback mismatch\r\n");
330 return;
331 }
332 demo_print("[fs] readback verified\r\n");
333 if (ra8_fs_unlink(mount, s_scratch_path) != k_ra8_ok) {
334 demo_print("[fs] ra8_fs_unlink failed\r\n");
335 return;
336 }
337 ra8_fs_stat_t st = {};
338 if (ra8_fs_stat(mount, s_scratch_path, &st) != k_ra8_err_not_found) {
339 demo_print("[fs] delete did not remove the file\r\n");
340 return;
341 }
342 demo_print("[fs] ospi FAT roundtrip ok\r\n");
343}
344
353static void demo_thread_entry(ULONG thread_input)
354{
355 (void)thread_input;
356
357 demo_print("[fs] formatting + opening LevelX on OSPI flash\r\n");
358 if (!demo_lx_open()) {
359 return;
360 }
361 demo_print("[fs] formatting + mounting FAT volume\r\n");
362 ra8_fs_backend_t backend = {};
363 ra8_fs_mount_t* mount = nullptr;
364 if (!demo_fs_format_mount(&backend, &mount)) {
365 (void)lx_nor_flash_close(&s_nor_flash);
366 return;
367 }
368 demo_file_ops(mount);
369 (void)ra8_fs_unmount(mount);
370 (void)lx_nor_flash_close(&s_nor_flash);
371 demo_print("[fs] done\r\n");
372}
373
387void tx_application_define(void* first_unused_memory)
388{
389 static CHAR s_mutex_name[] = "ra8_fs";
390 static CHAR s_thread_name[] = "fs_demo";
391
392 (void)first_unused_memory;
393
394 lx_nor_flash_initialize();
395
396 (void)tx_mutex_create(&s_fs_mutex, s_mutex_name, TX_NO_INHERIT);
397 const ra8_fs_lock_t lock = {
398 .acquire = demo_fs_lock_acquire,
399 .release = demo_fs_lock_release,
400 .ctx = &s_fs_mutex,
401 };
402 if (ra8_fs_set_lock(&lock) != k_ra8_ok) {
403 demo_print("[fs] ra8_fs_set_lock failed\r\n");
404 }
405
409 0U,
411 (ULONG)sizeof(s_demo_stack),
412 8U, /* priority */
413 8U, /* preempt threshold */
416}
417#endif /* !RA8_OFF_TARGET */
418
426void main(void)
427{
430 demo_print("[fs] booting ThreadX + ra8_fs on OSPI flash...\r\n");
431
432#ifndef RA8_OFF_TARGET
433 tx_kernel_enter();
434#endif
435
437}
void main(void)
Secure fallback main entry point.
Definition main.c:37
static TX_THREAD s_demo_thread
Definition main.c:237
demo_config_t
Compile-time settings for the HTTPS client demo.
Definition main.c:87
@ k_demo_thread_stack
Demo thread stack.
Definition main.c:89
@ k_demo_baud
Demo baud.
Definition main.c:88
static UCHAR s_demo_stack[k_demo_thread_stack]
Definition main.c:238
void tx_application_define(void *first_unused_memory)
ThreadX system-define hook: build worker thread + byte pool.
Definition main.c:942
static LX_NOR_FLASH s_nor_flash
LevelX control block (statically allocated – NASA P10 Rule 3).
Definition main.c:76
static void demo_print(const char *msg)
Print a NUL-terminated string on the demo's UART stream.
Definition main.c:100
static void demo_setup_or_halt(void)
Bring up CGC + SysTick + the SCI8 console; halt forever on any failure.
Definition main.c:123
static void demo_panic_halt(void)
Halt forever in WFI – used as a panic stop on init failure.
Definition main.c:93
static CHAR s_thread_name[]
Definition main.c:212
static void demo_thread_entry(ULONG thread_input)
ThreadX worker entry: PSA + NetX up, connect, run the TLS session.
Definition main.c:731
static const char s_scratch_path[]
Path of the file that is deleted and confirmed gone.
Definition main.c:76
static bool demo_read_verify(ra8_fs_mount_t *mount, const char *path, const char *expected)
Read path back and verify its bytes equal expected.
Definition main.c:250
static void demo_fs_lock_acquire(void *ctx)
ra8_fs lock-seam acquire: block on the ThreadX mutex.
Definition main.c:155
static void demo_list_entry(const char *name, uint8_t attr, uint64_t size, void *ctx)
ra8_fs_listdir callback: print one root-directory entry name.
Definition main.c:290
static TX_MUTEX s_fs_mutex
ThreadX mutex the ra8_fs lock seam is bound to (#608).
Definition main.c:85
static void demo_fs_lock_release(void *ctx)
ra8_fs lock-seam release: hand the ThreadX mutex back.
Definition main.c:168
static void demo_file_ops(ra8_fs_mount_t *mount)
Run the file-ops sequence; print the pass banner only if all pass.
Definition main.c:311
@ k_demo_file_chunk
Read-back chunk for verification.
Definition main.c:65
static bool demo_fs_format_mount(ra8_fs_backend_t *out_backend, ra8_fs_mount_t **out_mount)
Bind the backend, lay down + mount a FAT volume on the LevelX partition.
Definition main.c:219
static const char s_readme_path[]
Path of the file that is read back and verified.
Definition main.c:73
static char s_lx_flash_name[]
Definition main.c:88
static const char s_readme_text[]
Test payload written into both demo files.
Definition main.c:70
static bool demo_lx_open(void)
Format + open the LevelX NOR partition on the OSPI flash.
Definition main.c:186
ra8_fs block-device backend over a LevelX wear-levelled NOR partition
ra8_err_t lx_fs_backend_bind(LX_NOR_FLASH *nor_flash, ra8_fs_backend_t *out)
Expose an open LevelX NOR flash as an ra8_fs block-device backend.
LevelX NOR-flash driver shim that bridges LevelX onto the RA8 ra8_xspi HAL (EK-RA8D2 ISSI IS25LX512M ...
UINT lx_nor_driver_ra8_xspi_initialize(LX_NOR_FLASH *nor_flash)
LevelX NOR driver-initialise entry point bridging onto ra8_xspi.
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
ra8_err_t ra8_board_uart_console_write(const uint8_t *data, size_t len)
Polled blocking write to the J-Link OB VCOM console.
ra8_err_t ra8_board_uart_console_init(uint32_t baud)
Configure SCI8 + PD02/PD03 as the debug-console UART.
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.
Definition ra8_cgc.c:132
@ k_ra8_clock_id_cpuclk0
Cortex-M85 CPUCLK0.
Definition ra8_cgc.h:70
ra8_err_t ra8_cgc_init(void)
Configure the clock tree to a safe default.
Definition ra8_cgc.c:727
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_not_found
Requested item not found (lookup / search missed).
Definition ra8_err.h:173
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
size_t strlen(const char *s)
Calculate string length.
Minimal FAT12/FAT16/FAT32 filesystem adapter (read + write).
ra8_err_t ra8_fs_format(const ra8_fs_backend_t *backend, const ra8_fs_format_opts_t *opts)
Format a block device as a fresh, empty FAT12/FAT16/FAT32/exFAT volume.
ra8_err_t ra8_fs_listdir(const ra8_fs_mount_t *handle, const char *path, ra8_fs_listdir_cb_t cb, void *ctx)
Enumerate directory entries; invoke cb once per visible entry.
ra8_err_t ra8_fs_mount(const ra8_fs_backend_t *backend, ra8_fs_mount_t **out_handle)
Mount a FAT volume from a block-device backend, auto-selecting the first partition.
ra8_err_t ra8_fs_read(ra8_fs_file_t *file, uint8_t *buf, uint32_t max_len, uint32_t *got_len)
Read up to max_len bytes; advance the cluster chain on cluster crossings.
ra8_err_t ra8_fs_stat(const ra8_fs_mount_t *handle, const char *path, ra8_fs_stat_t *out)
Report what a path names – file or directory – without opening it.
ra8_err_t ra8_fs_unlink(const ra8_fs_mount_t *handle, const char *path)
Delete a file: mark its dir entry deleted and free its clusters.
ra8_err_t ra8_fs_open(ra8_fs_mount_t *handle, const char *path, ra8_fs_mode_t mode, ra8_fs_file_t **out_file)
Open or create a file by path, 8.3 or long.
ra8_err_t ra8_fs_unmount(ra8_fs_mount_t *handle)
Unmount a previously mounted volume and release its slot.
ra8_err_t ra8_fs_close(ra8_fs_file_t *file)
Close an open file, stamping its final modification time.
ra8_err_t ra8_fs_write_file(ra8_fs_mount_t *handle, const char *path, const uint8_t *data, uint32_t len)
Create a whole file in one call (provisioning helper).
ra8_err_t ra8_fs_set_lock(const ra8_fs_lock_t *lock)
Install (or remove) the lock taken around every public ra8_fs call.
@ k_ra8_fs_type_fat12
count_of_clusters < 4085.
@ k_ra8_fs_mode_read
Read-only, must exist.
NVIC + ICU IELSR allocator.
void ra8_isr_globals_enable(void)
Globally enable maskable interrupts (PRIMASK = 0).
Definition ra8_isr.c:439
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.
Definition ra8_time.c:59
#define TX_NO_INHERIT
#define tx_thread_create
#define TX_NO_TIME_SLICE
#define tx_mutex_create
#define tx_mutex_put
char CHAR
ThreadX-compatible CHAR (host stub).
#define TX_AUTO_START
#define TX_WAIT_FOREVER
unsigned long ULONG
ThreadX-compatible unsigned long (host stub).
#define tx_mutex_get
Opaque mutex stand-in for the host build.
Opaque thread stand-in for the host build.
Block-device interface that ra8_fs runs on top of.
Open-file state.
Tunables for ra8_fs_format() (the on-disk geometry of a fresh volume).
ra8_fs_type_t type
FAT variant to lay down (12/16/32).
const char * label
0..11 char volume label, or NULL.
Dependency-injection seam for mutual exclusion around the public API.
Cached parse of one mounted FAT volume.
What ra8_fs_stat() read out of a directory entry.