ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
main.c File Reference

Minimal chrome stub: register apps + launch + back-stack (#146). More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_app.h"
#include "ra8_board_ek_ra8d2_peripherals.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_widget.h"
Include dependency graph for main.c:

Go to the source code of this file.

Data Structures

struct  app_launch_ctx_t
 Per-app stub state: a display name + lifecycle-call counters. More...

Macros

#define APP_LAUNCH_SETTINGS   (1)
 Build-time selector for the optional settings app (#146 exclusion).

Enumerations

enum  app_launch_hil_t : uint32_t { k_app_launch_hil_baud = 115200U }
 VCOM-console line rate for the deterministic HIL success banner. More...
enum  app_launch_id_t : uint16_t {
  k_app_id_reader = 1U ,
  k_app_id_settings = 2U
}
 Registered app ids (launch keys). More...
enum  app_launch_const_t : uint16_t {
  k_app_reg_cap = 2U ,
  k_app_nav_cap = 4U ,
  k_app_btn_back = 1U
}
 Capacities + the button id the stub apps understand. More...

Functions

static bool app_launch_hil_console_init (void)
 Bring up the SCI8 / J-Link OB VCOM console for the HIL success banner.
static void app_launch_hil_emit_pass (void)
 Emit the deterministic HIL success banner over the VCOM console.
static void app_stub_on_enter (ra8_app_t *a)
 Stub on_enter: count the focus gain and log it.
static void app_stub_on_leave (ra8_app_t *a)
 Stub on_leave: count the focus loss and log it.
static void app_stub_render (const ra8_app_t *a)
 Stub render: count the frame and log it (stands in for drawing).
static bool app_stub_on_input (ra8_app_t *a, const ra8_widget_event_t *ev)
 Stub on_input: count the event, consume only the "back" button.
static bool app_launch_register (void)
 Initialise the registry + back-stack and register every app.
static bool app_launch_enter_reader (void)
 Launch the reader app from the chrome and verify first focus.
static bool app_launch_route_back (void)
 Route a back-button event through the chrome to the active app.
static bool app_launch_switch_and_back (void)
 Switch reader -> settings and back, verifying the focus + back-stack.
static bool app_launch_selfcheck (void)
 Run the whole deterministic registry + launch + back-stack surface.
static void app_launch_banner (void)
 Emit the PASS banner: app count, reader enters, and the PASS line.
void main (void)
 App entry: register the apps, run the self-check, emit PASS, park.

Variables

static const uint8_t k_app_launch_pass_banner [] = "app_launch_demo: demo PASS\r\n"
 Deterministic, run-to-run-stable HIL success banner (uart_scrape gate).
static ra8_app_registry_t s_reg
 The app registry (single active app + membership table).
static ra8_app_ts_slots [k_app_reg_cap]
 Caller-owned storage backing the registry's app-pointer table.
static uint16_t s_nav_stack [k_app_nav_cap]
 Caller-owned storage backing the navigation back-stack (app ids).
static ra8_app_nav_t s_nav
 Navigation back-stack layered over s_reg.
static app_launch_ctx_t s_reader_ctx = {.name = "reader"}
 Stub state for the core reader app.
static ra8_app_t s_reader_app
 The core reader app instance (registered into s_reg).
static app_launch_ctx_t s_settings_ctx = {.name = "settings"}
 Stub state for the optional settings app.
static ra8_app_t s_settings_app
 The optional settings app instance (registered into s_reg).
static const ra8_app_vtable_t k_app_stub_vt
 Shared lifecycle vtable for every stub app (behaviour keyed off ctx).

Detailed Description

Minimal chrome stub: register apps + launch + back-stack (#146).

The first runnable increment of the app framework (#146). It proves the ra8_app registry + launcher + the navigation back-stack (ra8_app_nav_t) end-to-end on the real Cortex-M85 image – no display, no widgets, just the lifecycle and routing so the path is observable headlessly on ra8_emulator via the ITM log (each line shows up as [itm] ...).

What it does, acting as a tiny "chrome" / shell:

  1. Registers two stub apps into one registry:
    • reader (id 1) – a core, non-removable app (removable=false): the "core functionality should be able to be uninstalled" point from #146 says the optional apps are removable; the reader is core here.
    • settings (id 2) – an optional, removable app (removable=true), wrapped in a build-time guard (#if APP_LAUNCH_SETTINGS). Building with -DAPP_LAUNCH_SETTINGS=0 drops it from the registry entirely – the "core uninstallable" build-time-exclusion mechanism – and the demo still builds + runs (it just skips the switch/back leg).
  2. Launches reader from the chrome through ra8_app_nav_go (first focus, nothing pushed) and renders it.
  3. Switches to settings through ra8_app_nav_go – the focus lifecycle fires (reader.on_leave -> settings.on_enter) and reader is pushed onto the back-stack.
  4. Presses "back" through ra8_app_nav_backsettings leaves, reader re-enters, and the back-stack empties.

Each stub app is a function-pointer vtable (init / on_enter / tick / render / on_input / on_leave / deinit) plus the removable flag; the stubs just count their lifecycle calls and log them. A deterministic self-check asserts the exact call counts and back-stack depth at every step, then emits:

[app_launch] INFO: demo PASS (ra8_emulator: [itm] [app_launch] INFO: demo PASS)

so the app doubles as a ra8_emulator regression gate; any failure logs a FAIL ... line and parks in WFI.

[Ring 6 / APP] {World: S}

Since
0.1.0

Definition in file main.c.

Macro Definition Documentation

◆ APP_LAUNCH_SETTINGS

#define APP_LAUNCH_SETTINGS   (1)

Build-time selector for the optional settings app (#146 exclusion).

APP LAUNCH SETTINGS.

Defaults to 1 (settings shipped). Define it to 0 at configure time (-DAPP_LAUNCH_SETTINGS=0) to exclude the removable settings app from the registry, demonstrating the "core uninstallable" build-time-exclusion path: the firmware still builds and runs, with settings simply absent.

Note
Compile-time only; no run-time cost.
Since
0.1.0

Definition at line 157 of file main.c.

Enumeration Type Documentation

◆ app_launch_const_t

enum app_launch_const_t : uint16_t

Capacities + the button id the stub apps understand.

Since
0.1.0
Enumerator
k_app_reg_cap 

Registry storage slots (reader + settings).

k_app_nav_cap 

Back-stack depth (history of focused apps).

k_app_btn_back 

Button id a chrome routes to mean "go back".

Definition at line 175 of file main.c.

◆ app_launch_hil_t

enum app_launch_hil_t : uint32_t

VCOM-console line rate for the deterministic HIL success banner.

The EK-RA8D2 J-Link OB VCOM bridge (SCI8, PD02/PD03) runs 8N1 at this rate; the Pi HIL rig's uart_scrape reads /dev/ttyACM0 to gate the app. The banner is additive to the existing ra8_log ITM trace.

Since
0.1.0
Enumerator
k_app_launch_hil_baud 

VCOM console line rate (8N1).

Definition at line 67 of file main.c.

◆ app_launch_id_t

enum app_launch_id_t : uint16_t

Registered app ids (launch keys).

Since
0.1.0
Enumerator
k_app_id_reader 

Core EPUB-reader app (non-removable).

k_app_id_settings 

Optional settings app (removable).

Definition at line 165 of file main.c.

Function Documentation

◆ app_launch_banner()

void app_launch_banner ( void )
static

Emit the PASS banner: app count, reader enters, and the PASS line.

The app count proves the build-time exclusion (2 with settings, 1 without); the reader-enter count proves the back-stack returned focus.

Precondition
The self-check passed.
ra8_log_init has run (otherwise the lines are dropped).
Postcondition
Three [app_launch] INFO: ... lines are emitted (or dropped).
No app/registry state is modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 609 of file main.c.

References app_launch_hil_emit_pass(), ra8_app_count(), ra8_log_info, ra8_log_info_val, s_reader_ctx, and s_reg.

Referenced by main().

◆ app_launch_enter_reader()

bool app_launch_enter_reader ( void )
static

Launch the reader app from the chrome and verify first focus.

The first ra8_app_nav_go has no prior focus, so it pushes nothing: the back-stack stays empty and only reader.on_enter fires. Then the chrome renders the foreground app once.

Returns
true if reader entered exactly once with an empty back-stack.
Return values
trueenters == 1 and depth == 0 after the launch + render.
falseAny nav/render call failed or a counter mismatched.
Precondition
app_launch_register succeeded.
No app has been launched yet (counters are zero).
Postcondition
On true, reader is foreground and rendered once.
On false, the self-check aborts and main parks.
Note
Not thread-safe.
Since
0.1.0

Definition at line 447 of file main.c.

References k_app_id_reader, k_ra8_ok, ra8_app_nav_depth(), ra8_app_nav_go(), ra8_app_render(), s_nav, s_reader_ctx, and s_reg.

Referenced by app_launch_selfcheck().

◆ app_launch_hil_console_init()

bool app_launch_hil_console_init ( void )
static

Bring up the SCI8 / J-Link OB VCOM console for the HIL success banner.

Configures the clock tree (ra8_cgc_init, which publishes the PCLKA the SCI8 BRR divisor is computed from) then the EK-RA8D2 debug console (ra8_board_uart_console_init, SCI8 on PD02/PD03 at k_app_launch_hil_baud). Best-effort: a failure only means the additive HIL banner cannot reach the host; the existing ra8_log ITM trace and the demo logic are unaffected.

Returns
Whether the VCOM console is ready to carry the banner.
Return values
trueClock + SCI8 console are up.
falseA bring-up step failed (the banner is then silently skipped).
Precondition
Called once during bring-up, before the success banner is emitted.
ra8_log_init has run (failures are narrated over ITM).
Postcondition
On true, SCI8 is enabled (TE/RE) and PD02/PD03 route to it.
On false, no console state persists; the app continues normally.
Note
Not thread-safe; single-threaded init context.
Since
0.1.0

Definition at line 106 of file main.c.

References k_app_launch_hil_baud, k_ra8_ok, ra8_board_uart_console_init(), and ra8_cgc_init().

Referenced by main().

◆ app_launch_hil_emit_pass()

void app_launch_hil_emit_pass ( void )
static

Emit the deterministic HIL success banner over the VCOM console.

Writes k_app_launch_pass_banner to the SCI8 / J-Link OB VCOM console and flushes it so the bytes clock out before the CPU parks in WFI. A no-op if the console never came up (the write returns k_ra8_err_not_initialized, ignored).

Returns
Nothing.
Precondition
Reached only on the verified success path (single, non-compound guard).
app_launch_hil_console_init was attempted during bring-up.
Postcondition
The banner has been handed to SCI8 and the TX FIFO drained (if up).
No registry / app state is modified.
Note
Not thread-safe; single-threaded init context.
Since
0.1.0

Definition at line 135 of file main.c.

References k_app_launch_pass_banner, ra8_board_uart_console_flush(), and ra8_board_uart_console_write().

Referenced by app_launch_banner().

◆ app_launch_register()

bool app_launch_register ( void )
static

Initialise the registry + back-stack and register every app.

Binds s_reg and s_nav to their caller-owned storage, builds the core reader app (non-removable) and – when APP_LAUNCH_SETTINGS is on – the optional settings app (removable), and registers each. Any failure short- circuits to a false return so main can log and park.

Returns
true if the registry, back-stack, and all apps initialised.
Return values
trueEvery ra8_app_*_init / ra8_app_register returned k_ra8_ok.
falseSome init/register step failed.
Precondition
Called once from main before any launch.
The static app/ctx storage is zero-initialised (C startup).
Postcondition
On true, s_reg holds the shipped apps and s_nav is empty.
On false, s_reg may be partially populated (the caller parks).
Note
Not thread-safe (single-threaded init context).
Since
0.1.0

Definition at line 400 of file main.c.

References k_app_id_reader, k_app_id_settings, k_app_nav_cap, k_app_reg_cap, k_app_stub_vt, k_ra8_ok, ra8_app_nav_init(), ra8_app_register(), ra8_app_registry_init(), s_nav, s_nav_stack, s_reader_app, s_reader_ctx, s_reg, s_settings_app, s_settings_ctx, and s_slots.

Referenced by main().

◆ app_launch_route_back()

bool app_launch_route_back ( void )
static

Route a back-button event through the chrome to the active app.

Proves the "event" leg of the vtable: ra8_app_route_input delivers the event to the foreground app's on_input, which counts it and consumes the back button. Focus is unchanged (the stub just reports it handled the event).

Returns
true if the active app consumed the event and counted it once.
Return values
trueout_handled was true and reader.inputs == 1.
falseRouting failed, was not handled, or the counter mismatched.
Precondition
reader is the foreground app and has not yet seen an input.
The registry is initialised.
Postcondition
reader.inputs == 1; focus is unchanged.
On false, the self-check aborts and main parks.
Note
Not thread-safe.
Since
0.1.0

Definition at line 485 of file main.c.

References k_app_btn_back, k_ra8_ok, k_ra8_widget_ev_button, ra8_app_route_input(), s_reader_ctx, and s_reg.

Referenced by app_launch_selfcheck().

◆ app_launch_selfcheck()

bool app_launch_selfcheck ( void )
static

Run the whole deterministic registry + launch + back-stack surface.

Composes app_launch_enter_reader, the optional app_launch_switch_and_back (only when settings ships), and a final check that reader is the active app.

Returns
true if every step held.
Return values
trueAll sub-checks passed and reader is active.
falseSome sub-check failed.
Precondition
app_launch_register succeeded.
Called once, before the idle loop.
Postcondition
On true, reader is the foreground app.
On false, main logs a failure and parks.
Note
Not thread-safe.
Since
0.1.0

Definition at line 571 of file main.c.

References app_launch_enter_reader(), app_launch_route_back(), app_launch_switch_and_back(), k_app_id_reader, k_ra8_ok, ra8_app_active(), and s_reg.

Referenced by main().

◆ app_launch_switch_and_back()

bool app_launch_switch_and_back ( void )
static

Switch reader -> settings and back, verifying the focus + back-stack.

ra8_app_nav_go(settings) fires reader.on_leave then settings.on_enter and pushes reader (depth 1). ra8_app_nav_back pops it: settings.on_leave then reader.on_enter (reader's second enter), depth back to 0.

Returns
true if the full switch + back sequence matched the expected counts.
Return values
trueLifecycle counts and the popped flag all matched.
falseAny nav call failed or a counter / depth mismatched.
Precondition
app_launch_enter_reader succeeded (reader is foreground, depth 0).
APP_LAUNCH_SETTINGS is enabled (two apps are registered).
Postcondition
On true, reader is foreground again with an empty back-stack.
On false, the self-check aborts and main parks.
Note
Not thread-safe.
Since
0.1.0

Definition at line 520 of file main.c.

References k_app_id_settings, k_ra8_ok, ra8_app_nav_back(), ra8_app_nav_depth(), ra8_app_nav_go(), s_nav, s_reader_ctx, and s_settings_ctx.

Referenced by app_launch_selfcheck().

◆ app_stub_on_enter()

void app_stub_on_enter ( ra8_app_t * a)
static

Stub on_enter: count the focus gain and log it.

Parameters
[in,out]aThe app gaining focus (non-NULL, ctx is an app_launch_ctx_t).
Precondition
a and a->ctx are non-NULL.
Postcondition
The app's enters counter advanced by one.
One [name] INFO: on_enter line is emitted (or dropped if no ITM).
Note
Not thread-safe; called from the foreground switch path.
Since
0.1.0

Definition at line 290 of file main.c.

References app_launch_ctx_t::enters, app_launch_ctx_t::name, and ra8_log_info.

◆ app_stub_on_input()

bool app_stub_on_input ( ra8_app_t * a,
const ra8_widget_event_t * ev )
static

Stub on_input: count the event, consume only the "back" button.

Parameters
[in,out]aThe foreground app (non-NULL, ctx is an app_launch_ctx_t).
[in]evThe input event (non-NULL).
Returns
true if the event was the back button (consumed), false otherwise.
Return values
trueev is a k_app_btn_back button press.
falseAny other event (the chrome keeps routing it).
Precondition
a, a->ctx, and ev are non-NULL.
Postcondition
The app's inputs counter advanced by one.
On a back press one [name] INFO: back requested line is emitted.
Note
Not thread-safe.
Since
0.1.0

Definition at line 342 of file main.c.

References ra8_widget_event_t::button_id, app_launch_ctx_t::inputs, k_app_btn_back, k_ra8_widget_ev_button, ra8_widget_event_t::kind, app_launch_ctx_t::name, and ra8_log_info.

◆ app_stub_on_leave()

void app_stub_on_leave ( ra8_app_t * a)
static

Stub on_leave: count the focus loss and log it.

Parameters
[in,out]aThe app losing focus (non-NULL, ctx is an app_launch_ctx_t).
Precondition
a and a->ctx are non-NULL.
Postcondition
The app's leaves counter advanced by one.
One [name] INFO: on_leave line is emitted (or dropped).
Note
Not thread-safe.
Since
0.1.0

Definition at line 306 of file main.c.

References app_launch_ctx_t::leaves, app_launch_ctx_t::name, and ra8_log_info.

◆ app_stub_render()

void app_stub_render ( const ra8_app_t * a)
static

Stub render: count the frame and log it (stands in for drawing).

Parameters
[in]aThe foreground app (non-NULL, ctx is an app_launch_ctx_t).
Precondition
a and a->ctx are non-NULL.
Postcondition
The app's renders counter advanced by one.
One [name] INFO: render line is emitted (or dropped).
Note
Not thread-safe; the real on-target draw callback would live here.
Since
0.1.0

Definition at line 322 of file main.c.

References app_launch_ctx_t::name, ra8_log_info, and app_launch_ctx_t::renders.

◆ main()

void main ( void )

App entry: register the apps, run the self-check, emit PASS, park.

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR / FPU / priority grouping.
Postcondition
On success the PASS banner is emitted; otherwise a FAIL line is.
The CPU parks in WFI (observable on ra8_emulator until its budget).
Since
0.1.0

Definition at line 631 of file main.c.

References app_launch_banner(), app_launch_hil_console_init(), app_launch_register(), app_launch_selfcheck(), ra8_log_info, and ra8_log_init().

Variable Documentation

◆ k_app_launch_pass_banner

const uint8_t k_app_launch_pass_banner[] = "app_launch_demo: demo PASS\r\n"
static

Deterministic, run-to-run-stable HIL success banner (uart_scrape gate).

Emitted over the SCI8 / J-Link OB VCOM console only on the success path, AFTER the registry + launcher self-check passes. The ITM ra8_log verdict is left intact; this is purely additive so the Pi rig (which has no SWO / ITM capture) can gate the app.

Note
Trailing CRLF terminates the line on the wire; the gate matches the text.
Warning
Do not modify; the HIL gate (hil.conf HIL_EXPECT) matches it exactly.
Since
0.1.0

Definition at line 82 of file main.c.

Referenced by app_launch_hil_emit_pass().

◆ k_app_stub_vt

const ra8_app_vtable_t k_app_stub_vt
static
Initial value:
= {
.init = nullptr,
.on_enter = app_stub_on_enter,
.tick = nullptr,
.render = app_stub_render,
.on_input = app_stub_on_input,
.on_leave = app_stub_on_leave,
.deinit = nullptr,
}
static void app_stub_on_leave(ra8_app_t *a)
Stub on_leave: count the focus loss and log it.
Definition main.c:306
static void app_stub_on_enter(ra8_app_t *a)
Stub on_enter: count the focus gain and log it.
Definition main.c:290
static void app_stub_render(const ra8_app_t *a)
Stub render: count the frame and log it (stands in for drawing).
Definition main.c:322
static bool app_stub_on_input(ra8_app_t *a, const ra8_widget_event_t *ev)
Stub on_input: count the event, consume only the "back" button.
Definition main.c:342

Shared lifecycle vtable for every stub app (behaviour keyed off ctx).

init, tick, and deinit are unused here (NULL = no-op), proving the framework tolerates partial vtables.

Note
Read-only; lives in .rodata.
Since
0.1.0

Definition at line 364 of file main.c.

Referenced by app_launch_register(), and app_shell_add().

◆ s_nav

◆ s_nav_stack

uint16_t s_nav_stack[k_app_nav_cap]
static

Caller-owned storage backing the navigation back-stack (app ids).

Note
Bound to s_nav by ra8_app_nav_init.
Warning
Sized to k_app_nav_cap.
Since
0.1.0

Definition at line 227 of file main.c.

Referenced by app_launch_register(), and app_shell_register().

◆ s_reader_app

ra8_app_t s_reader_app
static

The core reader app instance (registered into s_reg).

Note
Built in app_launch_register.
Warning
Must outlive the registry (static storage).
Since
0.1.0

Definition at line 254 of file main.c.

Referenced by app_launch_register(), and app_shell_register().

◆ s_reader_ctx

app_launch_ctx_t s_reader_ctx = {.name = "reader"}
static

Stub state for the core reader app.

Note
Read/written by the reader app's vtable callbacks only.
Warning
Counters are asserted by the self-check; do not reset elsewhere.
Since
0.1.0

Definition at line 245 of file main.c.

Referenced by app_launch_banner(), app_launch_enter_reader(), app_launch_register(), app_launch_route_back(), app_launch_switch_and_back(), app_shell_open_reader(), app_shell_register(), and app_shell_settings_round_trip().

◆ s_reg

ra8_app_registry_t s_reg
static

The app registry (single active app + membership table).

Note
Mutated only from main (single-threaded init context).
Warning
Do not access from interrupt context.
Since
0.1.0

Definition at line 209 of file main.c.

◆ s_settings_app

ra8_app_t s_settings_app
static

The optional settings app instance (registered into s_reg).

Note
Compiled only when APP_LAUNCH_SETTINGS is enabled.
Warning
Must outlive the registry (static storage).
Since
0.1.0

Definition at line 273 of file main.c.

Referenced by app_launch_register(), and app_shell_register().

◆ s_settings_ctx

app_launch_ctx_t s_settings_ctx = {.name = "settings"}
static

Stub state for the optional settings app.

Note
Compiled only when APP_LAUNCH_SETTINGS is enabled.
Warning
Counters are asserted by the self-check.
Since
0.1.0

Definition at line 264 of file main.c.

Referenced by app_launch_register(), app_launch_switch_and_back(), app_shell_register(), app_shell_settings_round_trip(), and app_shell_uninstall_demo().

◆ s_slots

ra8_app_t* s_slots[k_app_reg_cap]
static

Caller-owned storage backing the registry's app-pointer table.

Note
Bound to s_reg by ra8_app_registry_init.
Warning
Sized to k_app_reg_cap; never indexed past s_reg.count.
Since
0.1.0

Definition at line 218 of file main.c.