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

Chunked run loop + report implementation (see emu_run.h). More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "board_console.h"
#include "board_input.h"
#include "board_net.h"
#include "board_overlay.h"
#include "board_periph.h"
#include "board_periph_sd.h"
#include "board_usb.h"
#include "board_view.h"
#include "emu_console.h"
#include "emu_cpu1.h"
#include "emu_elf.h"
#include "emu_engine.h"
#include "emu_exc.h"
#include "emu_host_io_internal.h"
#include "emu_memmap.h"
#include "emu_mmio.h"
#include "emu_mpu.h"
#include "emu_prof.h"
#include "emu_run_internal.h"
#include "emu_seams.h"
#include "emu_usbh_seam.h"
#include "emu_view.h"
Include dependency graph for emu_run.c:

Go to the source code of this file.

Enumerations

enum  loop_action_t : uint8_t {
  k_loop_next = 0 ,
  k_loop_continue = 1 ,
  k_loop_break = 2
}
 Loop-control verdict a per-phase run-loop helper hands back. More...

Functions

static void internal_run_setup_geometry (const emu_run_cfg_t *cfg, run_loop_t *st)
 Derive the presentation geometry from the panel size and rotation.
static void internal_run_open_view (const emu_run_cfg_t *cfg, run_loop_t *st)
 Open the live window over the owned raw-fd surface when requested.
static void internal_run_classify_click (const emu_run_cfg_t *cfg, run_loop_t *st)
 Classify a headless –click into a tab / button / panel target once.
static void internal_run_loop_setup (const emu_run_cfg_t *cfg, run_loop_t *st)
 Populate the run state from the config before the chunk loop.
static loop_action_t internal_run_loop_prologue (run_loop_t *st)
 Run-loop prologue: wall-profiler charge, telemetry, warm reboots.
static void internal_run_loop_tick_inputs (run_loop_t *st)
 Arm the tick, advance time/peripherals, drain input, replay the click.
static loop_action_t internal_run_loop_run_chunk (run_loop_t *st)
 Run one chunk via priv_run_inner and service its post-chunk resets.
static void internal_run_loop_record (run_loop_t *st)
 Step cpu1 and dump a –record frame at the recording cadence.
static void internal_run_view_maybe_present (run_loop_t *st)
 Composite and present the live window at the ~60 Hz present cadence.
static loop_action_t internal_run_loop_view (run_loop_t *st)
 Handle live-window mouse input, presenting, and the close request.
static loop_action_t internal_run_loop_click_tail (run_loop_t *st)
 Run the bounded post-click tail and the CPU-time wall guard (headless).
static bool internal_run_stop_prof_idle (run_loop_t *st)
 Profiler compute-idle early-stop (insn mode, build-stable).
static bool internal_run_stop_idle (run_loop_t *st)
 Steady-state idle early-stop (RA8_EMU_IDLE_STOP).
static bool internal_run_stop_usb (run_loop_t *st)
 USB device- and host-mode enumeration early-stops.
static bool internal_run_stop_banner (run_loop_t *st)
 Generic console-banner early-stop (RA8_EMU_STOP_ON).
static bool internal_run_stop_sym (run_loop_t *st)
 –stop-sym watched-global early-stop.
static bool internal_run_stop_wall (run_loop_t *st)
 CPU-time wall-clock safety guard (headless plain run).
static loop_action_t internal_run_loop_headless (run_loop_t *st)
 Evaluate every headless plain-run early-stop in order.
static loop_action_t internal_run_loop_present_and_stops (run_loop_t *st)
 Dispatch the per-chunk output / stop phase by run mode.
static void internal_run_loop (run_loop_t *st)
 Drive the chunked run loop to a stop condition.
int emu_run_and_report (const emu_run_cfg_t *cfg)
 Run the firmware to a stop condition, print the report, map the exit code.

Detailed Description

Chunked run loop + report implementation (see emu_run.h).

The streamed-presentation setup, run-guard environment knobs, the chunked run loop with its inner exception-resolve loop, the run-end report and the exit-code mapping – moved verbatim out of the ra8_emulator main translation unit (the loop body is unchanged; the former main() locals it consumed now arrive through emu_run_cfg_t).

Since
0.1.0

Definition in file emu_run.c.

Enumeration Type Documentation

◆ loop_action_t

enum loop_action_t : uint8_t

Loop-control verdict a per-phase run-loop helper hands back.

The outer chunk loop is a sequence of phase helpers; each returns this so the driver can continue (a reboot / tail-chain that re-boots the chunk), break (a stop condition or fault), or fall through to the next phase without either.

Invariant
Exactly one value is returned per phase-helper call.
See also
internal_run_loop() The driver that dispatches on it.
Since
0.1.0
Enumerator
k_loop_next 

Fall through to the next phase in the body.

k_loop_continue 

Restart the outer loop (reboot / tail-chain).

k_loop_break 

Leave the outer loop (stop condition / fault).

Definition at line 60 of file emu_run.c.

Function Documentation

◆ emu_run_and_report()

int emu_run_and_report ( const emu_run_cfg_t * cfg)

Run the firmware to a stop condition, print the report, map the exit code.

Uses the caller-prepared raw-fd presentation surface (window / –ppm / –record / –click), reads the run-guard environment knobs, executes the chunked run loop – one SysTick period per outer chunk, exceptions resolved to a steady state by the inner loop, cpu1 interleaved, seven stop conditions – then prints the run-end report (stop cause, telemetry, peripheral summaries, MMIO table, –dump-sym probes), writes the –ppm / –record outputs, holds the live window until closed, saves the SD image, closes owned descriptors and the engine, and returns the #67 matrix exit code.

Parameters
[in]cfgThe setup products (see emu_run_cfg_t).
Returns
Process exit status.
Return values
0Clean run-to-budget (no fault / BKPT / timeout).
1Emulation fault / invalid access ended the run.
2Firmware executed a BKPT (assert / give-up).
3Wall-clock budget reached before a clean stop.
Precondition
cfg is fully populated and its engine is ready to run.
The seams / hooks are installed.
Postcondition
The engine and caller-owned ELF source are closed.
Note
Not thread-safe; this IS the single-threaded run.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 852 of file emu_run.c.

References internal_run_loop(), internal_run_loop_setup(), priv_run_cleanup(), priv_run_hold_view(), priv_run_report(), and priv_run_write_outputs().

Referenced by internal_main_run_loaded().

◆ internal_run_classify_click()

void internal_run_classify_click ( const emu_run_cfg_t * cfg,
run_loop_t * st )
static

Classify a headless –click into a tab / button / panel target once.

A click on the console tab bar switches the active console channel (a one-shot view change); an on-screen sidebar button toggles a user switch (fired once); anything else is a panel touch (re-armed until drained). The classification is resolved here so the loop just replays it.

Parameters
[in]cfgThe run configuration (–click coordinates + flag).
[in,out]stThe run state (click_was_tab / click_btn written).
Returns
void
Precondition
internal_run_setup_geometry has filled st->disp_w.
cfg and st are non-NULL.
Postcondition
st->click_was_tab and st->click_btn reflect the click target.
A tab click has already switched the active console channel.
Note
Not thread-safe; part of single-threaded setup.
Since
0.1.0

Definition at line 139 of file emu_run.c.

References board_overlay_hit_button(), board_overlay_hit_console_tab(), run_loop_t::click_btn, run_loop_t::click_was_tab, emu_run_cfg_t::click_x, emu_run_cfg_t::click_y, run_loop_t::disp_w, emu_view_select_console_tab(), k_board_console_ch_count, k_board_overlay_btn_none, priv_emu_io_errf(), RA8_INTERNAL, and emu_run_cfg_t::want_click.

Referenced by internal_run_loop_setup().

◆ internal_run_loop()

void internal_run_loop ( run_loop_t * st)
static

Drive the chunked run loop to a stop condition.

One SysTick period per outer chunk: prologue (profiler charge / telemetry / reboots), tick + inputs, the inner exception-resolve chunk, cpu1 step + record, then the mode-specific present / stop phase. Each phase hands back a loop_action_t the driver dispatches on.

Parameters
[in,out]stThe run state.
Returns
void
Precondition
st is fully initialized by internal_run_loop_setup.
The engine and seams are ready.
Postcondition
st holds the run's final PC, counters and stop-cause flags.
Note
Not thread-safe; this IS the single-threaded run.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 827 of file emu_run.c.

References run_loop_t::chunks, run_loop_t::guards, internal_run_loop_present_and_stops(), internal_run_loop_prologue(), internal_run_loop_record(), internal_run_loop_run_chunk(), internal_run_loop_tick_inputs(), k_loop_break, k_loop_continue, run_guards_t::max_chunks, and RA8_INTERNAL.

Referenced by emu_run_and_report().

◆ internal_run_loop_click_tail()

loop_action_t internal_run_loop_click_tail ( run_loop_t * st)
static

Run the bounded post-click tail and the CPU-time wall guard (headless).

After the headless –click input lands (a drained touch or a fired on-screen button) a bounded settle tail runs so the dumped frame shows the result, then stops; the CPU-time wall guard ends a run that overran.

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_breakThe settle tail expired or the wall guard fired.
k_loop_nextKeep draining the tail.
Precondition
st->view is NULL and –click is active.
st is initialized.
Postcondition
On a wall-guard stop, st->timed_out is true.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 518 of file emu_run.c.

References board_periph_touch_reported(), run_loop_t::button_fired, run_loop_t::click_btn, run_guards_t::click_settle_chunks, run_loop_t::guards, k_board_overlay_btn_none, k_loop_break, k_loop_next, RA8_INTERNAL, run_loop_t::settle_left, run_loop_t::t0, run_loop_t::timed_out, run_guards_t::wall_guard_on, and run_guards_t::wall_s.

Referenced by internal_run_loop_present_and_stops().

◆ internal_run_loop_headless()

loop_action_t internal_run_loop_headless ( run_loop_t * st)
static

Evaluate every headless plain-run early-stop in order.

Runs the profiler-idle, steady-idle, USB, banner, –stop-sym and wall-guard stops in the pre-split order; the first to fire ends the run. Each stop keeps its per-chunk side effects (counter updates), and short-circuit evaluation preserves that only the stops up to and including the firing one run this chunk – exactly as the original sequential breaks did.

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_breakAn early-stop fired.
k_loop_nextNo stop fired; proceed.
Precondition
st->view is NULL and –click is inactive (plain headless run).
st is initialized.
Postcondition
The stop-cause flag for the firing stop is set.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 773 of file emu_run.c.

References internal_run_stop_banner(), internal_run_stop_idle(), internal_run_stop_prof_idle(), internal_run_stop_sym(), internal_run_stop_usb(), internal_run_stop_wall(), k_loop_break, k_loop_next, and RA8_INTERNAL.

Referenced by internal_run_loop_present_and_stops().

◆ internal_run_loop_present_and_stops()

loop_action_t internal_run_loop_present_and_stops ( run_loop_t * st)
static

Dispatch the per-chunk output / stop phase by run mode.

A live window services mouse input and presents; a headless –click runs its settle tail; a plain headless run evaluates the early-stops.

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_breakA window close, settle-tail end, or early-stop fired.
k_loop_nextProceed to the next chunk.
Precondition
st is initialized.
The chunk has been run and recorded.
Postcondition
The relevant stop-cause / closed flag is set on k_loop_break.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 799 of file emu_run.c.

References run_loop_t::cfg, internal_run_loop_click_tail(), internal_run_loop_headless(), internal_run_loop_view(), RA8_INTERNAL, run_loop_t::view, and emu_run_cfg_t::want_click.

Referenced by internal_run_loop().

◆ internal_run_loop_prologue()

loop_action_t internal_run_loop_prologue ( run_loop_t * st)
static

Run-loop prologue: wall-profiler charge, telemetry, warm reboots.

Charges the previous chunk's wall time to its start PC (RA8_EMU_ PROFILE wall mode), publishes PC + chunk telemetry to the board view, then services a scheduled –reboot and any watchdog-requested reset by warm- rebooting the image (a failed reload ends the run).

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_continueA warm reboot happened; restart the outer loop.
k_loop_breakA warm reboot failed to reload the image.
k_loop_nextNo reboot; proceed to the chunk.
Precondition
st is initialized and its engine is ready.
st->run_pc holds the current resume PC.
Postcondition
On k_loop_continue, st->run_pc / last_boot_chunk are updated.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 213 of file emu_run.c.

References board_now_s(), board_periph_reset_set_cause(), board_periph_reset_take_request(), run_loop_t::cfg, run_loop_t::chunks, emu_run_cfg_t::elf, emu_prof_mode(), emu_view_publish(), k_loop_break, k_loop_continue, k_loop_next, k_prof_wall, k_reboot_settle, run_loop_t::last_boot_chunk, prof_add(), run_loop_t::prof_prev_pc, run_loop_t::prof_prev_t, RA8_INTERNAL, run_loop_t::reboot_count, run_loop_t::run_pc, emu_run_cfg_t::uc, emu_run_cfg_t::want_trace, and warm_reboot().

Referenced by internal_run_loop().

◆ internal_run_loop_record()

void internal_run_loop_record ( run_loop_t * st)
static

Step cpu1 and dump a –record frame at the recording cadence.

Interleaves one cpu1 step (a real second core sharing SRAM, not a model) with cpu0, then, every k_record_every chunks with –record active, composites the panel + sidebar and writes the next numbered PPM.

Parameters
[in,out]stThe run state.
Returns
void
Precondition
st is initialized and its engine is ready.
With –record, st->presentation owns an open raw surface.
Postcondition
cpu1 has advanced one step.
A recorded frame count reflects any PPM written this chunk.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

< Recorded-frame path: record_dir/frame_NNNNNN.ppm.

Definition at line 384 of file emu_run.c.

References build_composite(), run_loop_t::cfg, run_loop_t::chunks, emu_cpu1_step(), emu_presentation_workspace_t::fd, k_record_every, run_loop_t::presentation, RA8_INTERNAL, run_loop_t::rec_frames, emu_run_cfg_t::record_dir, emu_run_cfg_t::uc, emu_run_cfg_t::win_title, and write_ppm().

Referenced by internal_run_loop().

◆ internal_run_loop_run_chunk()

loop_action_t internal_run_loop_run_chunk ( run_loop_t * st)
static

Run one chunk via priv_run_inner and service its post-chunk resets.

Runs the inner exception-resolve loop, then ends the run on a fault or a profiler STOP_PC, or warm-reboots on an AIRCR.SYSRESETREQ (a failed reload ends the run). A successful software reset restarts the outer loop.

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_breakA fault, BKPT, STOP_PC, or failed reload ended it.
k_loop_continueA software reset warm-rebooted; restart the loop.
k_loop_nextThe chunk resolved cleanly; proceed.
Precondition
st is initialized and its engine is ready.
The seams / exception hooks are installed.
Postcondition
st->run_pc / err reflect the chunk's outcome.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 343 of file emu_run.c.

References board_periph_reset_set_cause(), run_loop_t::cfg, emu_run_cfg_t::elf, emu_exc_clear_reboot_request(), emu_exc_reboot_requested(), emu_prof_stop_hit(), run_loop_t::err, k_loop_break, k_loop_continue, k_loop_next, priv_run_inner(), run_loop_t::prof_stopped, RA8_INTERNAL, run_loop_t::run_pc, emu_run_cfg_t::uc, emu_run_cfg_t::vtor_base, emu_run_cfg_t::want_trace, and warm_reboot().

Referenced by internal_run_loop().

◆ internal_run_loop_setup()

void internal_run_loop_setup ( const emu_run_cfg_t * cfg,
run_loop_t * st )
static

Populate the run state from the config before the chunk loop.

Zeroes the mutable counters, derives the presentation geometry, opens the window over the bound surface, reads run guards, classifies a headless –click, and seeds the resume PC / reboot count / CPU-time origin.

Parameters
[in]cfgThe setup products (see emu_run_cfg_t).
[out]stThe run state to initialize.
Returns
void
Precondition
cfg is fully populated and st is non-NULL.
The engine referenced by cfg is ready to run.
Postcondition
st is fully initialized for the first chunk.
The window / presentation / guards / click are all resolved.
Note
Not thread-safe; this is the single-threaded setup entry.
Since
0.1.0

Definition at line 177 of file emu_run.c.

References run_loop_t::cfg, run_loop_t::click_btn, run_loop_t::err, run_loop_t::guards, run_loop_t::held_btn, emu_run_cfg_t::initial_pc, internal_run_classify_click(), internal_run_open_view(), internal_run_setup_geometry(), k_board_overlay_btn_none, RA8_INTERNAL, emu_run_cfg_t::reboot_count, run_loop_t::reboot_count, run_loop_t::run_pc, run_read_guards(), run_loop_t::t0, and run_loop_t::view.

Referenced by emu_run_and_report().

◆ internal_run_loop_tick_inputs()

void internal_run_loop_tick_inputs ( run_loop_t * st)
static

Arm the tick, advance time/peripherals, drain input, replay the click.

Arms the once-per-chunk SysTick, advances the DWT cycle counter and the modelled timers / network, drains buffered keystrokes into the console UART RX, and re-arms the headless –click (an on-screen button fires once; a panel touch is re-injected until the firmware drains it).

Parameters
[in,out]stThe run state.
Returns
void
Precondition
st is initialized and its engine is ready.
The seams / exception hooks are installed.
Postcondition
The tick is armed and one tick-period of peripheral time has advanced.
A pending headless click has been (re-)applied for this chunk.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

Definition at line 277 of file emu_run.c.

References apply_battery_click(), board_input_pop_key(), board_net_tick(), board_periph_sci_console_channel(), board_periph_sci_feed_rx(), board_periph_tick(), board_periph_touch_inject(), board_periph_touch_reported(), run_loop_t::button_fired, run_loop_t::cfg, run_loop_t::click_btn, run_loop_t::click_was_tab, emu_run_cfg_t::click_x, emu_run_cfg_t::click_y, run_loop_t::disp_w, dwt_cyccnt_advance(), emu_exc_arm_systick(), k_board_overlay_btn_batt_chg, k_board_overlay_btn_battery, k_board_overlay_btn_lowpower, k_board_overlay_btn_none, run_loop_t::panel_h, run_loop_t::panel_w, RA8_INTERNAL, emu_run_cfg_t::rotate_deg, set_switch(), emu_run_cfg_t::uc, unrotate_click(), and emu_run_cfg_t::want_click.

Referenced by internal_run_loop().

◆ internal_run_loop_view()

loop_action_t internal_run_loop_view ( run_loop_t * st)
static

Handle live-window mouse input, presenting, and the close request.

Mouse-down on an on-screen SW1/SW2 presses that momentary switch (a panel press arms one GT911 contact); a battery-slider press grabs the slider so a drag keeps setting the SOC; mouse-up releases the held switch and the grab; the wheel pages the console scrollback. Presents at the cadence and ends the run when the window is closed.

Parameters
[in,out]stThe run state.
Returns
The loop action for the driver.
Return values
k_loop_breakThe window was closed.
k_loop_nextThe window is still open; proceed.
Precondition
st->view is a live window.
st is initialized and its presentation surface is open.
Postcondition
On k_loop_break, st->closed is true.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 464 of file emu_run.c.

References apply_battery_click(), board_view_poll_click(), board_view_poll_drag(), board_view_poll_release(), board_view_poll_scroll(), board_view_pump(), run_loop_t::cfg, run_loop_t::chunks, run_loop_t::closed, run_loop_t::disp_w, emu_view_wheel(), run_loop_t::held_btn, internal_run_view_maybe_present(), k_board_overlay_btn_battery, k_board_overlay_btn_none, k_board_overlay_btn_sw1, k_board_overlay_btn_sw2, k_loop_break, k_loop_next, k_view_present_every, run_loop_t::panel_h, run_loop_t::panel_w, RA8_INTERNAL, emu_run_cfg_t::rotate_deg, route_click(), set_switch(), run_loop_t::slider_grab, and run_loop_t::view.

Referenced by internal_run_loop_present_and_stops().

◆ internal_run_open_view()

void internal_run_open_view ( const emu_run_cfg_t * cfg,
run_loop_t * st )
static

Open the live window over the owned raw-fd surface when requested.

–view opens a window using caller-owned handle storage and an immutable raw-fd snapshot per present. Failure preserves the established headless fallback; frame storage and bounded scratch were prepared by main.

Parameters
[in]cfgThe run configuration (output-mode flags + rotation).
[in,out]stThe run state (geometry read; view handle written).
Returns
void
Precondition
internal_run_setup_geometry has filled st geometry.
cfg and st are non-NULL.
Postcondition
st->view is a window handle or NULL (headless).
The bound presentation workspace remains unchanged.
Note
Not thread-safe; performs the platform window open during setup.
Since
0.1.0

Definition at line 111 of file emu_run.c.

References board_view_open(), run_loop_t::comp_h, run_loop_t::comp_w, priv_emu_io_errf(), RA8_INTERNAL, run_loop_t::view, run_loop_t::view_storage, emu_run_cfg_t::want_view, and emu_run_cfg_t::win_title.

Referenced by internal_run_loop_setup().

◆ internal_run_setup_geometry()

void internal_run_setup_geometry ( const emu_run_cfg_t * cfg,
run_loop_t * st )
static

Derive the presentation geometry from the panel size and rotation.

The firmware always renders panel_w x panel_h; –rotate 90/270 swap width and height for display, and the sidebar widens/heightens the displayed frame into the composite that both the window and –ppm show.

Parameters
[in]cfgThe run configuration (panel size + rotation).
[out]stThe run state whose geometry fields are filled.
Returns
void
Precondition
cfg and st are non-NULL.
cfg holds a valid panel size and rotation.
Postcondition
st panel/disp/comp dimensions are set consistently.
No allocation or engine state changes.
Note
Not thread-safe; part of single-threaded setup.
Since
0.1.0

Definition at line 83 of file emu_run.c.

References run_loop_t::comp_h, run_loop_t::comp_w, emu_presentation_workspace_t::composite_height, emu_presentation_workspace_t::composite_width, run_loop_t::disp_h, run_loop_t::disp_w, emu_presentation_workspace_t::display_height, emu_presentation_workspace_t::display_width, run_loop_t::panel_h, emu_presentation_workspace_t::panel_height, run_loop_t::panel_w, emu_presentation_workspace_t::panel_width, emu_run_cfg_t::presentation, run_loop_t::presentation, and RA8_INTERNAL.

Referenced by internal_run_loop_setup().

◆ internal_run_stop_banner()

bool internal_run_stop_banner ( run_loop_t * st)
static

Generic console-banner early-stop (RA8_EMU_STOP_ON).

Ends the run as soon as the stop substring appears on any of the three text endpoints – the UART last line, the ITM/SWO stimulus stream, or the SEGGER RTT up-buffer – so a ra8_log-only or RTT-only app stops the instant its verdict is emitted, exactly as for UART-banner apps.

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueThe stop substring appeared on a console endpoint.
falseSTOP_ON is unset or the substring has not appeared.
Precondition
st is initialized (headless plain run).
st->guards.stop_on is the substring or NULL.
Postcondition
st->usb_stopped is set true only when true is returned.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 674 of file emu_run.c.

References board_console_line(), board_periph_uart_last_line(), run_loop_t::guards, k_board_console_ch_itm, k_board_console_ch_rtt, RA8_INTERNAL, run_guards_t::stop_on, strstr(), and run_loop_t::usb_stopped.

Referenced by internal_run_loop_headless().

◆ internal_run_stop_idle()

bool internal_run_stop_idle ( run_loop_t * st)
static

Steady-state idle early-stop (RA8_EMU_IDLE_STOP).

All tracked counters (MMIO reads/writes, PendSV/SVCall, peripheral IRQs) are monotonic, so an unchanged sum for N consecutive chunks means the firmware reached steady-state idle and there is nothing left to run. Not evaluated while recording (which must span its full window).

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueThe idle signature held for idle_stop_chunks chunks.
falseIdle-stop off, recording, or the signature changed.
Precondition
st is initialized (headless plain run).
st->guards.idle_stop_chunks is the configured window.
Postcondition
st->idle_stopped is set true only when true is returned.
st->idle_sig_prev / idle_run track the idle streak.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

Definition at line 595 of file emu_run.c.

References board_periph_irq_total(), run_loop_t::cfg, emu_exc_pendsv_takes(), emu_exc_svc_takes(), emu_mmio_reads(), emu_mmio_writes(), run_loop_t::guards, run_loop_t::idle_run, run_loop_t::idle_sig_prev, run_guards_t::idle_stop_chunks, run_loop_t::idle_stopped, RA8_INTERNAL, and emu_run_cfg_t::record_dir.

Referenced by internal_run_loop_headless().

◆ internal_run_stop_prof_idle()

bool internal_run_stop_prof_idle ( run_loop_t * st)
static

Profiler compute-idle early-stop (insn mode, build-stable).

A chunk that retires very few instructions is an idle frame; after enough consecutive idle chunks (armed only after a warm-up) the firmware has reached its steady frame loop, so the profile spans boot, not the idle tail.

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueEnough consecutive profiler-idle chunks elapsed.
falseNot in insn-profile mode, recording, or not yet idle.
Precondition
st is initialized (headless plain run).
st->guards holds the profiler-idle thresholds.
Postcondition
st->prof_stopped is set true only when true is returned.
st->prof_idle_prev_i / prof_idle_run track the idle streak.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

Definition at line 556 of file emu_run.c.

References run_loop_t::cfg, run_loop_t::chunks, emu_prof_mode(), emu_prof_total_insns(), run_loop_t::guards, k_prof_insn, run_guards_t::prof_idle_arm, run_guards_t::prof_idle_insns, run_guards_t::prof_idle_need, run_loop_t::prof_idle_prev_i, run_loop_t::prof_idle_run, run_loop_t::prof_stopped, RA8_INTERNAL, and emu_run_cfg_t::record_dir.

Referenced by internal_run_loop_headless().

◆ internal_run_stop_sym()

bool internal_run_stop_sym ( run_loop_t * st)
static

–stop-sym watched-global early-stop.

Ends the run the instant the watched 32-bit global reaches its threshold (the jlink_memprobe counter floor). Checked at the chunk boundary like STOP_ON, so the stop is deterministic and host-load independent.

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueThe watched global reached its threshold.
false–stop-sym is off or the global is below the threshold.
Precondition
st is initialized (headless plain run).
st->cfg holds the resolved –stop-sym address + threshold.
Postcondition
st->stop_sym_hit is set true only when true is returned.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 711 of file emu_run.c.

References run_loop_t::cfg, emu_mem_read(), RA8_INTERNAL, emu_run_cfg_t::stop_sym_addr, run_loop_t::stop_sym_hit, emu_run_cfg_t::stop_sym_thresh, and emu_run_cfg_t::uc.

Referenced by internal_run_loop_headless().

◆ internal_run_stop_usb()

bool internal_run_stop_usb ( run_loop_t * st)
static

USB device- and host-mode enumeration early-stops.

USB device apps never go idle, so once the device reaches CONFIGURED a short settle window runs (for the first class traffic + report), then stops; the host-mode stop is kept distinct so a host app that also runs a device worker is not stopped by that worker reaching CONFIGURED first.

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueA USB device or host settle window elapsed.
falseBoth USB stops are off, recording, or not yet reached.
Precondition
st is initialized (headless plain run).
st->guards holds the USB settle windows.
Postcondition
st->usb_stopped is set true only when true is returned.
st->usb_stop_run / usbh_stop_run track the settle windows.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

Definition at line 635 of file emu_run.c.

References board_usb_configured(), run_loop_t::cfg, emu_usbh_done(), run_loop_t::guards, RA8_INTERNAL, emu_run_cfg_t::record_dir, run_loop_t::usb_stop_run, run_guards_t::usb_stop_settle, run_loop_t::usb_stopped, run_loop_t::usbh_stop_run, and run_guards_t::usbh_stop_settle.

Referenced by internal_run_loop_headless().

◆ internal_run_stop_wall()

bool internal_run_stop_wall ( run_loop_t * st)
static

CPU-time wall-clock safety guard (headless plain run).

Ends a run that has burned its CPU-time budget (clock(), so a heavily-loaded host trips it sooner). WALL_S=0 disables the guard (#168).

Parameters
[in,out]stThe run state.
Returns
true when the run should end here.
Return values
trueThe CPU-time budget was reached.
falseThe guard is disabled or the budget is not yet spent.
Precondition
st is initialized and st->t0 is the CPU-time origin.
st->guards holds the wall bound + enable.
Postcondition
st->timed_out is set true only when true is returned.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0
Postcondition
Ownership of caller-supplied storage is unchanged.

Definition at line 743 of file emu_run.c.

References run_loop_t::guards, RA8_INTERNAL, run_loop_t::t0, run_loop_t::timed_out, run_guards_t::wall_guard_on, and run_guards_t::wall_s.

Referenced by internal_run_loop_headless().

◆ internal_run_view_maybe_present()

void internal_run_view_maybe_present ( run_loop_t * st)
static

Composite and present the live window at the ~60 Hz present cadence.

Compositing + uploading the full panel + sidebar frame is the dominant host cost, so the live present is capped to ~60 Hz wall-clock; when a present is skipped the host CPU is yielded so an idle app does not spin a core redrawing identical frames.

Parameters
[in,out]stThe run state.
Returns
void
Precondition
st->view is live and its presentation surface is open.
st->chunks is a multiple of k_view_present_every.
Postcondition
Either a frame was presented or the host CPU was yielded.
st->last_present_us tracks the last present time.
Note
Not thread-safe; part of the single-threaded run loop.
Since
0.1.0

Definition at line 427 of file emu_run.c.

References board_view_present(), build_composite(), run_loop_t::cfg, k_ns_per_us, k_us_per_s, k_view_frame_us, k_view_yield_us, run_loop_t::last_present_us, run_loop_t::presentation, RA8_INTERNAL, emu_run_cfg_t::uc, run_loop_t::view, and emu_run_cfg_t::win_title.

Referenced by internal_run_loop_view().