|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
ThreadX-aware watchdog supervisor implementation. More...
#include "ra8_wdt_supervisor.h"#include <stdint.h>#include <string.h>#include "ra8_attributes.h"#include "ra8_err.h"#include "ra8_wdt.h"#include "tx_api.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_wdt_sup_slot_t |
| One row of the supervisor registry. More... | |
| struct | ra8_wdt_sup_state_t |
| Module state – entirely static. More... | |
Enumerations | |
| enum | ra8_wdt_sup_internal_t : uint32_t { k_ra8_wdt_sup_min_stack = 512U , k_ra8_wdt_sup_max_priority = 31U , k_ra8_wdt_sup_default_tick_ms = 1U , k_ra8_wdt_sup_slot_free = 0U , k_ra8_wdt_sup_slot_used = 1U , k_ra8_wdt_sup_mutex_id = 0x57445353U , k_ra8_wdt_sup_thread_id = 0x57445354U } |
| Internal numeric constants used by the implementation. More... | |
Functions | |
| static uint32_t | internal_default_now (void) |
| Default monotonic-time hook – scales tx_time_get to ms. | |
| static void | internal_default_refresh (void) |
| Default WDT-refresh hook. | |
| static ra8_err_t | internal_validate_cfg (const ra8_wdt_sup_cfg_t *cfg) |
| Validate the public configuration block. | |
| static bool | internal_is_overdue (uint32_t now, uint32_t last_checkin, uint32_t deadline) |
| Compute whether now - last_checkin exceeds deadline. | |
| static void | internal_thread_entry (ULONG arg) |
| The supervisor thread's entry point. | |
| ra8_err_t | ra8_wdt_supervisor_init (const ra8_wdt_sup_cfg_t *cfg) |
| Initialise the supervisor registry and runtime hooks. | |
| ra8_err_t | ra8_wdt_supervisor_deinit (void) |
| Reset the supervisor to its uninitialized state (test helper). | |
| static void | internal_fill_slot (uint8_t idx, const char *name, uint32_t deadline_ms) |
| Initialise an unused slot with the caller's parameters. | |
| ra8_err_t | ra8_wdt_supervisor_register_thread (const char *name, uint32_t deadline_ms, uint8_t *out_handle) |
| Register a worker thread with the supervisor. | |
| ra8_err_t | ra8_wdt_supervisor_checkin (uint8_t handle) |
| Record a thread check-in, resetting its deadline window. | |
| ra8_err_t | ra8_wdt_supervisor_start (void) |
| Spawn the supervisor thread. | |
| ra8_err_t | ra8_wdt_supervisor_tick (bool *out_did_refresh) |
| Run one supervisor tick synchronously (test / introspection hook). | |
| ra8_err_t | ra8_wdt_supervisor_set_now_hook (ra8_wdt_sup_now_fn_t now) |
| Override the monotonic-time hook (test injection point). | |
| ra8_err_t | ra8_wdt_supervisor_set_refresh_hook (ra8_wdt_sup_refresh_fn_t refresh) |
| Override the WDT-refresh hook (test injection point). | |
| uint8_t | ra8_wdt_supervisor_thread_count (void) |
| Read the number of currently-registered worker threads. | |
Variables | |
| static ra8_wdt_sup_state_t | s_state |
| Singleton module state. | |
ThreadX-aware watchdog supervisor implementation.
Static-allocation registry with a TX_MUTEX guard and a single TX_THREAD that wakes every refresh_period_ms. See ra8_wdt_supervisor.h for the design rationale.
Definition in file ra8_wdt_supervisor.c.
| enum ra8_wdt_sup_internal_t : uint32_t |
Internal numeric constants used by the implementation.
Definition at line 35 of file ra8_wdt_supervisor.c.
|
static |
Default monotonic-time hook – scales tx_time_get to ms.
Assumes a 1 kHz kernel tick (the most common ThreadX default for Cortex-M cores). Override via ra8_wdt_supervisor_set_now_hook if the kernel runs at a different rate.
| k_ra8_ok | Operation succeeded. |
Definition at line 98 of file ra8_wdt_supervisor.c.
References k_ra8_wdt_sup_default_tick_ms, RA8_INTERNAL, and tx_time_get.
Referenced by ra8_wdt_supervisor_init(), and ra8_wdt_supervisor_set_now_hook().
|
static |
Default WDT-refresh hook.
Wraps ra8_wdt_refresh_deferred so the test build can swap it out without pulling the WDT register layout into the unit test image.
Definition at line 118 of file ra8_wdt_supervisor.c.
References RA8_INTERNAL, and ra8_wdt_refresh_deferred().
Referenced by ra8_wdt_supervisor_init(), and ra8_wdt_supervisor_set_refresh_hook().
|
static |
Initialise an unused slot with the caller's parameters.
Helper extracted from ra8_wdt_supervisor_register_thread so the outer function fits the project size threshold (NASA Power-of-10 Rule 4 / clang-tidy readability-function-size). The caller MUST already hold s_state.mutex.
| [in] | idx | Index of a free slot in s_state.slots. |
| [in] | name | Caller-supplied thread name (NUL-terminated). |
| [in] | deadline_ms | Per-thread deadline in milliseconds. |
Definition at line 288 of file ra8_wdt_supervisor.c.
References k_ra8_wdt_sup_name_max, k_ra8_wdt_sup_slot_used, memset(), RA8_INTERNAL, and s_state.
Referenced by ra8_wdt_supervisor_register_thread().
|
static |
Compute whether now - last_checkin exceeds deadline.
Uses unsigned subtraction so 32-bit wrap-around is handled implicitly as long as the gap is < 2^31 ms (~24.8 days), which is always the case for the supervisor's ms-scale ticks.
| [in] | now | Current monotonic time (ms). |
| [in] | last_checkin | Time of slot's last check-in (ms). |
| [in] | deadline | Slot's deadline budget (ms). |
| k_ra8_ok | Operation succeeded. |
Definition at line 184 of file ra8_wdt_supervisor.c.
References RA8_INTERNAL.
Referenced by ra8_wdt_supervisor_tick().
|
static |
The supervisor thread's entry point.
Loops forever, sleeping refresh_period_ms between ticks. Each iteration calls ra8_wdt_supervisor_tick to evaluate the registry and conditionally refresh the WDT.
| [in] | arg | Unused (ThreadX entry-fn signature requires a ULONG). |
Definition at line 209 of file ra8_wdt_supervisor.c.
References RA8_INTERNAL, ra8_wdt_supervisor_tick(), s_state, and tx_thread_sleep.
Referenced by internal_h_thread_create(), ra8_wdt_supervisor_start(), and tx_application_define().
|
static |
Validate the public configuration block.
| [in] | cfg | Caller-supplied configuration. |
| k_ra8_err_null_ptr | cfg or cfg->stack was null. |
| k_ra8_err_invalid_arg | Stack too small / period zero / priority bad. |
See implementation.
Definition at line 141 of file ra8_wdt_supervisor.c.
References k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, k_ra8_wdt_sup_max_priority, k_ra8_wdt_sup_min_stack, ra8_wdt_sup_cfg_t::priority, RA8_INTERNAL, ra8_wdt_sup_cfg_t::refresh_period_ms, ra8_wdt_sup_cfg_t::stack, and ra8_wdt_sup_cfg_t::stack_size_bytes.
Referenced by ra8_wdt_supervisor_init().
|
nodiscard |
Record a thread check-in, resetting its deadline window.
Called by registered worker threads at known points in their loops (typically once per iteration, before any blocking call). Updates the slot's last_checkin_ms to the current monotonic time so the supervisor sees the thread as alive on its next tick.
| [in] | handle | Handle returned by ra8_wdt_supervisor_register_thread. |
| k_ra8_ok | Check-in recorded. |
| k_ra8_err_invalid_arg | handle is out of range. |
| k_ra8_err_not_found | handle refers to a free slot. |
| k_ra8_err_not_initialized | ra8_wdt_supervisor_init not called. |
Definition at line 342 of file ra8_wdt_supervisor.c.
References k_ra8_err_invalid_arg, k_ra8_err_not_found, k_ra8_err_not_initialized, k_ra8_err_rtos_error, k_ra8_ok, k_ra8_wdt_sup_max_threads, k_ra8_wdt_sup_slot_used, s_state, tx_mutex_get, tx_mutex_put, TX_SUCCESS, and TX_WAIT_FOREVER.
Referenced by internal_sys_thread_entry(), internal_ui_thread_entry(), worker_a_entry(), and worker_b_entry().
|
nodiscard |
Reset the supervisor to its uninitialized state (test helper).
Tears down the registry, deletes the mutex, and clears module state. Intended for unit tests that need a fresh slate between cases. Safe to call when never initialized.
| k_ra8_ok | Always succeeds. |
Definition at line 254 of file ra8_wdt_supervisor.c.
References k_ra8_ok, memset(), s_state, tx_mutex_delete, tx_thread_delete, and tx_thread_terminate.
|
nodiscard |
Initialise the supervisor registry and runtime hooks.
Validates cfg, zeroes the static registry, creates the registry mutex, and stores cfg for later use by ..._start. Does not spawn the supervisor thread yet – callers register their workers first, then call ra8_wdt_supervisor_start.
Algorithm:
| [in] | cfg | Pointer to a populated configuration block. |
| k_ra8_ok | Supervisor initialized, ready for register / start. |
| k_ra8_err_null_ptr | cfg was null or cfg->stack was null. |
| k_ra8_err_invalid_arg | Stack too small / period zero / bad priority. |
| k_ra8_err_busy | ra8_wdt_supervisor_init was already called. |
Definition at line 229 of file ra8_wdt_supervisor.c.
References internal_default_now(), internal_default_refresh(), internal_validate_cfg(), k_ra8_err_busy, k_ra8_err_rtos_error, k_ra8_ok, memset(), s_state, tx_mutex_create, TX_NO_INHERIT, and TX_SUCCESS.
Referenced by internal_wdt_setup(), and wdt_sup_demo_bring_up().
|
nodiscard |
Register a worker thread with the supervisor.
Allocates one of the k_ra8_wdt_sup_max_threads static slots, copies up to k_ra8_wdt_sup_name_max - 1 bytes of name for diagnostics, stamps the deadline budget, and primes last_checkin_ms to "now" so the first tick does not count the thread as overdue before it has had a chance to run.
| [in] | name | Short diagnostic name (must be NUL-terminated). |
| [in] | deadline_ms | Maximum allowed gap between consecutive check-ins, in milliseconds. Must be > 0. |
| [out] | out_handle | Receives the registered handle on success. |
| k_ra8_ok | Slot allocated, *out_handle populated. |
| k_ra8_err_null_ptr | name or out_handle was null. |
| k_ra8_err_invalid_arg | deadline_ms was zero. |
| k_ra8_err_no_mem | All slots are taken. |
| k_ra8_err_not_initialized | ra8_wdt_supervisor_init not called. |
Definition at line 306 of file ra8_wdt_supervisor.c.
References internal_fill_slot(), k_ra8_err_invalid_arg, k_ra8_err_no_mem, k_ra8_err_not_initialized, k_ra8_err_null_ptr, k_ra8_err_rtos_error, k_ra8_ok, k_ra8_wdt_sup_handle_invalid, k_ra8_wdt_sup_max_threads, k_ra8_wdt_sup_slot_free, s_state, tx_mutex_get, tx_mutex_put, TX_SUCCESS, and TX_WAIT_FOREVER.
Referenced by internal_wdt_setup(), and wdt_sup_demo_bring_up().
|
nodiscard |
Override the monotonic-time hook (test injection point).
Pass nullptr to restore the default ThreadX-tick reader. NASA Rule 9 deviation: function pointer used for Dependency Inversion.
| [in] | now | Replacement hook or nullptr. |
Definition at line 444 of file ra8_wdt_supervisor.c.
References internal_default_now(), k_ra8_ok, and s_state.
|
nodiscard |
Override the WDT-refresh hook (test injection point).
Pass nullptr to restore the default that calls ra8_wdt_refresh_deferred. NASA Rule 9 deviation: function pointer used for Dependency Inversion.
| [in] | refresh | Replacement hook or nullptr. |
Definition at line 450 of file ra8_wdt_supervisor.c.
References internal_default_refresh(), k_ra8_ok, and s_state.
Referenced by internal_wdt_setup().
|
nodiscard |
Spawn the supervisor thread.
Creates the supervisor's TX_THREAD with the stack region from cfg, then returns. The supervisor's loop:
| k_ra8_ok | Supervisor thread created. |
| k_ra8_err_not_initialized | ra8_wdt_supervisor_init not called. |
| k_ra8_err_busy | Already started. |
| k_ra8_err_rtos_thread_create | Underlying tx_thread_create failed. |
Definition at line 366 of file ra8_wdt_supervisor.c.
References internal_thread_entry(), k_ra8_err_busy, k_ra8_err_not_initialized, k_ra8_err_rtos_error, k_ra8_ok, s_state, TX_AUTO_START, TX_NO_TIME_SLICE, TX_SUCCESS, and tx_thread_create.
Referenced by internal_wdt_setup(), and wdt_sup_demo_bring_up().
| uint8_t ra8_wdt_supervisor_thread_count | ( | void | ) |
Read the number of currently-registered worker threads.
Diagnostic accessor for tests and dump helpers.
| k_ra8_ok | Operation succeeded. |
Definition at line 456 of file ra8_wdt_supervisor.c.
References k_ra8_wdt_sup_max_threads, k_ra8_wdt_sup_slot_used, and s_state.
|
nodiscard |
Run one supervisor tick synchronously (test / introspection hook).
Production builds run the same logic from the supervisor thread's loop. Exposing it as a callable function lets unit tests drive the supervisor without spinning a real ThreadX kernel and lets a host application probe "would I refresh right now?" out-of-band.
| [out] | out_did_refresh | Optional. Receives true if every registered thread was within deadline and the refresh hook was therefore called. |
| k_ra8_ok | Tick complete. |
| k_ra8_err_not_initialized | ra8_wdt_supervisor_init not called. |
Definition at line 393 of file ra8_wdt_supervisor.c.
References internal_is_overdue(), k_ra8_err_not_initialized, k_ra8_err_rtos_error, k_ra8_ok, k_ra8_wdt_sup_max_threads, k_ra8_wdt_sup_slot_used, s_state, tx_mutex_get, tx_mutex_put, TX_SUCCESS, and TX_WAIT_FOREVER.
Referenced by internal_thread_entry().
|
static |
Singleton module state.
Definition at line 77 of file ra8_wdt_supervisor.c.