Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#include "wdt_task/wdt_task.h"
|
||||
|
||||
#if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D
|
||||
#include "iwdg.h" /* [CCU601E_D] STM32 IWDG 独立看门狗 */
|
||||
#endif
|
||||
|
||||
#include "sys_drv_init.h"
|
||||
#include "publicdata/public_define.h"
|
||||
#include "mylog/mylog.h"
|
||||
#include "publicdata/publicdata.h"
|
||||
|
||||
#define WDT_TASK_CNT ((uint8_t)MY_TASK_NUM)
|
||||
#define WDT_TIMEOUT_SECONDS (300U)
|
||||
#define WDT_RESET_ENABLE 0U /* 1: 超时后触发系统复位; 0: 仅钳位计数 */
|
||||
|
||||
static uint16_t g_wdt_evt_flag[WDT_TASK_CNT] = {0U};
|
||||
|
||||
#define WDT_LOG(fmt, ...) \
|
||||
MYLOG_MSG(TASK_ID_WATCHDOG,fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief 获取指定任务的看门狗计数值。
|
||||
*
|
||||
* 计数值含义:距离该任务最近一次调用 `v_wdt_setFlag()` 的秒数。
|
||||
* 当任务ID非法时返回0。
|
||||
*
|
||||
* @param id 任务ID(对应 `TASK_ID` 枚举值)。
|
||||
* @return uint16_t 对应任务当前计数值。
|
||||
*/
|
||||
uint16_t u16_get_wdt_cnt(uint8_t id)
|
||||
{
|
||||
if (id < WDT_TASK_CNT) {
|
||||
return g_wdt_evt_flag[id];
|
||||
}
|
||||
return 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清零指定任务的看门狗计数(任务喂狗)。
|
||||
*
|
||||
* 该函数通常由各业务任务在其主循环中周期调用,用于表明任务仍在正常运行。
|
||||
* 传入ID越界时函数静默返回,不执行任何写操作。
|
||||
*
|
||||
* @param task_id 任务ID(`TASK_ID` 枚举)。
|
||||
*/
|
||||
void v_wdt_setFlag(TASK_ID task_id)
|
||||
{
|
||||
uint8_t id = (uint8_t)task_id;
|
||||
if (id < WDT_TASK_CNT) {
|
||||
g_wdt_evt_flag[id] = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 每秒对所有任务看门狗计数加1。
|
||||
*
|
||||
* 基于 `xTaskGetTickCount()` 做1秒节拍判断,避免依赖RTC/系统秒计时接口。
|
||||
* 计数采用饱和累加,最大不超过 `0xFFFF`。
|
||||
*/
|
||||
static void v_wdt_add_timer(void)
|
||||
{
|
||||
static TickType_t last_tick = 0U;
|
||||
TickType_t now_tick = xTaskGetTickCount();
|
||||
|
||||
if ((now_tick - last_tick) >= pdMS_TO_TICKS(1000U)) {
|
||||
last_tick = now_tick;
|
||||
for (uint8_t i = 0U; i < WDT_TASK_CNT; ++i) {
|
||||
if (g_wdt_evt_flag[i] < 0xFFFFU) {
|
||||
++g_wdt_evt_flag[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void v_wdt_dog_toggle()
|
||||
{
|
||||
WATCKDOG_TOGGLE(); //看门狗翻转
|
||||
#if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D
|
||||
v_iwdg_refresh(); /* [CCU601E_D] STM32 内部看门狗喂狗 */
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @brief 执行任务运行状态检查。
|
||||
*
|
||||
* 检查流程:
|
||||
* 1. 先调用 `v_wdt_add_timer()` 更新各任务计数;
|
||||
* 2. 跳过 lwIP 内部任务(`EthIf`、`TCPIP`);
|
||||
* 3. 当 Shell 未使能时跳过 `MyShell`;
|
||||
* 4. 若任务计数超过超时阈值,当前阶段先钳位到阈值,不直接复位系统。
|
||||
*/
|
||||
static void v_wdt_task_runing_cheak(void)
|
||||
{
|
||||
v_wdt_add_timer();
|
||||
|
||||
/* EthIf/TCPIP 为 lwIP 内部线程创建,不参与本任务计数判断 */
|
||||
for (uint8_t i = 0U; i < WDT_TASK_CNT; ++i) {
|
||||
if ((i == (uint8_t)TASK_ID_EthIf) || (i == (uint8_t)TASK_ID_TCPIP)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_wdt_evt_flag[i] > WDT_TIMEOUT_SECONDS) {
|
||||
#if (WDT_RESET_ENABLE)
|
||||
/* 超时触发系统复位:打印故障任务名后复位 */
|
||||
const char *task_name = (i < (uint8_t)MY_TASK_NUM) ? my_task_data[i].task_name : "UNKNOWN";
|
||||
printf("\r\n!!! WDT RESET: Task[%s](ID=%u) timeout > %us, system reset !!!\r\n",
|
||||
task_name, (unsigned int)i, (unsigned int)WDT_TIMEOUT_SECONDS);
|
||||
/* 短暂延时让串口数据发送完成 */
|
||||
for (volatile uint32_t delay = 0U; delay < 100000U; delay++) {}
|
||||
NVIC_SystemReset();
|
||||
#else
|
||||
/* 仅钳位计数,不复位(调试阶段使用) */
|
||||
g_wdt_evt_flag[i] = WDT_TIMEOUT_SECONDS;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 看门狗任务主循环。
|
||||
*
|
||||
* 任务职责:
|
||||
* - 对自身任务喂狗;
|
||||
* - 周期扫描其它任务运行计数;
|
||||
* - 按半周期翻转外部看门狗引脚,维持硬件喂狗节奏。
|
||||
*
|
||||
* @param argument 任务参数,当前未使用。
|
||||
*/
|
||||
void v_wdt_task(void *argument)
|
||||
{
|
||||
(void)argument;
|
||||
uint16_t sleep_ms = MY_GET_SLEEP_TIME(TASK_ID_WATCHDOG);
|
||||
/* 将完整周期拆成两次半周期喂狗;当周期过小时兜底为1ms,避免出现0ms延时。 */
|
||||
uint16_t half_sleep_ms = (sleep_ms > 1U) ? (sleep_ms / 2U) : 1U;
|
||||
|
||||
for (;;) {
|
||||
v_wdt_setFlag(TASK_ID_WATCHDOG);
|
||||
v_wdt_task_runing_cheak();
|
||||
|
||||
v_wdt_dog_toggle();
|
||||
mSleep(half_sleep_ms);
|
||||
|
||||
v_wdt_dog_toggle();
|
||||
mSleep(half_sleep_ms);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef WDT_TASK_H
|
||||
#define WDT_TASK_H
|
||||
|
||||
#include "app_init/app_init.h"
|
||||
void v_wdt_dog_toggle(void);
|
||||
|
||||
void v_wdt_task(void *argument);
|
||||
void v_wdt_setFlag(TASK_ID task_id);
|
||||
uint16_t u16_get_wdt_cnt(uint8_t id);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
# wdt_task 模块说明
|
||||
|
||||
> 路径:`app/wdt_task/`
|
||||
> 返回主说明:[README](../../README.md)
|
||||
|
||||
## 1. 模块职责
|
||||
|
||||
- 周期执行看门狗任务;
|
||||
- 统计任务运行健康状态;
|
||||
- 执行硬件喂狗,防止系统异常卡死。
|
||||
|
||||
## 2. 关键文件
|
||||
|
||||
- `wdt_task.c`
|
||||
- `wdt_task.h`
|
||||
|
||||
## 3. 功能说明
|
||||
|
||||
- 通过任务计数/心跳判断系统是否处于正常调度状态;
|
||||
- 达到喂狗条件时执行硬件喂狗动作;
|
||||
- 异常时可配合日志模块输出告警信息。
|
||||
|
||||
## 4. 调度与对外接口
|
||||
|
||||
该模块由 FreeRTOS 任务 `WatchDog` 周期运行(单位:ms),周期来自 `app/app_init/app_init.c`:
|
||||
|
||||
- `WatchDog`:`150ms`(任务入口:`v_wdt_task(void *argument)`)
|
||||
|
||||
对外接口(来自 `wdt_task.h`):
|
||||
|
||||
- `void v_wdt_setFlag(TASK_ID task_id)`:由其他任务打标,表示“该任务本周期正常运行”,用于喂狗/健康判断
|
||||
- `uint16_t u16_get_wdt_cnt(uint8_t id)`:读取任务健康计数/喂狗相关计数(用于调试与统计)
|
||||
|
||||
## 5. 维护建议
|
||||
|
||||
- 新增关键任务后建议纳入健康监测;
|
||||
- 调整喂狗周期时,需与系统实时负载联动评估。
|
||||
|
||||
## 6. 关联文档
|
||||
|
||||
- 主索引:[README](../../README.md)
|
||||
Reference in New Issue
Block a user