|
Safe API Framework 0.1.0 build 384e6ae
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Real watchdog implementation: a fixed-size pool of watchdog slots, timed via the already-portable rte_timer_now() OAL primitive rather than any new OS-specific timing code of its own (REQ-OAL-COMMON-010: no dynamic allocation). More...
#include "rte/redundancy/watchdog/rte_watchdog.h"#include "rte/utils/lifecycle/rte_lifecycle.h"#include "rte/oal/log/rte_log.h"#include "rte/utils/safestate/rte_safestate.h"#include "rte/oal/timer/rte_timer.h"#include <stdbool.h>#include <string.h>Go to the source code of this file.
Data Structures | |
| struct | rte_watchdog_t |
| Watchdog handle (opaque). More... | |
Macros | |
| #define | RTE_WATCHDOG_MAX_COUNT 8U |
Functions | |
| static bool | is_valid_handle (rte_watchdog_t watchdog) |
| Defensive check that handle actually points at one of this module's own live pool slots, not an arbitrary caller pointer. | |
| static bool | is_valid_action (rte_watchdog_action_t action) |
| Checks whether action is one of the defined rte_watchdog_action_t enumerators. | |
| static bool | is_supervising (const rte_watchdog_s *slot) |
| Checks whether slot is currently supervising: allocated, started (not stopped) and not yet fired - i.e. a watchdog whose deadline rte_watchdog_timer_tick() must be able to compare against the clock. | |
| static uint32_t | first_supervising_index (void) |
| Finds the first supervising slot (see is_supervising()). | |
| rte_status_t | rte_watchdog_manager_initialize (void) |
| Initialize watchdog manager (call once at startup). | |
| rte_status_t | rte_watchdog_manager_shutdown (void) |
| Shutdown watchdog manager (call once at shutdown). | |
| rte_status_t | rte_watchdog_create (rte_watchdog_t *handle_out, const rte_watchdog_config_t *config) |
| Create a watchdog. | |
| rte_status_t | rte_watchdog_start (rte_watchdog_t watchdog) |
| Start watchdog timer. | |
| rte_status_t | rte_watchdog_stop (rte_watchdog_t watchdog) |
| Stop watchdog timer. | |
| rte_status_t | rte_watchdog_kick (rte_watchdog_t watchdog) |
| Kick (pet) watchdog - prove liveness. | |
| rte_status_t | rte_watchdog_get_status (rte_watchdog_t watchdog, rte_watchdog_status_t *status_out) |
| Get watchdog status. | |
| rte_status_t | rte_watchdog_destroy (rte_watchdog_t watchdog) |
| Destroy watchdog. | |
| void | rte_watchdog_timeout_handler (uint32_t watchdog_id) |
| Watchdog timeout handler (INTERNAL - called by framework). | |
| void | rte_watchdog_timer_tick (void) |
| Poll all active watchdogs for expiry (call periodically). | |
Variables | |
| static rte_watchdog_s | g_watchdog_pool [RTE_WATCHDOG_MAX_COUNT] |
| Fixed-size static pool backing every rte_watchdog_t handle. | |
| static uint8_t | g_manager_initialized = 0U |
| 1 once rte_watchdog_manager_initialize() has been called. | |
Real watchdog implementation: a fixed-size pool of watchdog slots, timed via the already-portable rte_timer_now() OAL primitive rather than any new OS-specific timing code of its own (REQ-OAL-COMMON-010: no dynamic allocation).
Timeout detection is polling-based: something (the application's own loop, or a periodic rte_timer callback) must call rte_watchdog_timer_tick() regularly for a fired watchdog to actually be detected - see that function's own doc for why a poll-driven design was chosen here over a true ISR/thread-driven one.
Replaces a previous stub where kick()/start()/get_status() were all no-ops and no timeout was ever detected (see git history) - discovered while wiring a real per-role watchdog into safeAPIRBC2oo2.
The time base is not trusted blindly (ISS-036): start()/kick()/ get_status() forward a failed rte_timer_now() status and leave the slot untouched (REQ-WATCHDOG-003), and rte_watchdog_timer_tick() treats a failed clock while any watchdog is supervising as a safe-state trigger (REQ-WATCHDOG-004) - a watchdog whose clock stands still can never expire, which would silently defeat the supervision it exists for.
Definition in file rte_watchdog.c.
| #define RTE_WATCHDOG_MAX_COUNT 8U |
Fixed pool size. rte_watchdog_create() returns RTE_STATUS_RESOURCE_EXHAUSTED once this many watchdogs are live at once - no dynamic growth, per this framework's no-malloc rule.
Definition at line 41 of file rte_watchdog.c.
|
static |
Defensive check that handle actually points at one of this module's own live pool slots, not an arbitrary caller pointer.
Pointer comparison against both ends of the same array object is well-defined in C (unlike comparing unrelated pointers).
| watchdog | Handle to validate. |
Definition at line 88 of file rte_watchdog.c.
|
static |
Checks whether action is one of the defined rte_watchdog_action_t enumerators.
| action | Value to validate. |
Definition at line 101 of file rte_watchdog.c.
|
static |
Checks whether slot is currently supervising: allocated, started (not stopped) and not yet fired - i.e. a watchdog whose deadline rte_watchdog_timer_tick() must be able to compare against the clock.
| slot | Pool slot to inspect (never NULL: callers index the pool). |
Definition at line 128 of file rte_watchdog.c.
|
static |
Finds the first supervising slot (see is_supervising()).
Returns an index, not the slot's name: config.name is a logging-only field that rte_watchdog_create() never validates, so a NULL name must change only the log text of the REQ-WATCHDOG-004 reaction, never the vital decision whether to react at all.
Definition at line 144 of file rte_watchdog.c.
|
static |
Fixed-size static pool backing every rte_watchdog_t handle.
Definition at line 69 of file rte_watchdog.c.
|
static |
1 once rte_watchdog_manager_initialize() has been called.
Definition at line 71 of file rte_watchdog.c.