- make-uefi-iso.sh: UEFI ISO image builder - test_boot.S, test_boot.ld: test boot assembly and linker script - eim_config.toml: EIM (External Interface Module) configuration - edk2-ovmf RPM for UEFI firmware - GAP_ANALYSIS_PIKEOS_PARITY.md: PikeOS parity gap analysis
129 lines
4.9 KiB
C
129 lines
4.9 KiB
C
/*
|
|
* UniversalisOS Microkernel — Hard Real-Time Monitoring
|
|
*
|
|
* HRT-2.1: Execution budget enforcement (WCET overrun detection)
|
|
* HRT-2.2: ISR latency measurement
|
|
*
|
|
* Design:
|
|
* - exec_consumed is incremented every tick for the running task.
|
|
* - If exec_consumed > exec_budget, the protection hook fires.
|
|
* - ISR entry/exit timestamps are captured via DWT cycle counter
|
|
* (Cortex-M3+) or SysTick counter (Cortex-M0).
|
|
*
|
|
* Bounds:
|
|
* - uos_hrt_tick_check: O(1) — single comparison
|
|
* - uos_hrt_isr_enter/exit: O(1) — 2 register reads + compare
|
|
*/
|
|
#ifndef UOS_HRT_H
|
|
#define UOS_HRT_H
|
|
|
|
#include "uos_types.h"
|
|
#include "uos_api.h"
|
|
|
|
/* ====================================================================== */
|
|
/* Protection Hook (called on WCET overrun, stack overflow, etc.) */
|
|
/* ====================================================================== */
|
|
|
|
typedef enum {
|
|
UOS_HRT_VIOLATION_NONE = 0,
|
|
UOS_HRT_VIOLATION_EXEC_BUDGET = 1, /* Task exceeded its WCET budget */
|
|
UOS_HRT_VIOLATION_INTERARRIVAL = 2, /* Task activated too soon */
|
|
UOS_HRT_VIOLATION_STACK_OVERFLOW= 3, /* Stack canary corrupted */
|
|
UOS_HRT_VIOLATION_ISR_LATENCY = 4, /* ISR latency exceeded bound */
|
|
} uos_hrt_violation_t;
|
|
|
|
typedef enum {
|
|
UOS_HRT_ACTION_IGNORE = 0,
|
|
UOS_HRT_ACTION_SUSPEND_TASK = 1,
|
|
UOS_HRT_ACTION_TERMINATE_TASK = 2,
|
|
UOS_HRT_ACTION_SHUTDOWN = 3,
|
|
} uos_hrt_action_t;
|
|
|
|
typedef uos_hrt_action_t (*uos_hrt_hook_t)(uos_hrt_violation_t violation,
|
|
uos_task_t* task,
|
|
uos_tick_t value);
|
|
|
|
/* Register the global protection hook */
|
|
void uos_hrt_set_hook(uos_hrt_hook_t hook);
|
|
|
|
/* ====================================================================== */
|
|
/* Execution Budget API */
|
|
/* ====================================================================== */
|
|
|
|
/* Set execution budget for a task (max ticks per activation) */
|
|
void uos_hrt_set_exec_budget(uos_task_t* task, uos_tick_t budget_ticks);
|
|
|
|
/* Set minimum inter-arrival time (for periodic tasks) */
|
|
void uos_hrt_set_interarrival(uos_task_t* task, uos_tick_t min_ticks);
|
|
|
|
/* Called from tick handler: check running task's budget */
|
|
void uos_hrt_tick_check(void);
|
|
|
|
/* Called when a task is activated: reset budget, check inter-arrival */
|
|
void uos_hrt_on_activate(uos_task_t* task);
|
|
|
|
/* ====================================================================== */
|
|
/* ISR Latency Measurement */
|
|
/* ====================================================================== */
|
|
|
|
typedef struct {
|
|
uint32_t min_cycles; /* Minimum ISR latency in CPU cycles */
|
|
uint32_t max_cycles; /* Maximum ISR latency in CPU cycles */
|
|
uint32_t count; /* Number of ISR invocations measured */
|
|
uint32_t threshold; /* Alert threshold (0 = unchecked) */
|
|
uint32_t overrun_count; /* Times threshold was exceeded */
|
|
} uos_hrt_isr_stat_t;
|
|
|
|
/* Register an ISR for latency measurement */
|
|
void uos_hrt_isr_register(uint32_t irq_num, uint32_t threshold_cycles);
|
|
|
|
/* Called at ISR entry — captures cycle counter */
|
|
void uos_hrt_isr_enter(uint32_t irq_num);
|
|
|
|
/* Called at ISR exit — computes latency, updates stats */
|
|
void uos_hrt_isr_exit(uint32_t irq_num);
|
|
|
|
/* Get ISR latency statistics */
|
|
const uos_hrt_isr_stat_t* uos_hrt_isr_get_stats(uint32_t irq_num);
|
|
|
|
/* Reset all ISR statistics */
|
|
void uos_hrt_isr_reset_stats(void);
|
|
|
|
/* ====================================================================== */
|
|
/* Cycle Counter (port-provided) */
|
|
/* ====================================================================== */
|
|
|
|
/* Read the CPU cycle counter.
|
|
* Cortex-M3+: DWT->CYCCNT
|
|
* Cortex-M0: approximate via SysTick->VAL */
|
|
UOS_INLINE uint32_t uos_hrt_cycle_count(void) {
|
|
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || \
|
|
defined(__ARM_ARCH_8M__) || defined(__ARM_ARCH_8M_MAIN__)
|
|
/* DWT cycle counter (Cortex-M3+) */
|
|
volatile uint32_t* dwt_cyccnt = (volatile uint32_t*)0xE0001004;
|
|
return *dwt_cyccnt;
|
|
#else
|
|
/* Cortex-M0: no DWT, approximate with a raw counter.
|
|
* The port layer can override this. */
|
|
static volatile uint32_t mock_cycles;
|
|
return ++mock_cycles;
|
|
#endif
|
|
}
|
|
|
|
/* Initialize the cycle counter (enable DWT on M3+) */
|
|
void uos_hrt_cycle_counter_init(void);
|
|
|
|
/* ====================================================================== */
|
|
/* Statistics */
|
|
/* ====================================================================== */
|
|
|
|
/* Get worst-case observed execution time for a task (in ticks) */
|
|
uos_tick_t uos_hrt_get_worst_case(uos_task_t* task);
|
|
|
|
/* Global context-switch count */
|
|
extern volatile uint32_t uos_hrt_switch_count;
|
|
|
|
/* Global tick count with ISR entry overhead */
|
|
extern volatile uint32_t uos_hrt_tick_isr_cycles;
|
|
|
|
#endif /* UOS_HRT_H */
|