|
Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
|
Application Manager abstraction for safeAPIFramework applications. More...
#include <stdint.h>#include "safeapi/utils/status/sapi_status.h"#include "safeapi/utils/types/sapi_types.h"#include "safeapi/redundancy/voter/sapi_voter.h"#include "safeapi/redundancy/watchdog/sapi_watchdog.h"Go to the source code of this file.
Data Structures | |
| struct | sapi_appmanager_operations_t |
| Application lifecycle operations. More... | |
| struct | sapi_appmanager_checkpoint_config_t |
| Optional built-in checkpoint rendezvous configuration (ADR-019/ADR-034). More... | |
| struct | sapi_appmanager_config_t |
| Application manager configuration. More... | |
| struct | sapi_appmanager_state_t |
| Application manager runtime state. More... | |
Macros | |
| #define | SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED ((uint64_t)0xFFFFFFFFFFFFFFFFULL) |
| Reset value of the per-cycle checkpoint signature before any marks are folded into it (ADR-034) - see sapi_appmanager_checkpoint_fold_signature()'s own doc. A cycle in which no SAPI_CHECKPOINT_MARK() call is ever made therefore always computes checkpoint_id as sapi_appmanager_checkpoint_fold_signature(SAPI_APPMANAGER_CHECKPOINT_SIGNATURE_SEED). | |
| #define | SAPI_CHECKPOINT_MARK() |
| Records a checkpoint mark for this call site (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc. | |
| #define | SAPI_CHECKPOINT_MARK_LABEL(label_str) |
| Records a checkpoint mark identified by a caller-supplied label instead of this call site's file:line (ADR-034) - see sapi_appmanager_checkpoint_mark()'s own doc. | |
Enumerations | |
| enum | sapi_app_state_t { SAPI_APP_STATE_UNINITIALIZED = 0 , SAPI_APP_STATE_INITIALIZING = 1 , SAPI_APP_STATE_RUNNING = 2 , SAPI_APP_STATE_SHUTTING_DOWN = 3 , SAPI_APP_STATE_SHUTDOWN = 4 , SAPI_APP_STATE_ERROR = 5 } |
| Application state enumeration. More... | |
Functions | |
| uint32_t | sapi_appmanager_checkpoint_fold_signature (uint64_t signature) |
| Pure helper: folds a 64-bit checkpoint signature down to the uint32_t sapi_checkpoint_config_t::checkpoint_id expects (ADR-034). | |
| void | sapi_appmanager_checkpoint_mark (const char *file, int32_t line, const char *label) |
| Folds a hash of this call site into the current cycle's checkpoint signature (ADR-034). | |
| int | sapi_appmanager_run (const sapi_appmanager_config_t *config) |
| Run application with lifecycle management. | |
| sapi_app_state_t | sapi_appmanager_get_state (void) |
| Get current application state. | |
| sapi_status_t | sapi_appmanager_get_stats (sapi_appmanager_state_t *state) |
| Get application statistics. | |
| void | sapi_appmanager_request_shutdown (void) |
| Request application shutdown. | |
| sapi_status_t | sapi_appmanager_install_default_signal_handlers (void) |
| POSIX-only convenience: installs SIGINT and SIGTERM handlers that call sapi_appmanager_request_shutdown(), so an operator (Ctrl+C) or process manager (SIGTERM) can stop a sapi_appmanager_run() loop gracefully - shutdown() still runs, this is not a hard kill. | |
| void | sapi_appmanager_reset_state (void) |
| Forcibly resets the application manager's own bookkeeping (lifecycle state, iteration/error counters, shutdown-request flag, and the ADR-026 setup-phase lock) back to its initial, pre-run condition. | |
Application Manager abstraction for safeAPIFramework applications.
Provides a single entry point pattern for safety-critical applications with well-defined lifecycle: initialize → execute → shutdown.
Each application implements the sapi_appmanager_operations_t interface:
The sapi_appmanager_run() function manages lifecycle and error handling. Per ADR-019/ADR-034, it can also be configured (sapi_appmanager_config_t::checkpoint) to perform a bounded sapi_channel_checkpoint() rendezvous (ADR-017) as the LAST stage of every cycle, after pre_execute/execute/post_execute, so a dual/multi-channel application does not have to hand-roll that call itself; this is opt-in and defaults to disabled (NULL).
ADR-034: the checkpoint's own checkpoint_id is no longer a bare cycle counter (that broke across an independent reboot of just one channel - see sapi_appmanager_checkpoint_config_t's own doc). Instead, application code calls SAPI_CHECKPOINT_MARK() (or the labelled variant, SAPI_CHECKPOINT_MARK_LABEL()) at meaningful decision/preparation points during pre_execute()/execute()/post_execute(); each call folds a CRC64 hash of its call site (by default FILE:LINE, or a caller-supplied label) into a single running per-cycle signature. The checkpoint stage then rendezvous-compares THIS cycle's own folded signature with the peer's - so a match proves both channels reached the exact same sequence of marks this cycle (the same program path), not merely "both channels are alive." If ops->on_checkpoint_result is non-NULL, it is called exactly once per cycle with the outcome, letting an application stage (queue but not transmit) its outputs during the cycle and only commit (actually send) them once the checkpoint confirms both channels agree - see that field's own doc.
REQ-APPMANAGER-001: Applications shall use the Application Manager for controlled initialization, execution, and shutdown lifecycle.
ADR-026: the moment init() returns SAPI_STATUS_OK, sapi_appmanager_run() locks the application's setup phase (sapi_lifecycle_lock() - see sapi_lifecycle.h) - every setup-only constructor this framework ships (sapi_timer_create(), sapi_channel_init(), sapi_voter_init()/ _register_channel(), sapi_cross_comparator_init()/_register_channel(), sapi_watchdog_create()) then rejects with SAPI_STATUS_INVALID_STATE for the remainder of this run: a timer/channel/voter/cross-comparator/ watchdog an application's own init() did not already create is not one its execute()/pre_execute()/post_execute() may create either. sapi_netlink_open()/sapi_dual_channel_init()/sapi_dual_negotiator_init() are deliberately NOT gated by this lock - see sapi_lifecycle.h's own doc for why a link an application already owns being re-established after a drop is not the same thing this lock exists to prevent.
Definition in file sapi_appmanager.h.