实现独立看门狗:CubeMX 配置 IWDG + 任务心跳位图,恢复三处被覆盖定制

经 CubeMX 图形界面启用 IWDG(Prescaler=64 / Reload=1249,标称 2498ms /
最坏 1701ms),并落地心跳位图判定、各任务埋点、RCC_CSR 复位原因上报与
configASSERT 改造。重生成覆盖的既有定制已全部恢复。

P0(开机死循环):HAL_IWDG_Init() 内部立即启动看门狗,而 CubeMX 把
MX_IWDG_Init() 插在 app_main_init() 之前——该段 NAND/RTC/ADC 初始化耗时
数秒无喂狗点,按 2.5s 超时必然复位。改 Src/iwdg.c 为只填参数不启动,
启动移交 task_wd_start(),由 defaultTask 在存储 bring-up 完成后调用。

恢复的三处定制(重生成覆盖):
- Src/stm32f4xx_it.c:HardFault_Handler 崩溃现场采集被打回空 while(1)
- Inc/FreeRTOSConfig.h:栈溢出检测与堆失败钩子两个宏被整块删除
- Src/freertos.c:三处任务栈实测记录中文注释丢失(数值未丢)

新增:
- App/util/task_watchdog.{c,h}:心跳位图 + 抽样判定 + IWDG 延后启动
- time_sync.c 长等待切片:net_recv_to 单次可睡满 30s 预算,切成 200ms 片
- Src/main.c 复位原因锁存(读后即清 RMVF,防残留误判)

埋点:defaultTask(唯一喂狗者)/ netTask(含 PHY 等待循环)/ uiTask /
timeSyncTask。ftpTask 首期剔除掩码,待二期改 lftpd。

门禁:build 0 错误 0 警告;pre-commit 10 钩子全通过;Flash +2956B / RAM +40B。
This commit is contained in:
2026-09-29 07:22:04 +08:00
parent e18e9f2cfd
commit 7feeea6c56
24 changed files with 1761 additions and 361 deletions
+12 -2
View File
@@ -81,7 +81,8 @@
/* 栈溢出机械检测(2026-09-20 存储套件死机事故后加):模式 2 在每次上下文切换
* 检查栈底水位线,溢出即调 vApplicationStackOverflowHook(报任务名+复位)。
* 关闭检测时溢出会静默腐蚀堆相邻块(其它任务栈/TCB),表现为无异常、不可定位
* 的全系统冻结——本次事故签名。开销:每次切换一次字比较,可忽略。 */
* 的全系统冻结——本次事故签名。开销:每次切换一次字比较,可忽略。
* ⚠ 本段为手工添加,CubeMX 重生成会删除(2026-09-29 实测),改完须核对本块存在 */
#define configCHECK_FOR_STACK_OVERFLOW 2
/* pvPortMalloc 失败钩子(只告警不复位:分配失败路径由各调用点 NULL 检查处理) */
#define configUSE_MALLOC_FAILED_HOOK 1
@@ -160,7 +161,16 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* ⚠ 本段为手工添加,CubeMX 重生成会删除(2026-09-29 实测),改完须核对本块存在。
*
* 断言失败处理(2026-09-29,配合 IWDG):
* 原实现 `taskDISABLE_INTERRUPTS(); for(;;);` = 关中断死循环——CPU 停摆、无输出、
* 只能人工断电;且关中断后 IWDG 仍在跑(IWDG 走 LSI,与本 CPU 中断无关),
* 只要喂狗者(defaultTask)也被这该死循环卡住,2.5s 后 IWDG 自动复位,
* 系统自恢复。故改为调用带输出的上报函数(打印断言位置后主动复位)。
* 若断言发生在 IWDG 启动之前的启动段(无看门狗兜底),上报函数自行复位。 */
void vApplicationAssertFailed(const char *file, long line);
#define configASSERT( x ) if ((x) == 0) { vApplicationAssertFailed(__FILE__, __LINE__); }
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS