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
68
69#include <stddef.h>
70#include <stdint.h>
71
72#include "ra8_app.h"
73#include "ra8_attributes.h"
75#include "ra8_boot_entry.h"
76#include "ra8_cgc.h"
77#include "ra8_err.h"
78#include "ra8_log.h"
79#include "ra8_widget.h"
80
89typedef enum : uint32_t {
92
104static const uint8_t k_app_shell_pass_banner[] = "app_shell_demo: demo PASS\r\n";
105
129{
130 if (ra8_cgc_init() != k_ra8_ok) {
131 return false;
132 }
134 return false;
135 }
136 return true;
137}
138
157static void app_shell_hil_emit_pass(void)
158{
160 (size_t)(sizeof(k_app_shell_pass_banner) - 1U));
162}
163
178#ifndef APP_SHELL_SETTINGS
180#define APP_SHELL_SETTINGS (1)
181#endif
182
188typedef enum : uint16_t {
193
205
219typedef struct {
220 const char* name;
221 uint32_t inits;
222 uint32_t enters;
223 uint32_t leaves;
224 uint32_t renders;
225 uint32_t inputs;
226 uint32_t deinits;
228
237
246
254static uint16_t s_nav_stack[k_app_nav_cap];
255
264
272static app_shell_ctx_t s_library_ctx = {.name = "library"};
273
282
290static app_shell_ctx_t s_reader_ctx = {.name = "reader"};
291
300
301#if APP_SHELL_SETTINGS
309static app_shell_ctx_t s_settings_ctx = {.name = "settings"};
310
319#endif
320
321/* ===========================================================================
322 * Stub-app vtable callbacks (one shared vtable; behaviour keyed off ctx)
323 * ===========================================================================
324 */
325
339{
340 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
341 c->inits++;
342 ra8_log_info(c->name, "init");
343 return k_ra8_ok;
344}
345
357{
358 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
359 c->enters++;
360 ra8_log_info(c->name, "on_enter");
361}
362
374{
375 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
376 c->leaves++;
377 ra8_log_info(c->name, "on_leave");
378}
379
391static void app_stub_render(const ra8_app_t* a)
392{
393 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
394 c->renders++;
395 ra8_log_info(c->name, "render");
396}
397
413{
414 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
415 c->inputs++;
416 if (ev->kind != k_ra8_widget_ev_button) {
417 return false;
418 }
419 if (ev->button_id != (uint16_t)k_app_btn_back) {
420 return false;
421 }
422 ra8_log_info(c->name, "back requested");
423 return true;
424}
425
438{
439 app_shell_ctx_t* c = (app_shell_ctx_t*)a->ctx;
440 c->deinits++;
441 ra8_log_info(c->name, "deinit");
442}
443
454 .init = app_stub_init,
455 .on_enter = app_stub_on_enter,
456 .tick = nullptr,
457 .render = app_stub_render,
458 .on_input = app_stub_on_input,
459 .on_leave = app_stub_on_leave,
460 .deinit = app_stub_deinit,
461};
462
463/* ===========================================================================
464 * Registration + launcher + self-check (the "chrome")
465 * ===========================================================================
466 */
467
494static bool
495app_shell_add(ra8_app_t* app, app_shell_ctx_t* ctx, uint16_t id, const char* name, bool removable)
496{
497 *app =
498 (ra8_app_t){.vt = &k_app_stub_vt, .ctx = ctx, .id = id, .name = name, .removable = removable};
499 return (ra8_app_register(&s_reg, app) == k_ra8_ok);
500}
501
523static bool app_shell_register(void)
524{
526 return false;
527 }
529 return false;
530 }
531 bool ok =
532 app_shell_add(&s_library_app, &s_library_ctx, (uint16_t)k_app_id_library, "library", false);
533 if (ok) {
534 ok = app_shell_add(&s_reader_app, &s_reader_ctx, (uint16_t)k_app_id_reader, "reader", false);
535 }
536#if APP_SHELL_SETTINGS
537 if (ok) {
540 (uint16_t)k_app_id_settings,
541 "settings",
542 true);
543 }
544#endif
545 return ok;
546}
547
566static void app_shell_log_menu(void)
567{
568 uint16_t n = 0U;
569 (void)ra8_app_count(&s_reg, &n);
571 for (uint16_t i = 0U; i < n; i++) {
572 ra8_app_t* app = nullptr;
573 if (ra8_app_at(&s_reg, i, &app) == k_ra8_ok) {
574 if (app != nullptr) {
575 ra8_log_info_val(app->name, app->removable ? "removable" : "core", (uint32_t)app->id);
576 }
577 }
578 }
579}
580
603{
604 uint16_t depth = 1U;
607 return false;
608 }
609 if (ra8_app_render(&s_reg) != k_ra8_ok) {
610 return false;
611 }
612 if (s_library_ctx.enters != 1U) {
613 return false;
614 }
615 if (ra8_app_nav_depth(&s_nav, &depth) != k_ra8_ok) {
616 return false;
617 }
618 return (depth == 0U);
619}
620
644static bool app_shell_open_reader(void)
645{
646 uint16_t depth = 0U;
647 if (ra8_app_nav_go(&s_nav, (uint16_t)k_app_id_reader) != k_ra8_ok) {
648 return false;
649 }
650 if (ra8_app_render(&s_reg) != k_ra8_ok) {
651 return false;
652 }
653 if (s_library_ctx.leaves != 1U) {
654 return false;
655 }
656 if (s_reader_ctx.enters != 1U) {
657 return false;
658 }
659 const ra8_widget_event_t back = {.kind = k_ra8_widget_ev_button,
660 .button_id = (uint16_t)k_app_btn_back};
661 bool handled = false;
662 if (ra8_app_route_input(&s_reg, &back, &handled) != k_ra8_ok) {
663 return false;
664 }
665 if (!handled) {
666 return false;
667 }
668 if (s_reader_ctx.inputs != 1U) {
669 return false;
670 }
671 if (ra8_app_nav_depth(&s_nav, &depth) != k_ra8_ok) {
672 return false;
673 }
674 return (depth == 1U);
675}
676
677#if APP_SHELL_SETTINGS
700{
701 uint16_t depth = 0U;
702 bool popped = false;
703 if (ra8_app_nav_go(&s_nav, (uint16_t)k_app_id_settings) != k_ra8_ok) {
704 return false;
705 }
706 if (ra8_app_render(&s_reg) != k_ra8_ok) {
707 return false;
708 }
709 if (s_reader_ctx.leaves != 1U) {
710 return false;
711 }
712 if (s_settings_ctx.enters != 1U) {
713 return false;
714 }
715 if (ra8_app_nav_depth(&s_nav, &depth) != k_ra8_ok) {
716 return false;
717 }
718 if (depth != 2U) {
719 return false;
720 }
721 if (ra8_app_nav_back(&s_nav, &popped) != k_ra8_ok) {
722 return false;
723 }
724 if (!popped) {
725 return false;
726 }
727 if (s_settings_ctx.leaves != 1U) {
728 return false;
729 }
730 return (s_reader_ctx.enters == 2U);
731}
732#endif
733
755static bool app_shell_back_to_root(void)
756{
757 uint16_t depth = 0U;
758 bool popped = false;
759 if (ra8_app_nav_back(&s_nav, &popped) != k_ra8_ok) {
760 return false;
761 }
762 if (!popped) {
763 return false;
764 }
765 if (s_library_ctx.enters != 2U) {
766 return false;
767 }
768 if (ra8_app_nav_depth(&s_nav, &depth) != k_ra8_ok) {
769 return false;
770 }
771 return (depth == 0U);
772}
773
774#if APP_SHELL_SETTINGS
803{
804 /* Core app: uninstall must be refused and tear nothing down. */
806 return false;
807 }
808 if (s_library_ctx.deinits != 0U) {
809 return false;
810 }
811 /* Removable, background app: uninstall unmounts it (deinit fires). */
813 return false;
814 }
815 if (s_settings_ctx.deinits != 1U) {
816 return false;
817 }
819 if (ra8_app_state(&s_reg, (uint16_t)k_app_id_settings, &st) != k_ra8_ok) {
820 return false;
821 }
822 if (st != k_ra8_app_state_unmounted) {
823 return false;
824 }
825 uint16_t n = 0U;
826 if (ra8_app_count(&s_reg, &n) != k_ra8_ok) {
827 return false;
828 }
829 return (n == 2U); /* library + reader remain */
830}
831#endif
832
855static bool app_shell_selfcheck(void)
856{
858 return false;
859 }
860 if (!app_shell_open_reader()) {
861 return false;
862 }
863#if APP_SHELL_SETTINGS
865 return false;
866 }
867#endif
868 if (!app_shell_back_to_root()) {
869 return false;
870 }
871#if APP_SHELL_SETTINGS
873 return false;
874 }
875#endif
876 ra8_app_t* act = nullptr;
877 if (ra8_app_active(&s_reg, &act) != k_ra8_ok) {
878 return false;
879 }
880 if (act == nullptr) {
881 return false;
882 }
883 return (act->id == (uint16_t)k_app_id_library);
884}
885
904static void app_shell_banner(void)
905{
906 uint16_t n = 0U;
907 (void)ra8_app_count(&s_reg, &n);
908 ra8_log_info_val("app_shell", "apps", (uint32_t)n);
909 ra8_log_info_val("app_shell", "library enters", s_library_ctx.enters);
910 ra8_log_info("app_shell", "app_shell_demo PASS");
911 /* Additive HIL banner: the Pi rig has no ITM/SWO capture, so mirror the PASS
912 * verdict to the SCI8 / J-Link OB VCOM console for uart_scrape to gate. */
914}
915
925void main(void)
926{
927 ra8_log_init();
928 ra8_log_info("app_shell", "boot");
929
930 /* Bring up the VCOM console so the success path can emit the HIL banner.
931 * Best-effort: a failure is narrated over ITM and the demo continues. */
933 ra8_log_info("app_shell", "VCOM console init failed -- HIL banner unavailable");
934 }
935
936 bool ok = app_shell_register();
937 if (!ok) {
938 ra8_log_info("app_shell", "FAIL register");
939 }
940 if (ok) {
941 ok = app_shell_selfcheck();
942 if (!ok) {
943 ra8_log_info("app_shell", "FAIL selfcheck");
944 }
945 }
946 if (ok) {
948 }
949
950 while (1) {
951 __asm__ volatile("wfi");
952 }
953}
void main(void)
Secure fallback main entry point.
Definition main.c:37
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 ra8_app_nav_t s_nav
Navigation back-stack layered over s_reg.
Definition main.c:236
static ra8_app_t s_reader_app
The core reader app instance (registered into s_reg).
Definition main.c:254
static uint16_t s_nav_stack[k_app_nav_cap]
Caller-owned storage backing the navigation back-stack (app ids).
Definition main.c:227
@ k_app_id_settings
Optional settings app (removable).
Definition main.c:167
@ k_app_id_reader
Core EPUB-reader app (non-removable).
Definition main.c:166
static app_launch_ctx_t s_reader_ctx
Stub state for the core reader app.
Definition main.c:245
static app_launch_ctx_t s_settings_ctx
Stub state for the optional settings app.
Definition main.c:264
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 const ra8_app_vtable_t k_app_stub_vt
Shared lifecycle vtable for every stub app (behaviour keyed off ctx).
Definition main.c:364
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
static ra8_app_t s_settings_app
The optional settings app instance (registered into s_reg).
Definition main.c:273
@ k_app_btn_back
Button id a chrome routes to mean "go back".
Definition main.c:178
@ k_app_nav_cap
Back-stack depth (history of focused apps).
Definition main.c:177
@ k_app_reg_cap
Registry storage slots (reader + settings).
Definition main.c:176
app_shell_hil_t
VCOM-console line rate for the deterministic HIL success banner.
Definition main.c:89
@ k_app_shell_hil_baud
VCOM console line rate (8N1).
Definition main.c:90
static bool app_shell_uninstall_demo(void)
Exercise the run-time "core uninstallable" rule: refuse core, unmount one.
Definition main.c:802
static bool app_shell_register(void)
Initialise the registry + back-stack and register every app.
Definition main.c:523
static bool app_shell_hil_console_init(void)
Bring up the SCI8 / J-Link OB VCOM console for the HIL success banner.
Definition main.c:128
static void app_shell_hil_emit_pass(void)
Emit the deterministic HIL success banner over the VCOM console.
Definition main.c:157
static app_shell_ctx_t s_library_ctx
Stub state for the core library app.
Definition main.c:272
static ra8_app_t s_library_app
The core library app instance (registered into s_reg).
Definition main.c:281
static bool app_shell_back_to_root(void)
Press "back" to the root: pop to library and confirm the empty trail.
Definition main.c:755
static bool app_shell_open_reader(void)
Open reader from library, then route a back-button event to it.
Definition main.c:644
static void app_stub_deinit(ra8_app_t *a)
Stub deinit: count the teardown and log it (wired, not yet fired).
Definition main.c:437
app_shell_id_t
Registered app ids (launch keys).
Definition main.c:188
@ k_app_id_library
Core file/book organizer (non-removable).
Definition main.c:189
static ra8_err_t app_stub_init(ra8_app_t *a)
Stub init: count the one-time setup and log it (runs at register).
Definition main.c:338
static bool app_shell_settings_round_trip(void)
Open settings from reader, then go "back" to reader.
Definition main.c:699
static void app_shell_log_menu(void)
Log the launcher "menu": every registered app, its id, and its class.
Definition main.c:566
static void app_shell_banner(void)
Emit the PASS banner: app count, library enters, and the PASS line.
Definition main.c:904
static bool app_shell_launch_library(void)
Launcher: list the apps then launch library by its registry index.
Definition main.c:602
app_shell_const_t
Capacities, the launcher tile index, and the chrome button id.
Definition main.c:199
@ k_app_idx_library
Registry index of library (first registered).
Definition main.c:202
static bool app_shell_selfcheck(void)
Run the whole deterministic launcher + navigate + back-stack surface.
Definition main.c:855
static bool app_shell_add(ra8_app_t *app, app_shell_ctx_t *ctx, uint16_t id, const char *name, bool removable)
Build one app instance from the shared vtable and register it.
Definition main.c:495
static const uint8_t k_app_shell_pass_banner[]
Deterministic, run-to-run-stable HIL success banner (uart_scrape gate).
Definition main.c:104
Zero-heap app framework: lifecycle + static registry + launcher (#146).
ra8_err_t ra8_app_nav_init(ra8_app_nav_t *nav, ra8_app_registry_t *reg, uint16_t *storage, uint16_t cap)
Bind a navigation back-stack to a registry + caller-owned storage.
Definition ra8_app.c:186
ra8_err_t ra8_app_nav_back(ra8_app_nav_t *nav, bool *out_popped)
Return to the most recently pushed app (pop the back-stack).
Definition ra8_app.c:251
ra8_err_t ra8_app_register(ra8_app_registry_t *reg, ra8_app_t *app)
Register an app (calls its init once) and add it to the registry.
Definition ra8_app.c:48
ra8_err_t ra8_app_nav_go_index(ra8_app_nav_t *nav, uint16_t idx)
Focus the app at registry index idx (launcher select-by-position).
Definition ra8_app.c:238
ra8_err_t ra8_app_nav_go(ra8_app_nav_t *nav, uint16_t id)
Focus app id, pushing the outgoing app onto the back-stack.
Definition ra8_app.c:201
ra8_err_t ra8_app_count(const ra8_app_registry_t *reg, uint16_t *out_count)
Number of registered apps (for the launcher to list).
Definition ra8_app.c:166
ra8_err_t ra8_app_state(const ra8_app_registry_t *reg, uint16_t id, ra8_app_state_t *out_state)
Report an app's lifecycle state, derived from the registry.
Definition ra8_app.c:279
ra8_err_t ra8_app_at(const ra8_app_registry_t *reg, uint16_t idx, ra8_app_t **out_app)
Get the app at registry index idx (launcher enumeration).
Definition ra8_app.c:174
ra8_err_t ra8_app_uninstall(ra8_app_registry_t *reg, uint16_t id)
Uninstall (unmount) a removable, non-focused app from the registry.
Definition ra8_app.c:329
ra8_err_t ra8_app_route_input(ra8_app_registry_t *reg, const ra8_widget_event_t *ev, bool *out_handled)
Route an input event to the focused app.
Definition ra8_app.c:124
ra8_err_t ra8_app_nav_depth(const ra8_app_nav_t *nav, uint16_t *out_depth)
Current back-stack depth (apps the user can still go back through).
Definition ra8_app.c:270
ra8_err_t ra8_app_active(const ra8_app_registry_t *reg, ra8_app_t **out_app)
Get the currently focused app.
Definition ra8_app.c:115
ra8_err_t ra8_app_render(ra8_app_registry_t *reg)
Run the focused app's render (on-target; no-op if none / NULL).
Definition ra8_app.c:153
ra8_app_state_t
Lifecycle state of one app within the framework's state machine.
Definition ra8_app.h:115
@ k_ra8_app_state_foreground
Mounted and focused (the active app).
Definition ra8_app.h:118
@ k_ra8_app_state_unmounted
Not registered (initial / after uninstall).
Definition ra8_app.h:116
ra8_err_t ra8_app_registry_init(ra8_app_registry_t *reg, ra8_app_t **storage, uint16_t cap)
Bind a registry to caller-owned pointer storage (empty, no focus).
Definition ra8_app.c:20
Annotation-attribute framework macros for ra8-firmware.
#define RA8_LOOP_BOUND(ceiling)
NASA Power-of-10 Rule 2: bind ONE loop to a compile-time ceiling.
I/O-expander, USB, camera, external-memory, MIPI-DSI, UART console, and Ethernet portion of the EK-RA...
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.
ra8_err_t ra8_board_uart_console_flush(void)
Block until every byte queued on the J-Link OB VCOM console has finished clocking out on the wire.
Boot entry points shared between a vector table and its startup code.
High-level Clock Generation Circuit driver.
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_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
static const ra8_io_fsfmt_t * s_reg[(uint32_t) k_ra8_io_fsfmt_max]
Registered formats, in probe priority order.
static ra8_isr_slot_t s_slots[k_ra8_isr_slot_count]
Per-slot dispatch table.
Definition ra8_isr.c:77
Lightweight Logging Interface for ra8-firmware.
void ra8_log_init(void)
Initialise the logging backend.
Definition ra8_log.c:379
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
Zero-heap composable widget layer (dwm-style) over ra8_box + ra8_ui.
@ k_ra8_widget_ev_button
A physical button press (button_id).
Definition ra8_widget.h:70
Per-app stub state: a display name + lifecycle-call counters.
Definition main.c:219
const char * name
Display name + ITM log tag (non-NULL).
Definition main.c:220
uint32_t inits
Times init fired (at register).
Definition main.c:221
uint32_t inputs
Times on_input fired.
Definition main.c:225
uint32_t enters
Times on_enter fired.
Definition main.c:222
uint32_t leaves
Times on_leave fired.
Definition main.c:223
uint32_t deinits
Times deinit fired (teardown).
Definition main.c:226
uint32_t renders
Times render fired.
Definition main.c:224
A bounded back-stack of app ids layered over a registry (zero-heap).
Definition ra8_app.h:485
Fixed table of registered apps + the focused index.
Definition ra8_app.h:161
One app instance + its metadata (caller-owned, static).
App lifecycle callbacks (shared by all instances of one app).
Definition ra8_app.h:133
One input event delivered to ra8_widget_dispatch.
Definition ra8_widget.h:77
ra8_widget_ev_kind_t kind
Touch or button.
Definition ra8_widget.h:78
uint16_t button_id
Button id (for k_ra8_widget_ev_button).
Definition ra8_widget.h:80