Add full automotive RTOS project
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers, middleware (CAN stack, diagnostics, safety), applications, board support, build/test tooling, and documentation.
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @file watchdog_manager.c
|
||||
* @brief Watchdog Manager for safety-critical applications
|
||||
*/
|
||||
|
||||
#include "kernel.h"
|
||||
#include "task.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Watchdog Configuration */
|
||||
#define WATCHDOG_MAX_TASKS 16
|
||||
#define WATCHDOG_DEFAULT_TIMEOUT 100 /* ms */
|
||||
#define WATCHDOG_MAX_ALIVE_COUNT 5
|
||||
|
||||
/* Watchdog Task Status */
|
||||
typedef enum {
|
||||
WATCHDOG_TASK_ALIVE = 0,
|
||||
WATCHDOG_TASK_TIMEOUT = 1,
|
||||
WATCHDOG_TASK_SUSPENDED = 2
|
||||
} WatchdogTaskStatus_t;
|
||||
|
||||
/* Watchdog Task Entry */
|
||||
typedef struct {
|
||||
TaskHandle_t task;
|
||||
char task_name[16];
|
||||
uint32_t timeout_ms;
|
||||
uint32_t last_alive_time;
|
||||
uint32_t alive_count;
|
||||
WatchdogTaskStatus_t status;
|
||||
bool is_supervised;
|
||||
} WatchdogTaskEntry_t;
|
||||
|
||||
/* Watchdog Manager State */
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
bool enabled;
|
||||
WatchdogTaskEntry_t tasks[WATCHDOG_MAX_TASKS];
|
||||
uint8_t task_count;
|
||||
uint32_t global_timeout_ms;
|
||||
uint32_t last_service_time;
|
||||
Mutex_t mutex;
|
||||
void (*system_reset_callback)(void);
|
||||
void (*task_timeout_callback)(TaskHandle_t task);
|
||||
} WatchdogManagerState_t;
|
||||
|
||||
static WatchdogManagerState_t watchdog_manager;
|
||||
|
||||
/* Initialize Watchdog Manager */
|
||||
KernelStatus_t watchdog_manager_init(uint32_t global_timeout_ms) {
|
||||
if (watchdog_manager.initialized) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
memset(&watchdog_manager, 0, sizeof(WatchdogManagerState_t));
|
||||
watchdog_manager.global_timeout_ms = global_timeout_ms;
|
||||
watchdog_manager.enabled = false;
|
||||
watchdog_manager.last_service_time = kernel_get_tick_count();
|
||||
|
||||
mutex_create(&watchdog_manager.mutex, false);
|
||||
|
||||
watchdog_manager.initialized = true;
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Register Task for Supervision */
|
||||
KernelStatus_t watchdog_register_task(TaskHandle_t task, const char* name,
|
||||
uint32_t timeout_ms) {
|
||||
if (!watchdog_manager.initialized || task == NULL) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
if (watchdog_manager.task_count >= WATCHDOG_MAX_TASKS) {
|
||||
return KERNEL_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mutex_lock(&watchdog_manager.mutex, 100);
|
||||
|
||||
WatchdogTaskEntry_t* entry = &watchdog_manager.tasks[watchdog_manager.task_count];
|
||||
entry->task = task;
|
||||
strncpy(entry->task_name, name, sizeof(entry->task_name) - 1);
|
||||
entry->timeout_ms = timeout_ms;
|
||||
entry->last_alive_time = kernel_get_tick_count();
|
||||
entry->alive_count = 0;
|
||||
entry->status = WATCHDOG_TASK_ALIVE;
|
||||
entry->is_supervised = true;
|
||||
|
||||
watchdog_manager.task_count++;
|
||||
|
||||
mutex_unlock(&watchdog_manager.mutex);
|
||||
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Task Alive Indication */
|
||||
KernelStatus_t watchdog_task_alive(TaskHandle_t task) {
|
||||
if (!watchdog_manager.initialized || task == NULL) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
mutex_lock(&watchdog_manager.mutex, 100);
|
||||
|
||||
for (uint8_t i = 0; i < watchdog_manager.task_count; i++) {
|
||||
if (watchdog_manager.tasks[i].task == task) {
|
||||
watchdog_manager.tasks[i].last_alive_time = kernel_get_tick_count();
|
||||
watchdog_manager.tasks[i].alive_count++;
|
||||
watchdog_manager.tasks[i].status = WATCHDOG_TASK_ALIVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&watchdog_manager.mutex);
|
||||
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Enable Watchdog */
|
||||
KernelStatus_t watchdog_enable(void) {
|
||||
if (!watchdog_manager.initialized) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
watchdog_manager.enabled = true;
|
||||
watchdog_manager.last_service_time = kernel_get_tick_count();
|
||||
|
||||
/* Enable hardware watchdog */
|
||||
hal_watchdog_enable(watchdog_manager.global_timeout_ms);
|
||||
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Disable Watchdog */
|
||||
KernelStatus_t watchdog_disable(void) {
|
||||
if (!watchdog_manager.initialized) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
watchdog_manager.enabled = false;
|
||||
|
||||
/* Disable hardware watchdog */
|
||||
hal_watchdog_disable();
|
||||
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Service Watchdog */
|
||||
KernelStatus_t watchdog_service(void) {
|
||||
if (!watchdog_manager.initialized || !watchdog_manager.enabled) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
/* Check all supervised tasks */
|
||||
uint32_t current_time = kernel_get_tick_count();
|
||||
bool all_tasks_alive = true;
|
||||
|
||||
mutex_lock(&watchdog_manager.mutex, 100);
|
||||
|
||||
for (uint8_t i = 0; i < watchdog_manager.task_count; i++) {
|
||||
WatchdogTaskEntry_t* entry = &watchdog_manager.tasks[i];
|
||||
|
||||
if (!entry->is_supervised) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if task is alive */
|
||||
if ((current_time - entry->last_alive_time) > entry->timeout_ms) {
|
||||
entry->status = WATCHDOG_TASK_TIMEOUT;
|
||||
all_tasks_alive = false;
|
||||
|
||||
/* Call task timeout callback */
|
||||
if (watchdog_manager.task_timeout_callback != NULL) {
|
||||
watchdog_manager.task_timeout_callback(entry->task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&watchdog_manager.mutex);
|
||||
|
||||
if (all_tasks_alive) {
|
||||
/* Service hardware watchdog */
|
||||
hal_watchdog_service();
|
||||
watchdog_manager.last_service_time = current_time;
|
||||
return KERNEL_OK;
|
||||
} else {
|
||||
/* Don't service watchdog - will trigger reset */
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register Callbacks */
|
||||
KernelStatus_t watchdog_register_callbacks(
|
||||
void (*system_reset_callback)(void),
|
||||
void (*task_timeout_callback)(TaskHandle_t task)) {
|
||||
|
||||
if (!watchdog_manager.initialized) {
|
||||
return KERNEL_ERROR;
|
||||
}
|
||||
|
||||
watchdog_manager.system_reset_callback = system_reset_callback;
|
||||
watchdog_manager.task_timeout_callback = task_timeout_callback;
|
||||
|
||||
return KERNEL_OK;
|
||||
}
|
||||
|
||||
/* Watchdog Main Function */
|
||||
void watchdog_manager_main_function(void) {
|
||||
if (!watchdog_manager.initialized || !watchdog_manager.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Service watchdog periodically */
|
||||
watchdog_service();
|
||||
}
|
||||
Reference in New Issue
Block a user