|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Non-Secure main entry point: launches ThreadX and the e-reader UI. More...
#include <stdint.h>#include "ra8_attributes.h"#include "ra8_err.h"#include "ra8_nsc.h"#include "ra8_wdt_supervisor.h"#include "tx_api.h"Go to the source code of this file.
Typedefs | |
| typedef void(* | ns_exc_handler_t) (void) |
Enumerations | |
| enum | ns_scb_addr_t : uintptr_t { k_ns_scb_vtor_addr = 0xE000ED08U } |
| Address of NS VTOR register. More... | |
| enum | ns_thread_stack_t : uint32_t { k_ns_ui_thread_stack_size = 4096U , k_ns_sys_thread_stack_size = 2048U } |
| Stack sizes for Non-Secure ThreadX threads. More... | |
| enum | ns_log_cadence_t : uint32_t { k_ns_ui_heartbeat_frames = 60U , k_ns_sys_heartbeat_iters = 10U } |
| Heartbeat-log cadence per thread (iterations between log lines). More... | |
| enum | ns_thread_sleep_t : uint32_t { k_ns_ui_frame_ticks = 16U , k_ns_sys_poll_ticks = 100U } |
| Per-thread loop sleep period, in ThreadX ticks. More... | |
| enum | ns_thread_prio_t : uint32_t { k_ns_ui_priority = 10U , k_ns_sys_priority = 15U } |
| ThreadX priority + preemption threshold for each Non-Secure thread. More... | |
| enum | ns_wdt_param_t : uint32_t { k_ns_wdt_sup_stack_size = 1024U , k_ns_wdt_ui_deadline_ms = 500U , k_ns_wdt_sys_deadline_ms = 1000U , k_ns_wdt_refresh_ms = 50U } |
| Watchdog-supervisor sizing and timing parameters. More... | |
| enum | ns_wdt_prio_t : uint32_t { k_ns_wdt_sup_priority = 14U } |
| ThreadX priority for the watchdog supervisor thread. More... | |
Functions | |
| void | PendSV_Handler (void) |
| Perform the ThreadX Non-Secure context switch requested by PendSV. | |
| void | _tx_timer_interrupt (void) |
| Advance the ThreadX kernel timer by one hardware tick. | |
| static void | internal_systick_handler (void) |
| SysTick exception handler for the Non-Secure ThreadX OS. | |
| static void | internal_panic_halt (void) |
| Park the CPU in an idle loop if a fatal startup error occurs. | |
| static void | internal_ui_thread_entry (ULONG thread_input) |
| UI thread entry: runs the e-reader UI frame loop. | |
| static void | internal_sys_thread_entry (ULONG thread_input) |
| System supervisor and storage background thread. | |
| static void | internal_wdt_setup (void) |
| Arm the watchdog and start the ThreadX check-in supervisor. | |
| void | tx_application_define (void *first_unused_memory) |
| Setup ThreadX threads and resources. | |
| void | ns_reset_handler (void) |
| Non-Secure Reset handler: entered via Secure-to-NS transition. | |
| static void | internal_nmi_halt (void) |
| Default Non-Secure fault/NMI handler: park the CPU in a wfi halt. | |
Variables | |
| uint32_t | g_ra8_ls_ns_bss_start |
| uint32_t | g_ra8_ls_ns_bss_end |
| uint32_t | g_ra8_ls_ns_stack_top |
| uint32_t | g_ra8_ls_ns_run_start |
| static TX_THREAD | s_ui_thread |
| static TX_THREAD | s_sys_thread |
| static uint8_t | s_ui_thread_stack [k_ns_ui_thread_stack_size] |
| static uint8_t | s_sys_thread_stack [k_ns_sys_thread_stack_size] |
| static uint8_t | s_sup_stack [k_ns_wdt_sup_stack_size] |
| Supervisor thread stack (caller-owned, 8-byte aligned for ThreadX). | |
| static uint8_t | s_ui_wdt_handle = (uint8_t)k_ra8_wdt_sup_handle_invalid |
| Supervisor check-in handle for the UI thread. | |
| static uint8_t | s_sys_wdt_handle = (uint8_t)k_ra8_wdt_sup_handle_invalid |
| Supervisor check-in handle for the system thread. | |
| volatile uint32_t | g_ns_ui_frames = 0U |
| HIL liveness probe: UI-thread iteration count. | |
| volatile uint32_t | g_ns_sys_ticks = 0U |
| HIL liveness probe: system-thread iteration count. | |
| volatile uint32_t | g_ra8_threadx_systick_ready |
| 0 until _tx_initialize_low_level has armed ThreadX's SysTick + timer state; 1 afterwards. | |
| const ns_exc_handler_t | g_ra8_ns_vector_table [16] |
Non-Secure main entry point: launches ThreadX and the e-reader UI.
This file is executed after the Secure world bootloader configures the SAU and jumps to ns_reset_handler. It operates entirely in Non-Secure state, leveraging ThreadX for multitasking and calling Secure services via NSC veneers.
A ThreadX watchdog supervisor guards the workers: at start-up it arms the Secure-owned WDT through the ra8_nsc_wdt_start veneer, then refreshes it (through ra8_nsc_wdt_refresh) only while every worker thread keeps checking in within its deadline. If any thread wedges the supervisor stops kicking the WDT and it underflows. Expiry is routed to NMI in this build, so a wedge halts the system deterministically (context preserved for a debugger) instead of hanging silently; routing expiry to an internal reset for automatic reboot is a separate product decision.
Definition in file ns_main.c.
| enum ns_log_cadence_t : uint32_t |
Heartbeat-log cadence per thread (iterations between log lines).
Each thread logs a startup line once, then a periodic heartbeat so the serial / SWO log shows the system is alive without flooding it. The UI thread sleeps ~16 ms (~60 FPS) and the system thread ~100 ticks, so both cadences land near a one-second heartbeat.
| Enumerator | |
|---|---|
| k_ns_ui_heartbeat_frames | UI heartbeat every ~60 frames (~1 s). |
| k_ns_sys_heartbeat_iters | System heartbeat every ~10 loops (~1 s). |
| enum ns_scb_addr_t : uintptr_t |
| enum ns_thread_prio_t : uint32_t |
ThreadX priority + preemption threshold for each Non-Secure thread.
Lower numbers are higher priority. The UI thread runs ahead of the system thread so input/rendering stays responsive; each thread uses the same value for its priority and its preemption threshold.
| Enumerator | |
|---|---|
| k_ns_ui_priority | UI thread priority + preemption threshold. |
| k_ns_sys_priority | System thread priority + preemption threshold. |
| enum ns_thread_sleep_t : uint32_t |
Per-thread loop sleep period, in ThreadX ticks.
The UI thread sleeps ~16 ticks (~16 ms at a 1 kHz tick, ~60 FPS); the system thread sleeps ~100 ticks (~100 ms) since it only supervises. Every loop must sleep so the other threads get to run.
| Enumerator | |
|---|---|
| k_ns_ui_frame_ticks | UI loop sleep (~16 ms, ~60 FPS). |
| k_ns_sys_poll_ticks | System loop sleep (~100 ms cadence). |
| enum ns_thread_stack_t : uint32_t |
| enum ns_wdt_param_t : uint32_t |
Watchdog-supervisor sizing and timing parameters.
The supervisor refreshes the WDT every k_ns_wdt_refresh_ms only if both workers have checked in within their deadlines. The deadlines are generous multiples of each worker's loop period (UI ~16 ms, SYS ~100 ms) so ordinary slow work (a book load, an SD read) never false -trips the reset, while a genuine wedge is caught within the deadline.
| enum ns_wdt_prio_t : uint32_t |
ThreadX priority for the watchdog supervisor thread.
Sits between the UI (k_ns_ui_priority) and system (k_ns_sys_priority) workers: high enough to preempt the background system thread and refresh on time, low enough not to starve the UI.
| Enumerator | |
|---|---|
| k_ns_wdt_sup_priority | Supervisor thread priority. |
|
extern |
Advance the ThreadX kernel timer by one hardware tick.
The ThreadX Cortex-M port supplies this timer ISR worker. The local SysTick handler calls it only after the kernel readiness flag is set, allowing ThreadX delays, timers, and timed waits to advance.
References g_ra8_threadx_systick_ready.
Referenced by internal_systick_handler(), and ns_systick_handler().
|
static |
Default Non-Secure fault/NMI handler: park the CPU in a wfi halt.
Installed on the NMI, HardFault, and the other unhandled Non-Secure exception vectors. There is no recovery path, so it spins in a wfi loop and leaves the faulting context intact for a debugger.
Definition at line 491 of file ns_main.c.
References RA8_INTERNAL.
|
static |
Park the CPU in an idle loop if a fatal startup error occurs.
Spins forever issuing wfi so a Non-Secure bring-up failure halts deterministically (low power) instead of executing undefined state. Recovery requires an external reset.
noreturn). Definition at line 239 of file ns_main.c.
References RA8_INTERNAL.
Referenced by internal_wdt_setup(), ns_reset_handler(), and tx_application_define().
|
static |
System supervisor and storage background thread.
Lower-priority background worker for long-running, non-UI duties – SD card / filesystem setup, input polling, battery status, and OTA state. It runs an infinite supervisor loop, emitting a periodic heartbeat and sleeping each iteration so the UI thread stays responsive. It never returns.
| [in] | thread_input | ThreadX entry argument (unused; reserved by the API). |
Definition at line 296 of file ns_main.c.
References g_ns_sys_ticks, k_ns_sys_heartbeat_iters, k_ns_sys_poll_ticks, RA8_INTERNAL, ra8_nsc_log_emit(), ra8_wdt_supervisor_checkin(), s_sys_wdt_handle, and tx_thread_sleep.
Referenced by tx_application_define().
|
static |
SysTick exception handler for the Non-Secure ThreadX OS.
Drives the ThreadX timer: once the kernel is up (g_ra8_threadx_systick_ready set), each SysTick forwards into _tx_timer_interrupt to service timeouts and the time-slice. Before the kernel is ready the tick is ignored so an early SysTick cannot enter the scheduler.
g_ra8_threadx_systick_ready is set only after tx_kernel_enter. Definition at line 218 of file ns_main.c.
References _tx_timer_interrupt(), g_ra8_threadx_systick_ready, and RA8_INTERNAL.
|
static |
UI thread entry: runs the e-reader UI frame loop.
The Non-Secure UI thread. By the time ThreadX schedules it the Secure substrate, the TrustZone boundary, and logging (SCI8) are all up, so it drives the frame loop for the lifetime of the system: each iteration advances the frame counter, emits a heartbeat on the configured cadence, and yields so the other threads run. Never returns.
| [in] | thread_input | ThreadX entry argument (unused; reserved by the API). |
ra8_nsc_periph_init has completed (Secure services available). Definition at line 262 of file ns_main.c.
References g_ns_ui_frames, k_ns_ui_frame_ticks, k_ns_ui_heartbeat_frames, RA8_INTERNAL, ra8_nsc_log_emit(), ra8_wdt_supervisor_checkin(), s_ui_wdt_handle, and tx_thread_sleep.
Referenced by tx_application_define().
|
static |
Arm the watchdog and start the ThreadX check-in supervisor.
Runs once from tx_application_define, before the workers are created, and in this exact order: arm the Secure WDT via the ra8_nsc_wdt_start veneer; initialise the supervisor with a caller-owned stack; redirect its refresh hook to the ra8_nsc_wdt_refresh veneer (the library default would call the WDT directly, which faults in NS); register the UI and system workers with their deadlines; then start the supervisor thread. Any failure is unrecoverable this early, so it parks in internal_panic_halt.
Definition at line 333 of file ns_main.c.
References internal_panic_halt(), k_ns_wdt_refresh_ms, k_ns_wdt_sup_priority, k_ns_wdt_sup_stack_size, k_ns_wdt_sys_deadline_ms, k_ns_wdt_ui_deadline_ms, k_ra8_ok, RA8_INTERNAL, ra8_nsc_wdt_refresh(), ra8_nsc_wdt_start(), ra8_wdt_supervisor_init(), ra8_wdt_supervisor_register_thread(), ra8_wdt_supervisor_set_refresh_hook(), ra8_wdt_supervisor_start(), s_sup_stack, s_sys_wdt_handle, and s_ui_wdt_handle.
Referenced by tx_application_define().
| void ns_reset_handler | ( | void | ) |
Non-Secure Reset handler: entered via Secure-to-NS transition.
Slot 1 of the NS vector table and the NS image's linker entry symbol; the Secure boot BLXNS-es here. No header declares it because the only callers are the hardware vector fetch and the linker – the prototype below satisfies -Wmissing-prototypes for this externally-linked boot symbol.
Definition at line 431 of file ns_main.c.
References g_ra8_ls_ns_bss_end, g_ra8_ls_ns_bss_start, g_ra8_ls_ns_run_start, internal_panic_halt(), k_ns_scb_vtor_addr, k_ra8_ok, ra8_nsc_log_emit(), and ra8_nsc_periph_init().
|
extern |
Perform the ThreadX Non-Secure context switch requested by PendSV.
The ThreadX Cortex-M port supplies this exception entry point. The Non-Secure vector table references it directly so a pending context switch saves the outgoing thread and restores the scheduler-selected thread before exception return.
| void tx_application_define | ( | void * | first_unused_memory | ) |
Setup ThreadX threads and resources.
Definition at line 370 of file ns_main.c.
References internal_panic_halt(), internal_sys_thread_entry(), internal_ui_thread_entry(), internal_wdt_setup(), k_ns_sys_priority, k_ns_sys_thread_stack_size, k_ns_ui_priority, k_ns_ui_thread_stack_size, s_sys_thread, s_sys_thread_stack, s_ui_thread, s_ui_thread_stack, TX_AUTO_START, TX_NO_TIME_SLICE, TX_SUCCESS, and tx_thread_create.
| volatile uint32_t g_ns_sys_ticks = 0U |
HIL liveness probe: system-thread iteration count.
Bumped once per system-thread poll; see g_ns_ui_frames. A frozen value means the system thread wedged. Diagnostic only.
Definition at line 169 of file ns_main.c.
Referenced by internal_sys_thread_entry().
| volatile uint32_t g_ns_ui_frames = 0U |
HIL liveness probe: UI-thread iteration count.
Bumped once per UI frame. Read via J-Link (NS SRAM survives a connect) to confirm the NS world is alive and the watchdog supervisor is being fed – a frozen value means the UI thread wedged (and the WDT would then stop being refreshed). Diagnostic only.
Definition at line 160 of file ns_main.c.
Referenced by internal_ui_thread_entry().
|
extern |
|
extern |
|
extern |
|
extern |
| const ns_exc_handler_t g_ra8_ns_vector_table[16] |
|
extern |
0 until _tx_initialize_low_level has armed ThreadX's SysTick + timer state; 1 afterwards.
Set by the kernel once tx_initialize_low_level has run.
Read by the shared SysTick handler in libs/ra8_core/src/ra8_time.c.
Definition at line 58 of file tx_systick_ready.c.
|
static |
|
static |
Definition at line 67 of file ns_main.c.
Referenced by tx_application_define().
|
static |
Definition at line 70 of file ns_main.c.
Referenced by tx_application_define().
|
static |
Supervisor check-in handle for the system thread.
Definition at line 148 of file ns_main.c.
Referenced by internal_sys_thread_entry(), and internal_wdt_setup().
|
static |
|
static |
Supervisor check-in handle for the UI thread.
Definition at line 146 of file ns_main.c.
Referenced by internal_ui_thread_entry(), and internal_wdt_setup().