Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
Watchdog Mechanism

Detect hung systems/tasks and trigger recovery. More...

Files

file  src/redundancy/watchdog/sapi_watchdog.c
 Real watchdog implementation: a fixed-size pool of watchdog slots, timed via the already-portable sapi_timer_now() OAL primitive rather than any new OS-specific timing code of its own (REQ-OAL-COMMON-010: no dynamic allocation).

Data Structures

struct  sapi_watchdog_config_t
 Watchdog configuration. More...
struct  sapi_watchdog_status_t
 Watchdog health/status information. More...

Enumerations

enum  sapi_watchdog_type_t { SAPI_WATCHDOG_SYSTEM , SAPI_WATCHDOG_TASK , SAPI_WATCHDOG_CHANNEL , SAPI_WATCHDOG_CHECKPOINT }
 Watchdog type. More...
enum  sapi_watchdog_action_t {
  SAPI_WATCHDOG_ACTION_LOG , SAPI_WATCHDOG_ACTION_SAFESTATE , SAPI_WATCHDOG_ACTION_REBOOT , SAPI_WATCHDOG_ACTION_FAILOVER ,
  SAPI_WATCHDOG_ACTION_CUSTOM
}
 Recovery action when watchdog fires. More...

Functions

sapi_status_t sapi_watchdog_create (sapi_watchdog_t *handle_out, const sapi_watchdog_config_t *config)
 Create a watchdog.
sapi_status_t sapi_watchdog_start (sapi_watchdog_t watchdog)
 Start watchdog timer.
sapi_status_t sapi_watchdog_stop (sapi_watchdog_t watchdog)
 Stop watchdog timer.
sapi_status_t sapi_watchdog_kick (sapi_watchdog_t watchdog)
 Kick (pet) watchdog - prove liveness.
sapi_status_t sapi_watchdog_get_status (sapi_watchdog_t watchdog, sapi_watchdog_status_t *status_out)
 Get watchdog status.
sapi_status_t sapi_watchdog_destroy (sapi_watchdog_t watchdog)
 Destroy watchdog.
sapi_status_t sapi_watchdog_manager_initialize (void)
 Initialize watchdog manager (call once at startup).
sapi_status_t sapi_watchdog_manager_shutdown (void)
 Shutdown watchdog manager (call once at shutdown).
void sapi_watchdog_timeout_handler (uint32_t watchdog_id)
 Watchdog timeout handler (INTERNAL - called by framework).
void sapi_watchdog_timer_tick (void)
 Poll all active watchdogs for expiry (call periodically).

Detailed Description

Detect hung systems/tasks and trigger recovery.

Enumeration Type Documentation

◆ sapi_watchdog_type_t

Watchdog type.

Defines what the watchdog is monitoring.

Enumerator
SAPI_WATCHDOG_SYSTEM 

Entire system liveness

SAPI_WATCHDOG_TASK 

Specific task/thread

SAPI_WATCHDOG_CHANNEL 

IPC/redundancy channel

SAPI_WATCHDOG_CHECKPOINT 

Checkpoint barrier

Definition at line 41 of file sapi_watchdog.h.

◆ sapi_watchdog_action_t

Recovery action when watchdog fires.

Defines what happens when watchdog timeout occurs.

Enumerator
SAPI_WATCHDOG_ACTION_LOG 

Log event only

SAPI_WATCHDOG_ACTION_SAFESTATE 

Trigger safe-state

SAPI_WATCHDOG_ACTION_REBOOT 

System reboot

SAPI_WATCHDOG_ACTION_FAILOVER 

Loss of a redundant peer/channel detected - invokes config->custom_action (same dispatch as SAPI_WATCHDOG_ACTION_CUSTOM; custom_action is required for this action too - see sapi_watchdog_create()). Use this over CUSTOM when the reason a watchdog exists is specifically "my redundant partner stopped responding" (e.g. a dual-channel cross-compare link) - the distinct name documents intent at the call site, even though the mechanism is identical to CUSTOM. REQ-WATCHDOG-002

SAPI_WATCHDOG_ACTION_CUSTOM 

Custom callback

Definition at line 53 of file sapi_watchdog.h.

Function Documentation

◆ sapi_watchdog_create()

sapi_status_t sapi_watchdog_create ( sapi_watchdog_t * handle_out,
const sapi_watchdog_config_t * config )

Create a watchdog.

Initializes a watchdog with specified configuration. Watchdog starts in disabled state; call sapi_watchdog_start() to enable.

Parameters
handle_outReceives watchdog handle
configWatchdog configuration
Returns
SAPI_STATUS_OK on success SAPI_STATUS_ERROR on failure
Precondition
config != NULL
Postcondition
watchdog is created but not started
Safety:
No dynamic memory allocation; all storage pre-allocated.

Example (system watchdog):

.name = "rbc_main_wd",
.timeout_ms = 1000,
};
sapi_watchdog_t wd;
sapi_watchdog_create(&wd, &config);
sapi_status_t sapi_watchdog_create(sapi_watchdog_t *handle_out, const sapi_watchdog_config_t *config)
Create a watchdog.
@ SAPI_WATCHDOG_SYSTEM
@ SAPI_WATCHDOG_ACTION_SAFESTATE
Watchdog configuration.

Definition at line 146 of file sapi_watchdog.c.

◆ sapi_watchdog_start()

sapi_status_t sapi_watchdog_start ( sapi_watchdog_t watchdog)

Start watchdog timer.

Enables watchdog monitoring. Countdown begins from timeout_ms. Must be called after sapi_watchdog_create().

Parameters
watchdogWatchdog handle
Returns
SAPI_STATUS_OK on success
Precondition
watchdog != NULL
Postcondition
watchdog is counting down; will fire if not kicked
Safety:
Deterministic: no blocking, no dynamic allocation

Definition at line 195 of file sapi_watchdog.c.

◆ sapi_watchdog_stop()

sapi_status_t sapi_watchdog_stop ( sapi_watchdog_t watchdog)

Stop watchdog timer.

Disables watchdog monitoring. No timeout will occur until restarted. Used during shutdown or maintenance.

Parameters
watchdogWatchdog handle
Returns
SAPI_STATUS_OK on success
Precondition
watchdog != NULL
Postcondition
watchdog is stopped; no timeout possible until start() called
Safety:
Deterministic; disarms watchdog

Definition at line 212 of file sapi_watchdog.c.

◆ sapi_watchdog_kick()

sapi_status_t sapi_watchdog_kick ( sapi_watchdog_t watchdog)

Kick (pet) watchdog - prove liveness.

Resets timeout countdown. Must be called periodically (before timeout expires) to prevent watchdog from firing.

Typical usage: called in main event loop, task loop, or after checkpoint.

Parameters
watchdogWatchdog handle
Returns
SAPI_STATUS_OK on success (countdown reset) SAPI_STATUS_ERROR if watchdog already fired (recovery in progress)
Precondition
watchdog != NULL
Postcondition
timeout countdown reset to timeout_ms
Safety:
Deterministic: no blocking, O(1) time

Example:

while (running) {
process_events();
sapi_watchdog_kick(wd); // Prove we're alive
}
sapi_status_t sapi_watchdog_kick(sapi_watchdog_t watchdog)
Kick (pet) watchdog - prove liveness.

Definition at line 224 of file sapi_watchdog.c.

◆ sapi_watchdog_get_status()

sapi_status_t sapi_watchdog_get_status ( sapi_watchdog_t watchdog,
sapi_watchdog_status_t * status_out )

Get watchdog status.

Non-blocking query of watchdog state (kicks, fires, time remaining). Useful for health monitoring and diagnostics.

Parameters
watchdogWatchdog handle
status_outReceives watchdog status
Returns
SAPI_STATUS_OK on success
Precondition
watchdog != NULL, status_out != NULL
Postcondition
status_out populated with current watchdog state
Safety:
Non-blocking, read-only, no side effects

Example:

printf("Watchdog: %u kicks, %u fires, %u ms until timeout\n",
status.kicks, status.fires, status.time_until_fire);
sapi_status_t sapi_watchdog_get_status(sapi_watchdog_t watchdog, sapi_watchdog_status_t *status_out)
Get watchdog status.
Watchdog health/status information.
sapi_duration_ms_t time_until_fire

Definition at line 249 of file sapi_watchdog.c.

◆ sapi_watchdog_destroy()

sapi_status_t sapi_watchdog_destroy ( sapi_watchdog_t watchdog)

Destroy watchdog.

Stops and deallocates watchdog. After destruction, handle is invalid.

Parameters
watchdogWatchdog handle
Returns
SAPI_STATUS_OK on success
Precondition
watchdog != NULL, watchdog was created via sapi_watchdog_create()
Postcondition
watchdog is stopped and deallocated
Safety:
Deterministic; safe to call on stopped or running watchdog

Definition at line 269 of file sapi_watchdog.c.

◆ sapi_watchdog_manager_initialize()

sapi_status_t sapi_watchdog_manager_initialize ( void )

Initialize watchdog manager (call once at startup).

Sets up the central watchdog manager that coordinates all watchdog timers. Must be called before creating any watchdogs.

Returns
SAPI_STATUS_OK on success
Postcondition
watchdog manager is ready to create watchdogs
Safety:
Called once at startup

Definition at line 118 of file sapi_watchdog.c.

◆ sapi_watchdog_manager_shutdown()

sapi_status_t sapi_watchdog_manager_shutdown ( void )

Shutdown watchdog manager (call once at shutdown).

Stops all running watchdogs and shuts down manager. After shutdown, cannot create new watchdogs until re-initialized.

Returns
SAPI_STATUS_OK on success
Postcondition
all watchdogs stopped; manager deallocated
Safety:
Safe to call multiple times; idempotent

Definition at line 129 of file sapi_watchdog.c.

◆ sapi_watchdog_timeout_handler()

void sapi_watchdog_timeout_handler ( uint32_t watchdog_id)

Watchdog timeout handler (INTERNAL - called by framework).

Invoked by watchdog timer when timeout occurs. Applies recovery action (log, safe-state, reboot, failover, or custom callback).

This is a framework-internal function; applications don't call it directly.

Parameters
watchdog_idID of watchdog that fired
Note
Called from timer interrupt context (may be ISR)
Recovery actions are async/deferred (logged, queued)

Definition at line 286 of file sapi_watchdog.c.

◆ sapi_watchdog_timer_tick()

void sapi_watchdog_timer_tick ( void )

Poll all active watchdogs for expiry (call periodically).

This implementation has no OS-specific interrupt/thread of its own (consistent with ADR-005: OS-specific timing belongs in an integrator backend, not in this module). Instead, the integrating application is responsible for calling this function regularly - e.g. from a sapi_timer periodic callback, or once per iteration of a sapi_appmanager execute() cycle - so that any watchdog whose deadline has passed is detected and its configured recovery action (sapi_watchdog_timeout_handler()) is dispatched.

Note
Non-blocking; O(N) over the fixed watchdog pool per call.
No-op if the watchdog manager has not been initialized.

Definition at line 369 of file sapi_watchdog.c.