实现独立看门狗: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:
@@ -37,6 +37,11 @@ MDK-ARM/RTE/
|
||||
# STM32CubeMX (keep .ioc, it's the project source)
|
||||
# *.ioc
|
||||
|
||||
# CubeMX 重生成时自动产生的旧文件备份(Src/Backup/、Inc/Backup/)——
|
||||
# 纯本地临时物,内容 = 重生成前的快照;入库只会造成无意义的提交抖动
|
||||
Src/Backup/
|
||||
Inc/Backup/
|
||||
|
||||
# Visual Studio / IDE
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
+4
-4
File diff suppressed because one or more lines are too long
@@ -28,6 +28,53 @@
|
||||
|
||||
/* g_rs485 由 rs485.c 定义,经 rs485.h 的 extern 引用;接收缓冲内聚于句柄 rx_buf */
|
||||
|
||||
/* 复位原因锁存值(Src/main.c 在 HAL_Init() 后立即写入并清除 RCC_CSR)。
|
||||
* 放这里而非 main.c,是因为需要与其它应用级全局量同层、且日志侧更好引用。 */
|
||||
volatile uint32_t g_rcc_csr_latched;
|
||||
|
||||
/*
|
||||
* 函数功能:把 RCC_CSR 锁存值翻译为可读的复位原因串(见手册 RM0090 §6.3.22)
|
||||
* 入口参数:csr - 锁存的 RCC_CSR 值
|
||||
* buf - 输出缓冲
|
||||
* len - 缓冲容量
|
||||
* 返回值:无
|
||||
* 函数说明:按"最可信归因"的优先级组织——IWDG/WWDG 优先于软件复位
|
||||
* (看门狗复位是我们真正关心的自动恢复事件;软件复位多为崩溃钩子
|
||||
* 兜底,两者同时置位时报告看门狗更有价值)。纯 ASCII,防编码坑。
|
||||
*/
|
||||
static void reset_cause_str(uint32_t csr, char *buf, unsigned int len) {
|
||||
const char *cause;
|
||||
|
||||
if ((csr & RCC_CSR_IWDGRSTF) != 0u) {
|
||||
cause = "IWDG (independent watchdog)";
|
||||
} else if ((csr & RCC_CSR_WWDGRSTF) != 0u) {
|
||||
cause = "WWDG (window watchdog)";
|
||||
} else if ((csr & RCC_CSR_SFTRSTF) != 0u) {
|
||||
cause = "software (NVIC_SystemReset)";
|
||||
} else if ((csr & RCC_CSR_PORRSTF) != 0u) {
|
||||
cause = "power-on (POR)";
|
||||
} else if ((csr & RCC_CSR_PINRSTF) != 0u) {
|
||||
cause = "external pin (NRST)";
|
||||
} else if ((csr & RCC_CSR_BORRSTF) != 0u) {
|
||||
cause = "brown-out (BOR)";
|
||||
} else {
|
||||
cause = "unknown";
|
||||
}
|
||||
|
||||
/* 简单有界拼接(不引 snprintf,避免依赖与栈开销) */
|
||||
if (buf == NULL || len == 0u) {
|
||||
return;
|
||||
}
|
||||
{
|
||||
unsigned int i = 0u;
|
||||
while ((i < (len - 1u)) && (cause[i] != '\0')) {
|
||||
buf[i] = cause[i];
|
||||
i++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:应用层初始化
|
||||
* 入口参数:无
|
||||
@@ -46,6 +93,21 @@ int app_main_init(void) {
|
||||
/* 日志引擎初始化(创建待发队列;须先于任何 syslog_post) */
|
||||
(void)syslog_mcu_init();
|
||||
|
||||
/* 0) 复位原因上报(锁存值由 Src/main.c 在 HAL_Init() 后立即采得)。
|
||||
* 放在日志引擎之后、业务初始化之前:任何一次非上电复位都值得在
|
||||
* 开机第一时间看到——尤其 IWDG,它意味着上一轮运行有任务卡死。
|
||||
* 注意:RCC_CSR 已被 main.c 清零,本处只读锁存副本。 */
|
||||
{
|
||||
char cause[40];
|
||||
uint32_t csr = g_rcc_csr_latched;
|
||||
reset_cause_str(csr, cause, sizeof(cause));
|
||||
DBG_INFO("reset cause: %s (CSR=0x%08lX)", cause, (unsigned long)csr);
|
||||
/* 看门狗复位记入自检记录(只记载故障,符合既有约定) */
|
||||
if ((csr & (RCC_CSR_IWDGRSTF | RCC_CSR_WWDGRSTF)) != 0u) {
|
||||
syslog_post(SYSLOG_SELFTEST, "watchdog reset");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) 时间子系统初始化(尽早完成,后续所有日志带时间戳)
|
||||
* sd2506_init() 从 RTC 读取初始时间
|
||||
|
||||
+26
-2
@@ -17,6 +17,7 @@
|
||||
#include "net_socket.h"
|
||||
#include "sys_clock.h"
|
||||
#include "sys_events.h"
|
||||
#include "task_watchdog.h"
|
||||
|
||||
#define DBG_TAG "[TIME_SYNC]"
|
||||
#include "dbg_log.h"
|
||||
@@ -36,6 +37,11 @@
|
||||
*/
|
||||
#define TIME_SYNC_TOTAL_BUDGET_MS 30000U
|
||||
|
||||
/* 看门狗分片等待:单次 net_recv_to 的等待片长上限。须显著小于看门狗抽样窗
|
||||
* (task_watchdog.c WD_POLL_PERIOD_MS=100ms)的容错窗口(8 窗 = 800ms),
|
||||
* 200ms 留足余量;语义上仅把一次长等待拆成多次短等待,总预算不变。 */
|
||||
#define TIME_SYNC_WAIT_SLICE_MS 200U
|
||||
|
||||
/*
|
||||
* 函数功能:创建并监听 TCP 时间同步服务端口
|
||||
* 入口参数:无
|
||||
@@ -49,6 +55,7 @@ static int time_sync_open_listener(void) {
|
||||
int retry;
|
||||
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
task_wd_beat(TASK_WD_TIMESYNC); /* 每次重试前喂心跳(见下方 500ms/2000ms 延时) */
|
||||
int s = net_socket(NET_AF_INET, NET_SOCK_STREAM);
|
||||
if (s < 0) {
|
||||
DBG_ERROR("time_sync: net_socket FAIL");
|
||||
@@ -65,6 +72,7 @@ static int time_sync_open_listener(void) {
|
||||
if (net_bind(s, (struct net_sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
DBG_ERROR("time_sync: bind port %d FAIL", TIME_SYNC_PORT);
|
||||
net_close(s);
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
continue;
|
||||
}
|
||||
@@ -72,6 +80,7 @@ static int time_sync_open_listener(void) {
|
||||
if (net_listen(s) != 0) {
|
||||
DBG_ERROR("time_sync: listen FAIL");
|
||||
net_close(s);
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
continue;
|
||||
}
|
||||
@@ -99,7 +108,11 @@ static void time_sync_handle_conn(int conn_sock) {
|
||||
|
||||
while (got < (int)sizeof(buf)) {
|
||||
/* 单次预算 = 剩余总预算(L3 pending:等待期 netTask 零占用,调用方
|
||||
* 在自己上下文睡任务通知,旧片间 vTaskDelay(1) 让出退役) */
|
||||
* 在自己上下文睡任务通知,旧片间 vTaskDelay(1) 让出退役)
|
||||
* ⚠ 看门狗约束:本任务在 required_mask 内,而单次 net_recv_to 可睡满
|
||||
* 30s 预算 —— 等待期必须周期性喂心跳,否则"对端连上但不发时间包"这种
|
||||
* 完全正常的场景会被判为任务卡死(见设计说明 §4.4 长耗时白名单)。
|
||||
* 做法:把长等待切成 WD 窗口内的短片(片长 ≤200ms),每片先喂心跳。 */
|
||||
TickType_t elapsed = xTaskGetTickCount() - t0;
|
||||
uint32_t rem = (elapsed >= (TickType_t)pdMS_TO_TICKS(TIME_SYNC_TOTAL_BUDGET_MS)) ? 0U
|
||||
: (uint32_t)((TickType_t)TIME_SYNC_TOTAL_BUDGET_MS - elapsed);
|
||||
@@ -107,6 +120,10 @@ static void time_sync_handle_conn(int conn_sock) {
|
||||
DBG_INFO("time_sync: no TIME packet in 30s, drop conn");
|
||||
break; /* 总预算耗尽(语义同旧 30s 超时) */
|
||||
}
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
if (rem > TIME_SYNC_WAIT_SLICE_MS) {
|
||||
rem = TIME_SYNC_WAIT_SLICE_MS; /* 分片:等待期保持心跳节奏 */
|
||||
}
|
||||
int n = net_recv_to(conn_sock, buf + got, (int)(sizeof(buf) - got), rem);
|
||||
if (n > 0) {
|
||||
got += n;
|
||||
@@ -119,7 +136,7 @@ static void time_sync_handle_conn(int conn_sock) {
|
||||
break; /* 对端关闭(EOF) */
|
||||
}
|
||||
if (n == -2) {
|
||||
continue; /* 本次预算等满无数据 → 下轮 rem=0 退出 */
|
||||
continue; /* 本片预算等满无数据 → 下一片重算剩余预算 */
|
||||
}
|
||||
break; /* 真错误 */
|
||||
}
|
||||
@@ -157,12 +174,17 @@ void time_sync_task(void *argument) {
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* 心跳:本任务在 required_mask 内。以下每一处可能长于 100ms 抽样窗的
|
||||
* 阻塞点(监听重试 2s、accept 轮询 200ms/次、收尾 50ms)都就近补心跳。 */
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
|
||||
/* 记录本次监听对应的网络代次;代次变化(网络重建)则放弃旧监听重建 */
|
||||
uint32_t gen = net_get_generation();
|
||||
|
||||
int ls = time_sync_open_listener();
|
||||
if (ls < 0) {
|
||||
DBG_ERROR("time_sync: open listener FAIL, retry later");
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
continue;
|
||||
}
|
||||
@@ -176,6 +198,7 @@ void time_sync_task(void *argument) {
|
||||
net_close(ls); /* 网络重建:旧监听失效,回外层重建 */
|
||||
break;
|
||||
}
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
}
|
||||
} while (conn < 0);
|
||||
@@ -188,6 +211,7 @@ void time_sync_task(void *argument) {
|
||||
time_sync_handle_conn(conn);
|
||||
/* conn(单连接模式下即 ls)已被 net_close 释放,下次循环重建监听 */
|
||||
|
||||
task_wd_beat(TASK_WD_TIMESYNC);
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "sys_log.h"
|
||||
#include "sys_events.h"
|
||||
#include "dbg_log.h"
|
||||
#include "task_watchdog.h"
|
||||
|
||||
/* 任务句柄与属性块(CubeMX 生成全局,定义于 Src/freertos.c):
|
||||
* 栈水位观测需 6 任务句柄 + 属性块 stack_size(配置栈大小的唯一定义处) */
|
||||
@@ -149,7 +150,19 @@ void default_task_func(void *argument) {
|
||||
* 并让脏指针无法再进入 HAL_UART_Transmit 的缓冲遍历。 */
|
||||
dbg_console_writer_attach();
|
||||
|
||||
/* 启动看门狗(延后启动):此处位于全部长耗时初始化之后——存储 bring-up 深链
|
||||
* (mount/mkfs/FAT 探针/syslog 挂载/配置加载)已完成,监视一开始即处于稳态。
|
||||
* 这正是"启动段不喂狗、主循环段才喂"的落点(见 docs/子系统设计/看门狗设计说明.md
|
||||
* §4.5 决策 C):MX_IWDG_Init() 只填参数不启动,启动延后到此时。
|
||||
* 代价(显式声明):从复位到此处约数秒的窗口无看门狗保护,该段死机表现为
|
||||
* "无任何输出 + LED 不闪",可人工辨识。 */
|
||||
task_wd_start();
|
||||
|
||||
for (;;) {
|
||||
/* 心跳抽样与喂狗判定(内部节流至 100ms;全员到位才喂,否则累计停喂) */
|
||||
task_wd_poll();
|
||||
/* 本任务自己的心跳 */
|
||||
task_wd_beat(TASK_WD_DEFAULT);
|
||||
/* 等待"保存网络配置"或"控制台待发":任一即醒;无事件 50ms 后返回
|
||||
* (日志时延 = 事件唤醒,实测无丢失;50ms 兜底仅防事件位异常) */
|
||||
if (sys_evtHandle != NULL) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "sys_events.h"
|
||||
#include "sys_log.h"
|
||||
#include "test_config.h" /* 测试模式宏(ENABLE_HW_LAYER_TESTS);产品构建全未定义,无作用 */
|
||||
#include "task_watchdog.h"
|
||||
|
||||
#define DBG_TAG "[NET_TASK]"
|
||||
#include "dbg_log.h"
|
||||
@@ -112,6 +113,10 @@ int net_stack_bring_up(void) {
|
||||
if (phy != CH395F_PHY_DISCONN) {
|
||||
break;
|
||||
}
|
||||
/* 心跳埋点:本循环单次最长约 1.1s(含 PHY 仍未就绪的 60 次迭代里
|
||||
* 每次 50ms 延时叠加),远超看门狗 100ms 抽样窗——必须在延时段补心跳,
|
||||
* 否则 PHY 未插网线时本任务会被误判为卡死(见设计说明 §4.4 长耗时白名单) */
|
||||
task_wd_beat(TASK_WD_NET);
|
||||
osDelay(50);
|
||||
}
|
||||
DBG_INFO("PHY: %s",
|
||||
@@ -166,6 +171,9 @@ void net_task_func(void const *arg) {
|
||||
#if defined(ENABLE_HW_LAYER_TESTS)
|
||||
DBG_INFO("netTask parked: HW-layer test mode, CH395F owned by testTask");
|
||||
for (;;) {
|
||||
/* 该模式下本任务已被 task_wd_required_mask() 剔除,喂心跳无副作用;
|
||||
* 保留埋点以免掩码配置变更时意外误杀 */
|
||||
task_wd_beat(TASK_WD_NET);
|
||||
osDelay(1000);
|
||||
}
|
||||
#endif
|
||||
@@ -196,6 +204,10 @@ void net_task_func(void const *arg) {
|
||||
|
||||
/* ==================== 主轮询循环 ==================== */
|
||||
for (;;) {
|
||||
/* 心跳:本任务在监视掩码内(ENABLE_HW_LAYER_TESTS 下由 task_wd_required_mask
|
||||
* 剔除,本埋点无副作用) */
|
||||
task_wd_beat(TASK_WD_NET);
|
||||
|
||||
/* UI 保存网口配置后请求立即应用:在此重建网络(新 IP/掩码/网关/MAC)。
|
||||
* 重建完成后代次号已递增,各 TCP 服务据此重建监听;期间连接会断开(预期)。 */
|
||||
if (sys_evtHandle != NULL
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "sys_clock.h"
|
||||
#include "test_config.h" /* TEST_LATENCY_PROBE(链路时延探针编译开关) */
|
||||
#include "net_latency_test.h" /* M3 探针:ui_loop(生产循环实测周期) */
|
||||
#include "task_watchdog.h"
|
||||
|
||||
/*
|
||||
* 函数功能:待机屏底部时钟提供回调(平台差异:MCU = sys_clock_get_str)
|
||||
@@ -63,6 +64,9 @@ static void ui_task_wait_net_ready(void) {
|
||||
void ui_task_func(void *argument) {
|
||||
(void)argument;
|
||||
|
||||
/* 等待网络就绪期间不可能喂狗:本任务此时尚未进入主循环,而就绪位由 netTask 置位。
|
||||
* 该段若长期不成立,看门狗会复位——这是期望行为(网络 bring-up 卡死须暴露)。
|
||||
* 注意本任务在 required_mask 内,主循环跑起来后须保证每 100ms 窗口内至少喂一次。 */
|
||||
DBG_INFO("UI task: started, wait net ready");
|
||||
ui_task_wait_net_ready();
|
||||
DBG_INFO("UI task: net ready, init port");
|
||||
@@ -108,6 +112,9 @@ void ui_task_func(void *argument) {
|
||||
#endif
|
||||
ui_port_step(10);
|
||||
ui_net_sink_poll();
|
||||
/* 心跳:ui_port_step 内含 LVGL 渲染,单轮耗时可能逼近 10ms 量级;
|
||||
* 100ms 抽样窗内可容纳多轮,此埋点足够 */
|
||||
task_wd_beat(TASK_WD_UI);
|
||||
osDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 模块名称:Task Watchdog(IWDG + 任务心跳位图)
|
||||
* 模块功能:把独立看门狗(IWDG)与"全部任务存活"绑定,使单任务死锁/饿死/
|
||||
* 断言挂死可自动复位恢复,而非人工断电。
|
||||
* 核心语义:喂狗 = "所有被监视任务都在抽样窗口内动过"。
|
||||
* 适用平台:STM32F407ZGTx + FreeRTOS(CMSIS-RTOS V2)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-29
|
||||
* 修改记录:
|
||||
* v1.0 2026-09-29 王建锋 创建:心跳位图 + 抽样判定 + IWDG 延后启动
|
||||
*
|
||||
* 设计依据:docs/子系统设计/看门狗设计说明.md
|
||||
* - §3.1 为何不用"每任务各自喂狗"(那只检测全系统同时挂死)
|
||||
* - §3.3 为何用"单字位图 + 取走清零"(免临界区,天然原子)
|
||||
* - §4.3 超时与窗口的取值推导(含 LSI 偏快 47kHz 的最坏情况校验)
|
||||
* - §4.5 为何由 defaultTask 在 bring-up 完成后启动
|
||||
* - §5.3 为何"停喂"而不直接 NVIC_SystemReset(保留 IWDGRSTF 权威归因)
|
||||
*
|
||||
* ⚠ 本模块不创建任何 FreeRTOS/CMSIS-RTOS 对象,可安全用于内核启动前后的上下文。
|
||||
*/
|
||||
|
||||
#include "task_watchdog.h"
|
||||
#include "main.h" /* HAL_GetTick()(HAL 时基 = TIM7,1ms) */
|
||||
#include "iwdg.h" /* hiwdg 参数来源(CubeMX 生成,见 Src/iwdg.c) */
|
||||
|
||||
#define DBG_TAG "[WD]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
/* 抽样周期:defaultTask 主循环为 50ms 基准,100ms 是其整数倍(见 §4.3) */
|
||||
#define WD_POLL_PERIOD_MS 100u
|
||||
|
||||
/* 连续未达标容忍次数:8 × 100ms = 800ms。
|
||||
* 需容纳 NAND 擦写(最坏数百 ms)等长耗时操作,同时远小于 IWDG 最坏超时
|
||||
* 1701ms,保证"停喂后仍能复上电"(§4.3 的包含关系) */
|
||||
#define WD_MISS_TOLERANCE 8u
|
||||
|
||||
/* IWDG 超时参数:PR=4 → 64 分频;RLR=1249
|
||||
* 标称 64 × 1249 / 32000 ≈ 2498 ms
|
||||
* 最坏 64 × 1249 / 47000 ≈ 1701 ms(LSI 偏快时超时变短,按最坏校核) */
|
||||
#define WD_IWDG_PRESCALER 4u
|
||||
#define WD_IWDG_RELOAD 1249u
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* 心跳位图:各任务只置位,校验者"取走并清零"。
|
||||
* 单字读-改-写在 Cortex-M4 上天然原子,无需临界区(§3.3) */
|
||||
static volatile uint32_t s_hb_bits;
|
||||
|
||||
static uint32_t s_miss_streak; /* 连续未达标轮数(达到容忍上限即停喂) */
|
||||
static uint32_t s_miss_total; /* 累计未达标轮数(观测用) */
|
||||
static uint32_t s_last_mask; /* 上次抽样到的位图(定位卡死任务用) */
|
||||
static uint32_t s_started; /* 1 = IWDG 已启动 */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
static uint32_t wd_required_mask(void);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* 函数功能:必需心跳位掩码(编译期按构建配置生成)
|
||||
* 入口参数:无
|
||||
* 返回值:本次构建要求"必须动过"的任务位集合
|
||||
* 限定条件:无
|
||||
* 函数说明:按 §4.1/§4.2 的设计,监视范围随构建配置变化:
|
||||
* - testTask 仅在启用测试套件时创建
|
||||
* - netTask 在 ENABLE_HW_LAYER_TESTS 下入口即自挂起(不干活),
|
||||
* 不要求其心跳,否则该构建永不喂狗
|
||||
* 注:ftpTask 当前统一纳入(其主循环为 lftpd 事件循环,需在
|
||||
* lftpd 侧埋点;若某构建下 ftpTask 不创建,句柄检查兜底)。
|
||||
*/
|
||||
static uint32_t wd_required_mask(void) {
|
||||
uint32_t m = (1u << (uint32_t)TASK_WD_DEFAULT)
|
||||
| (1u << (uint32_t)TASK_WD_NET)
|
||||
| (1u << (uint32_t)TASK_WD_FTP)
|
||||
| (1u << (uint32_t)TASK_WD_UI)
|
||||
| (1u << (uint32_t)TASK_WD_TIMESYNC);
|
||||
|
||||
/* netTask 自挂起(CH395F 由 testTask 独占):不要求心跳 */
|
||||
#if defined(ENABLE_HW_LAYER_TESTS)
|
||||
m &= ~(1u << (uint32_t)TASK_WD_NET);
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/* Public functions ----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* 函数功能:任务心跳置位
|
||||
* 入口参数:id - 任务 ID(见 task_watchdog.h)
|
||||
* 返回值:无
|
||||
* 限定条件:可在任意上下文调用(单字写,无内核对象依赖)
|
||||
* 函数说明:各任务在自己的主循环里调用。仅 1~2 条指令。
|
||||
*/
|
||||
void task_wd_beat(task_wd_id_t id) {
|
||||
if ((uint32_t)id < (uint32_t)TASK_WD_ID_MAX) {
|
||||
s_hb_bits |= (1u << (uint32_t)id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:启动 IWDG(延后启动,由 defaultTask 在 bring-up 完成后调用)
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:仅 defaultTask 调用;须在 osKernelStart 之后(本函数只用 HAL/寄存器)
|
||||
* 函数说明:MX_IWDG_Init() 已把参数填入全局 hiwdg(Prescaler/Reload 由 CubeMX
|
||||
* 在 Src/iwdg.c 生成区维护),但不启动(见该文件 IWDG_DEFER_START 注释)。
|
||||
* 此处才真正写 IWDG_Key 启动——使"启动段不喂狗"成立(§4.5)。
|
||||
* IWDG 一旦启动不可停,只能靠复位终止。
|
||||
*/
|
||||
void task_wd_start(void) {
|
||||
if (s_started != 0u) {
|
||||
return;
|
||||
}
|
||||
s_started = 1u;
|
||||
|
||||
/* 启动前先喂一次:让首个抽样窗口从"启动时刻"起算,
|
||||
* 而非从 MX_IWDG_Init 的时刻起算(避免启动后立即超时) */
|
||||
IWDG->KR = 0x0000AAAAu; /* 重装计数器(喂狗) */
|
||||
IWDG->KR = 0x0000CCCCu; /* 启动看门狗 */
|
||||
|
||||
DBG_INFO("[WD] armed: timeout ~2498ms (worst ~1701ms), miss_tol=800ms");
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:心跳抽样与喂狗判定(defaultTask 主循环调用)
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:仅 defaultTask 主循环调用(唯一喂狗者);内部节流到 100ms 一次
|
||||
* 函数说明:取走并清零位图 → 与必需掩码比较:
|
||||
* 全中 → 清零缺失计数并喂狗;
|
||||
* 有缺 → 累计;连续达到 WD_MISS_TOLERANCE 次后**停止喂狗**,
|
||||
* 让 IWDG 自然溢出复位(这样 RCC_CSR 记录的是权威的
|
||||
* IWDGRSTF,而不是 NVIC_SystemReset 留下的 SFTRSTF —— §5.3)。
|
||||
*/
|
||||
void task_wd_poll(void) {
|
||||
static uint32_t s_last_tick;
|
||||
uint32_t now;
|
||||
uint32_t snapshot;
|
||||
|
||||
if (s_started == 0u) {
|
||||
return; /* 未启动:不做任何判定 */
|
||||
}
|
||||
|
||||
now = HAL_GetTick();
|
||||
if ((now - s_last_tick) < WD_POLL_PERIOD_MS) {
|
||||
return; /* 节流:非 100ms 边界直接返回 */
|
||||
}
|
||||
s_last_tick = now;
|
||||
|
||||
snapshot = s_hb_bits; /* 读 */
|
||||
s_hb_bits = 0u; /* 清:语义 = "自上次抽样以来谁动过" */
|
||||
s_last_mask = snapshot;
|
||||
|
||||
if (snapshot == wd_required_mask()) {
|
||||
s_miss_streak = 0u;
|
||||
IWDG->KR = 0x0000AAAAu; /* 全员健康:喂狗 */
|
||||
return;
|
||||
}
|
||||
|
||||
/* 有任务缺席:累计(不喂狗) */
|
||||
s_miss_total++;
|
||||
if (s_miss_streak < WD_MISS_TOLERANCE) {
|
||||
s_miss_streak++;
|
||||
}
|
||||
|
||||
if (s_miss_streak >= WD_MISS_TOLERANCE) {
|
||||
/* 连续 800ms 有任务未动过 → 已停喂 → 约 2.5s 后 IWDG 复位。
|
||||
* 最后遗言走裸 UART(不依赖内核、不遍历指针、有界长度)。 */
|
||||
DBG_ERROR("[WD] task stall: mask=0x%08X req=0x%08X miss=%lu",
|
||||
(unsigned)snapshot,
|
||||
(unsigned)wd_required_mask(),
|
||||
(unsigned long)s_miss_total);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:读上次抽样到的位图(观测/自检用)
|
||||
*/
|
||||
uint32_t task_wd_last_mask(void) {
|
||||
return s_last_mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:读累计未达标轮数(观测/自检用)
|
||||
*/
|
||||
uint32_t task_wd_miss_count(void) {
|
||||
return s_miss_total;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:查询 IWDG 是否已启动(观测/自检用)
|
||||
*/
|
||||
uint32_t task_wd_is_armed(void) {
|
||||
return (s_started != 0u) ? 1u : 0u;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 模块名称:Task Watchdog(IWDG + 任务心跳位图)
|
||||
* 模块功能:独立看门狗与"全部任务存活"绑定的对外接口
|
||||
* 适用平台:STM32F407ZGTx + FreeRTOS(CMSIS-RTOS V2)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09-29
|
||||
* 修改记录:
|
||||
* v1.0 2026-09-29 王建锋 创建
|
||||
*
|
||||
* 设计依据:docs/子系统设计/看门狗设计说明.md
|
||||
*/
|
||||
|
||||
#ifndef TASK_WATCHDOG_H
|
||||
#define TASK_WATCHDOG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 任务 ID(位序号 = 心跳位图上的位置,与必需掩码一一对应)
|
||||
* 顺序一旦确定不要插空/改动,掩码是编译期常量
|
||||
*/
|
||||
typedef enum {
|
||||
TASK_WD_DEFAULT = 0,
|
||||
TASK_WD_NET = 1,
|
||||
TASK_WD_FTP = 2,
|
||||
TASK_WD_TEST = 3,
|
||||
TASK_WD_UI = 4,
|
||||
TASK_WD_TIMESYNC = 5,
|
||||
TASK_WD_ID_MAX
|
||||
} task_wd_id_t;
|
||||
|
||||
/*
|
||||
* 函数功能:任务心跳置位(各任务在自己主循环里调用)
|
||||
* 入口参数:id - 任务 ID
|
||||
* 返回值:无
|
||||
* 限定条件:任意上下文可调(单字原子写、无内核对象依赖)
|
||||
* 函数说明:仅 1~2 条指令,无锁、无阻塞,可放在中断外任意位置。
|
||||
*/
|
||||
void task_wd_beat(task_wd_id_t id);
|
||||
|
||||
/*
|
||||
* 函数功能:启动 IWDG(**延后启动**)
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:仅 defaultTask 在存储 bring-up 完成后调用一次
|
||||
* 函数说明:MX_IWDG_Init() 只填参数不启动(原因见 Src/iwdg.c 的
|
||||
* IWDG_DEFER_START 注释:HAL_IWDG_Init 内部会立即启动,而它被
|
||||
* CubeMX 插在 app_main_init 之前,那段无喂狗点且耗时可达数秒)。
|
||||
* 本函数才真正启动,使"启动段不喂狗、主循环段才喂"成立。
|
||||
*/
|
||||
void task_wd_start(void);
|
||||
|
||||
/*
|
||||
* 函数功能:心跳抽样与喂狗判定
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:仅 defaultTask 主循环调用(唯一喂狗者)
|
||||
* 函数说明:内部节流至 100ms 一次。全员到位才喂狗;连续 800ms 有任务
|
||||
* 缺席则停止喂狗,由 IWDG 自然溢出复位(保留 IWDGRSTF 权威归因)。
|
||||
*/
|
||||
void task_wd_poll(void);
|
||||
|
||||
/* 观测接口(自检 / 串口报告用) */
|
||||
uint32_t task_wd_last_mask(void); /* 上次抽样到的位图(0 位 = 缺席任务) */
|
||||
uint32_t task_wd_miss_count(void); /* 累计未达标轮数 */
|
||||
uint32_t task_wd_is_armed(void); /* 1 = IWDG 已启动 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TASK_WATCHDOG_H */
|
||||
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_iwdg.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of IWDG HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F4xx_HAL_IWDG_H
|
||||
#define STM32F4xx_HAL_IWDG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG IWDG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Exported_Types IWDG Exported Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief IWDG Init structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t Prescaler; /*!< Select the prescaler of the IWDG.
|
||||
This parameter can be a value of @ref IWDG_Prescaler */
|
||||
|
||||
uint32_t Reload; /*!< Specifies the IWDG down-counter reload value.
|
||||
This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */
|
||||
|
||||
} IWDG_InitTypeDef;
|
||||
|
||||
/**
|
||||
* @brief IWDG Handle Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
IWDG_TypeDef *Instance; /*!< Register base address */
|
||||
|
||||
IWDG_InitTypeDef Init; /*!< IWDG required parameters */
|
||||
} IWDG_HandleTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Exported_Constants IWDG Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_Prescaler IWDG Prescaler
|
||||
* @{
|
||||
*/
|
||||
#define IWDG_PRESCALER_4 0x00000000u /*!< IWDG prescaler set to 4 */
|
||||
#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */
|
||||
#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */
|
||||
#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */
|
||||
#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */
|
||||
#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */
|
||||
#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Exported_Macros IWDG Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the IWDG peripheral.
|
||||
* @param __HANDLE__ IWDG handle
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE)
|
||||
|
||||
/**
|
||||
* @brief Reload IWDG counter with value defined in the reload register
|
||||
* (write access to IWDG_PR and IWDG_RLR registers disabled).
|
||||
* @param __HANDLE__ IWDG handle
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Exported_Functions IWDG Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions
|
||||
* @{
|
||||
*/
|
||||
/* Initialization/Start functions ********************************************/
|
||||
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions
|
||||
* @{
|
||||
*/
|
||||
/* I/O operation functions ****************************************************/
|
||||
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Private_Constants IWDG Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief IWDG Key Register BitMask
|
||||
*/
|
||||
#define IWDG_KEY_RELOAD 0x0000AAAAu /*!< IWDG Reload Counter Enable */
|
||||
#define IWDG_KEY_ENABLE 0x0000CCCCu /*!< IWDG Peripheral Enable */
|
||||
#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555u /*!< IWDG KR Write Access Enable */
|
||||
#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000u /*!< IWDG KR Write Access Disable */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Private_Macros IWDG Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable write access to IWDG_PR and IWDG_RLR registers.
|
||||
* @param __HANDLE__ IWDG handle
|
||||
* @retval None
|
||||
*/
|
||||
#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE)
|
||||
|
||||
/**
|
||||
* @brief Disable write access to IWDG_PR and IWDG_RLR registers.
|
||||
* @param __HANDLE__ IWDG handle
|
||||
* @retval None
|
||||
*/
|
||||
#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE)
|
||||
|
||||
/**
|
||||
* @brief Check IWDG prescaler value.
|
||||
* @param __PRESCALER__ IWDG prescaler value
|
||||
* @retval None
|
||||
*/
|
||||
#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_8) || \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_16) || \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_32) || \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_64) || \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_128)|| \
|
||||
((__PRESCALER__) == IWDG_PRESCALER_256))
|
||||
|
||||
/**
|
||||
* @brief Check IWDG reload value.
|
||||
* @param __RELOAD__ IWDG reload value
|
||||
* @retval None
|
||||
*/
|
||||
#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F4xx_HAL_IWDG_H */
|
||||
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_ll_iwdg.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of IWDG LL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F4xx_LL_IWDG_H
|
||||
#define STM32F4xx_LL_IWDG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(IWDG)
|
||||
|
||||
/** @defgroup IWDG_LL IWDG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup IWDG_LL_Private_Constants IWDG Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define LL_IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
|
||||
#define LL_IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
|
||||
#define LL_IWDG_KEY_WR_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
|
||||
#define LL_IWDG_KEY_WR_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup IWDG_LL_Exported_Constants IWDG Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_LL_EC_GET_FLAG Get Flags Defines
|
||||
* @brief Flags defines which can be used with LL_IWDG_ReadReg function
|
||||
* @{
|
||||
*/
|
||||
#define LL_IWDG_SR_PVU IWDG_SR_PVU /*!< Watchdog prescaler value update */
|
||||
#define LL_IWDG_SR_RVU IWDG_SR_RVU /*!< Watchdog counter reload value update */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_LL_EC_PRESCALER Prescaler Divider
|
||||
* @{
|
||||
*/
|
||||
#define LL_IWDG_PRESCALER_4 0x00000000U /*!< Divider by 4 */
|
||||
#define LL_IWDG_PRESCALER_8 (IWDG_PR_PR_0) /*!< Divider by 8 */
|
||||
#define LL_IWDG_PRESCALER_16 (IWDG_PR_PR_1) /*!< Divider by 16 */
|
||||
#define LL_IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< Divider by 32 */
|
||||
#define LL_IWDG_PRESCALER_64 (IWDG_PR_PR_2) /*!< Divider by 64 */
|
||||
#define LL_IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< Divider by 128 */
|
||||
#define LL_IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< Divider by 256 */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/** @defgroup IWDG_LL_Exported_Macros IWDG Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_LL_EM_WRITE_READ Common Write and read registers Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Write a value in IWDG register
|
||||
* @param __INSTANCE__ IWDG Instance
|
||||
* @param __REG__ Register to be written
|
||||
* @param __VALUE__ Value to be written in the register
|
||||
* @retval None
|
||||
*/
|
||||
#define LL_IWDG_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__))
|
||||
|
||||
/**
|
||||
* @brief Read a value in IWDG register
|
||||
* @param __INSTANCE__ IWDG Instance
|
||||
* @param __REG__ Register to be read
|
||||
* @retval Register value
|
||||
*/
|
||||
#define LL_IWDG_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup IWDG_LL_Exported_Functions IWDG Exported Functions
|
||||
* @{
|
||||
*/
|
||||
/** @defgroup IWDG_LL_EF_Configuration Configuration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the Independent Watchdog
|
||||
* @note Except if the hardware watchdog option is selected
|
||||
* @rmtoll KR KEY LL_IWDG_Enable
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_Enable(IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
WRITE_REG(IWDGx->KR, LL_IWDG_KEY_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reloads IWDG counter with value defined in the reload register
|
||||
* @rmtoll KR KEY LL_IWDG_ReloadCounter
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_ReloadCounter(IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
WRITE_REG(IWDGx->KR, LL_IWDG_KEY_RELOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
|
||||
* @rmtoll KR KEY LL_IWDG_EnableWriteAccess
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_EnableWriteAccess(IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
WRITE_REG(IWDGx->KR, LL_IWDG_KEY_WR_ACCESS_ENABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers
|
||||
* @rmtoll KR KEY LL_IWDG_DisableWriteAccess
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_DisableWriteAccess(IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
WRITE_REG(IWDGx->KR, LL_IWDG_KEY_WR_ACCESS_DISABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the prescaler of the IWDG
|
||||
* @rmtoll PR PR LL_IWDG_SetPrescaler
|
||||
* @param IWDGx IWDG Instance
|
||||
* @param Prescaler This parameter can be one of the following values:
|
||||
* @arg @ref LL_IWDG_PRESCALER_4
|
||||
* @arg @ref LL_IWDG_PRESCALER_8
|
||||
* @arg @ref LL_IWDG_PRESCALER_16
|
||||
* @arg @ref LL_IWDG_PRESCALER_32
|
||||
* @arg @ref LL_IWDG_PRESCALER_64
|
||||
* @arg @ref LL_IWDG_PRESCALER_128
|
||||
* @arg @ref LL_IWDG_PRESCALER_256
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_SetPrescaler(IWDG_TypeDef *IWDGx, uint32_t Prescaler)
|
||||
{
|
||||
WRITE_REG(IWDGx->PR, IWDG_PR_PR & Prescaler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the selected prescaler of the IWDG
|
||||
* @rmtoll PR PR LL_IWDG_GetPrescaler
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval Returned value can be one of the following values:
|
||||
* @arg @ref LL_IWDG_PRESCALER_4
|
||||
* @arg @ref LL_IWDG_PRESCALER_8
|
||||
* @arg @ref LL_IWDG_PRESCALER_16
|
||||
* @arg @ref LL_IWDG_PRESCALER_32
|
||||
* @arg @ref LL_IWDG_PRESCALER_64
|
||||
* @arg @ref LL_IWDG_PRESCALER_128
|
||||
* @arg @ref LL_IWDG_PRESCALER_256
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_IWDG_GetPrescaler(const IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
return (READ_REG(IWDGx->PR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specify the IWDG down-counter reload value
|
||||
* @rmtoll RLR RL LL_IWDG_SetReloadCounter
|
||||
* @param IWDGx IWDG Instance
|
||||
* @param Counter Value between Min_Data=0 and Max_Data=0x0FFF
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_IWDG_SetReloadCounter(IWDG_TypeDef *IWDGx, uint32_t Counter)
|
||||
{
|
||||
WRITE_REG(IWDGx->RLR, IWDG_RLR_RL & Counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the specified IWDG down-counter reload value
|
||||
* @rmtoll RLR RL LL_IWDG_GetReloadCounter
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval Value between Min_Data=0 and Max_Data=0x0FFF
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_IWDG_GetReloadCounter(const IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
return (READ_REG(IWDGx->RLR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IWDG_LL_EF_FLAG_Management FLAG_Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Check if flag Prescaler Value Update is set or not
|
||||
* @rmtoll SR PVU LL_IWDG_IsActiveFlag_PVU
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval State of bit (1 or 0).
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_PVU(const IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
return ((READ_BIT(IWDGx->SR, IWDG_SR_PVU) == (IWDG_SR_PVU)) ? 1UL : 0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if flag Reload Value Update is set or not
|
||||
* @rmtoll SR RVU LL_IWDG_IsActiveFlag_RVU
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval State of bit (1 or 0).
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_IWDG_IsActiveFlag_RVU(const IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
return ((READ_BIT(IWDGx->SR, IWDG_SR_RVU) == (IWDG_SR_RVU)) ? 1UL : 0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if flags Prescaler & Reload Value Update are reset or not
|
||||
* @rmtoll SR PVU LL_IWDG_IsReady\n
|
||||
* SR RVU LL_IWDG_IsReady
|
||||
* @param IWDGx IWDG Instance
|
||||
* @retval State of bits (1 or 0).
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_IWDG_IsReady(const IWDG_TypeDef *IWDGx)
|
||||
{
|
||||
return ((READ_BIT(IWDGx->SR, IWDG_SR_PVU | IWDG_SR_RVU) == 0U) ? 1UL : 0UL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* IWDG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F4xx_LL_IWDG_H */
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_iwdg.c
|
||||
* @author MCD Application Team
|
||||
* @brief IWDG HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Independent Watchdog (IWDG) peripheral:
|
||||
* + Initialization and Start functions
|
||||
* + IO operation functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### IWDG Generic features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) The IWDG can be started by either software or hardware (configurable
|
||||
through option byte).
|
||||
|
||||
(+) The IWDG is clocked by the Low-Speed Internal clock (LSI) and thus stays
|
||||
active even if the main clock fails.
|
||||
|
||||
(+) Once the IWDG is started, the LSI is forced ON and both cannot be
|
||||
disabled. The counter starts counting down from the reset value (0xFFF).
|
||||
When it reaches the end of count value (0x000) a reset signal is
|
||||
generated (IWDG reset).
|
||||
|
||||
(+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
|
||||
the IWDG_RLR value is reloaded into the counter and the watchdog reset
|
||||
is prevented.
|
||||
|
||||
(+) The IWDG is implemented in the VDD voltage domain that is still functional
|
||||
in STOP and STANDBY mode (IWDG reset can wake up the CPU from STANDBY).
|
||||
IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
|
||||
reset occurs.
|
||||
|
||||
(+) Debug mode: When the microcontroller enters debug mode (core halted),
|
||||
the IWDG counter either continues to work normally or stops, depending
|
||||
on DBG_IWDG_STOP configuration bit in DBG module, accessible through
|
||||
__HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros.
|
||||
|
||||
[..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
|
||||
The IWDG timeout may vary due to LSI clock frequency dispersion.
|
||||
STM32F4xx devices provide the capability to measure the LSI clock
|
||||
frequency (LSI clock is internally connected to TIM5 CH4 input capture).
|
||||
The measured value can be used to have an IWDG timeout with an
|
||||
acceptable accuracy.
|
||||
|
||||
[..] Default timeout value (necessary for IWDG_SR status register update):
|
||||
Constant LSI_VALUE is defined based on the nominal LSI clock frequency.
|
||||
This frequency being subject to variations as mentioned above, the
|
||||
default timeout value (defined through constant HAL_IWDG_DEFAULT_TIMEOUT
|
||||
below) may become too short or too long.
|
||||
In such cases, this default timeout value can be tuned by redefining
|
||||
the constant LSI_VALUE at user-application level (based, for instance,
|
||||
on the measured LSI clock frequency as explained above).
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Use IWDG using HAL_IWDG_Init() function to :
|
||||
(++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
|
||||
clock is forced ON and IWDG counter starts counting down.
|
||||
(++) Enable write access to configuration registers:
|
||||
IWDG_PR and IWDG_RLR.
|
||||
(++) Configure the IWDG prescaler and counter reload value. This reload
|
||||
value will be loaded in the IWDG counter each time the watchdog is
|
||||
reloaded, then the IWDG will start counting down from this value.
|
||||
(++) Wait for status flags to be reset.
|
||||
|
||||
(#) Then the application program must refresh the IWDG counter at regular
|
||||
intervals during normal operation to prevent an MCU reset, using
|
||||
HAL_IWDG_Refresh() function.
|
||||
|
||||
*** IWDG HAL driver macros list ***
|
||||
====================================
|
||||
[..]
|
||||
Below the list of most used macros in IWDG HAL driver:
|
||||
(+) __HAL_IWDG_START: Enable the IWDG peripheral
|
||||
(+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
|
||||
the reload register
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
/** @addtogroup IWDG
|
||||
* @brief IWDG HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Private_Defines IWDG Private Defines
|
||||
* @{
|
||||
*/
|
||||
/* Status register needs up to 5 LSI clock periods divided by the clock
|
||||
prescaler to be updated. The number of LSI clock periods is upper-rounded to
|
||||
6 for the timeout value calculation.
|
||||
The timeout value is calculated using the highest prescaler (256) and
|
||||
the LSI_VALUE constant. The value of this constant can be changed by the user
|
||||
to take into account possible LSI clock period variations.
|
||||
The timeout value is multiplied by 1000 to be converted in milliseconds.
|
||||
LSI startup time is also considered here by adding LSI_STARTUP_TIME
|
||||
converted in milliseconds. */
|
||||
#define HAL_IWDG_DEFAULT_TIMEOUT (((6UL * 256UL * 1000UL) / (LSI_VALUE / 128U)) + \
|
||||
((LSI_STARTUP_TIME / 1000UL) + 1UL))
|
||||
#define IWDG_KERNEL_UPDATE_FLAGS (IWDG_SR_RVU | IWDG_SR_PVU)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions_Group1
|
||||
* @brief Initialization and Start functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and Start functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the IWDG according to the specified parameters in the
|
||||
IWDG_InitTypeDef of associated handle.
|
||||
(+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
|
||||
is reloaded in order to exit function with correct time base.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the IWDG according to the specified parameters in the
|
||||
* IWDG_InitTypeDef and start watchdog. Before exiting function,
|
||||
* watchdog is refreshed in order to have correct time base.
|
||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Check the IWDG handle allocation */
|
||||
if (hiwdg == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
|
||||
assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
|
||||
assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
|
||||
|
||||
/* Enable IWDG. LSI is turned on automatically */
|
||||
__HAL_IWDG_START(hiwdg);
|
||||
|
||||
/* Enable write access to IWDG_PR and IWDG_RLR registers by writing
|
||||
0x5555 in KR */
|
||||
IWDG_ENABLE_WRITE_ACCESS(hiwdg);
|
||||
|
||||
/* Write to IWDG registers the Prescaler & Reload values to work with */
|
||||
hiwdg->Instance->PR = hiwdg->Init.Prescaler;
|
||||
hiwdg->Instance->RLR = hiwdg->Init.Reload;
|
||||
|
||||
/* Check pending flag, if previous update not done, return timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for register to be updated */
|
||||
while ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
|
||||
{
|
||||
if ((hiwdg->Instance->SR & IWDG_KERNEL_UPDATE_FLAGS) != 0x00u)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reload IWDG counter with value defined in the reload register */
|
||||
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions_Group2
|
||||
* @brief IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Refresh the IWDG.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Refresh the IWDG.
|
||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
|
||||
{
|
||||
/* Reload IWDG counter with value defined in the reload register */
|
||||
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
+12
-2
@@ -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
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file iwdg.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the iwdg.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __IWDG_H__
|
||||
#define __IWDG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern IWDG_HandleTypeDef hiwdg;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_IWDG_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IWDG_H__ */
|
||||
@@ -55,7 +55,7 @@
|
||||
/* #define HAL_HASH_MODULE_ENABLED */
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
/* #define HAL_I2S_MODULE_ENABLED */
|
||||
/* #define HAL_IWDG_MODULE_ENABLED */
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
/* #define HAL_LTDC_MODULE_ENABLED */
|
||||
/* #define HAL_RNG_MODULE_ENABLED */
|
||||
/* #define HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
+196
-267
@@ -1,10 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="project_projx.xsd">
|
||||
<SchemaVersion>2.1</SchemaVersion>
|
||||
|
||||
<Header>### uVision Project, (C) Keil Software</Header>
|
||||
|
||||
<Targets>
|
||||
<Target>
|
||||
<TargetName>STM32F407-Demo</TargetName>
|
||||
@@ -19,28 +16,28 @@
|
||||
<PackID>Keil.STM32F4xx_DFP.3.1.1</PackID>
|
||||
<PackURL>https://www.keil.com/pack/</PackURL>
|
||||
<Cpu>IRAM(0x20000000-0x2001BFFF) IRAM2(0x2001C000-0x2001FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(25000000) FPU2 CPUTYPE("Cortex-M4") TZ</Cpu>
|
||||
<FlashUtilSpec></FlashUtilSpec>
|
||||
<StartupFile></StartupFile>
|
||||
<FlashDriverDll></FlashDriverDll>
|
||||
<FlashUtilSpec />
|
||||
<StartupFile />
|
||||
<FlashDriverDll />
|
||||
<DeviceId>0</DeviceId>
|
||||
<RegisterFile></RegisterFile>
|
||||
<MemoryEnv></MemoryEnv>
|
||||
<Cmp></Cmp>
|
||||
<Asm></Asm>
|
||||
<Linker></Linker>
|
||||
<OHString></OHString>
|
||||
<InfinionOptionDll></InfinionOptionDll>
|
||||
<SLE66CMisc></SLE66CMisc>
|
||||
<SLE66AMisc></SLE66AMisc>
|
||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
||||
<RegisterFile />
|
||||
<MemoryEnv />
|
||||
<Cmp />
|
||||
<Asm />
|
||||
<Linker />
|
||||
<OHString />
|
||||
<InfinionOptionDll />
|
||||
<SLE66CMisc />
|
||||
<SLE66AMisc />
|
||||
<SLE66LinkerMisc />
|
||||
<SFDFile>$$Device:STM32F407ZGTx$CMSIS\SVD\STM32F407.svd</SFDFile>
|
||||
<bCustSvd>0</bCustSvd>
|
||||
<UseEnv>0</UseEnv>
|
||||
<BinPath></BinPath>
|
||||
<IncludePath></IncludePath>
|
||||
<LibPath></LibPath>
|
||||
<RegisterFilePath></RegisterFilePath>
|
||||
<DBRegisterFilePath></DBRegisterFilePath>
|
||||
<BinPath />
|
||||
<IncludePath />
|
||||
<LibPath />
|
||||
<RegisterFilePath />
|
||||
<DBRegisterFilePath />
|
||||
<TargetStatus>
|
||||
<Error>0</Error>
|
||||
<ExitCodeStop>0</ExitCodeStop>
|
||||
@@ -55,15 +52,15 @@
|
||||
<CreateHexFile>1</CreateHexFile>
|
||||
<DebugInformation>1</DebugInformation>
|
||||
<BrowseInformation>1</BrowseInformation>
|
||||
<ListingPath></ListingPath>
|
||||
<ListingPath />
|
||||
<HexFormatSelection>1</HexFormatSelection>
|
||||
<Merge32K>0</Merge32K>
|
||||
<CreateBatchFile>0</CreateBatchFile>
|
||||
<BeforeCompile>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Name />
|
||||
<UserProg2Name />
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopU1X>0</nStopU1X>
|
||||
@@ -72,8 +69,8 @@
|
||||
<BeforeMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>0</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Name />
|
||||
<UserProg2Name />
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopB1X>0</nStopB1X>
|
||||
@@ -82,15 +79,15 @@
|
||||
<AfterMake>
|
||||
<RunUserProg1>0</RunUserProg1>
|
||||
<RunUserProg2>1</RunUserProg2>
|
||||
<UserProg1Name></UserProg1Name>
|
||||
<UserProg2Name></UserProg2Name>
|
||||
<UserProg1Name />
|
||||
<UserProg2Name />
|
||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||
<nStopA1X>0</nStopA1X>
|
||||
<nStopA2X>0</nStopA2X>
|
||||
</AfterMake>
|
||||
<SelectedForBatchBuild>1</SelectedForBatchBuild>
|
||||
<SVCSIdString></SVCSIdString>
|
||||
<SVCSIdString />
|
||||
</TargetCommonOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>0</UseCPPCompiler>
|
||||
@@ -104,8 +101,8 @@
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<CustomArgument />
|
||||
<IncludeLibraryModules />
|
||||
<ComprImg>0</ComprImg>
|
||||
</CommonProperty>
|
||||
<DllOption>
|
||||
@@ -139,10 +136,10 @@
|
||||
<bUseTDR>1</bUseTDR>
|
||||
<Flash2>BIN\UL2CM3.DLL</Flash2>
|
||||
<Flash3>"" ()</Flash3>
|
||||
<Flash4></Flash4>
|
||||
<pFcarmOut></pFcarmOut>
|
||||
<pFcarmGrp></pFcarmGrp>
|
||||
<pFcArmRoot></pFcArmRoot>
|
||||
<Flash4 />
|
||||
<pFcarmOut />
|
||||
<pFcarmGrp />
|
||||
<pFcArmRoot />
|
||||
<FcArmLst>0</FcArmLst>
|
||||
</Utilities>
|
||||
<TargetArmAds>
|
||||
@@ -175,7 +172,7 @@
|
||||
<RvctClst>0</RvctClst>
|
||||
<GenPPlst>0</GenPPlst>
|
||||
<AdsCpuType>"Cortex-M4"</AdsCpuType>
|
||||
<RvctDeviceName></RvctDeviceName>
|
||||
<RvctDeviceName />
|
||||
<mOS>0</mOS>
|
||||
<uocRom>0</uocRom>
|
||||
<uocRam>0</uocRam>
|
||||
@@ -309,7 +306,7 @@
|
||||
<Size>0x0</Size>
|
||||
</OCR_RVCT10>
|
||||
</OnChipMemories>
|
||||
<RvctStartVector></RvctStartVector>
|
||||
<RvctStartVector />
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
@@ -338,7 +335,7 @@
|
||||
<VariousControls>
|
||||
<MiscControls>--diag_suppress=1,68,111,188,191,546,1293</MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F407xx,NDEBUG</Define>
|
||||
<Undefine></Undefine>
|
||||
<Undefine />
|
||||
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../Drivers/BSP/NET/lftpd;../Drivers/BSP/NETCFG;../App;../App/app;../App/cfg;../App/log;../App/sync;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs;../test/board;../Lib/lvgl;../Drivers/BSP/UI;../Lib</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
@@ -354,9 +351,9 @@
|
||||
<useXO>0</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<MiscControls />
|
||||
<Define />
|
||||
<Undefine />
|
||||
<IncludePath>../Drivers/CMSIS/Include</IncludePath>
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
@@ -367,15 +364,15 @@
|
||||
<noStLib>0</noStLib>
|
||||
<RepFail>1</RepFail>
|
||||
<useFile>1</useFile>
|
||||
<TextAddressRange></TextAddressRange>
|
||||
<DataAddressRange></DataAddressRange>
|
||||
<pXoBase></pXoBase>
|
||||
<TextAddressRange />
|
||||
<DataAddressRange />
|
||||
<pXoBase />
|
||||
<ScatterFile>STM32F407-Demo\STM32F407-Demo.sct</ScatterFile>
|
||||
<IncludeLibs></IncludeLibs>
|
||||
<IncludeLibsPath></IncludeLibsPath>
|
||||
<Misc></Misc>
|
||||
<LinkerInputFile></LinkerInputFile>
|
||||
<DisabledWarnings></DisabledWarnings>
|
||||
<IncludeLibs />
|
||||
<IncludeLibsPath />
|
||||
<Misc />
|
||||
<LinkerInputFile />
|
||||
<DisabledWarnings />
|
||||
</LDads>
|
||||
</TargetArmAds>
|
||||
</TargetOption>
|
||||
@@ -420,8 +417,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -449,12 +444,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -476,8 +465,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -505,12 +492,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -532,8 +513,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -561,16 +540,70 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>iwdg.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Src/iwdg.c</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>2</interw>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<thumb>2</thumb>
|
||||
<SplitLS>2</SplitLS>
|
||||
<SwStkChk>2</SwStkChk>
|
||||
<NoWarn>2</NoWarn>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<useXO>2</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
</Aads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>spi.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -588,8 +621,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -617,12 +648,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -644,8 +669,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -673,12 +696,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -710,8 +727,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -739,12 +754,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -784,6 +793,11 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\App\util\sys_clock.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>task_watchdog.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\App\util\task_watchdog.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>time_sync.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -826,8 +840,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -855,12 +867,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -882,8 +888,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -911,12 +915,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1003,8 +1001,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1032,12 +1028,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1059,8 +1049,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1088,16 +1076,70 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f4xx_hal_iwdg.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c</FilePath>
|
||||
<FileOption>
|
||||
<CommonProperty>
|
||||
<UseCPPCompiler>2</UseCPPCompiler>
|
||||
<RVCTCodeConst>0</RVCTCodeConst>
|
||||
<RVCTZI>0</RVCTZI>
|
||||
<RVCTOtherData>0</RVCTOtherData>
|
||||
<ModuleSelection>0</ModuleSelection>
|
||||
<IncludeInBuild>1</IncludeInBuild>
|
||||
<AlwaysBuild>2</AlwaysBuild>
|
||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
<Cads>
|
||||
<interw>2</interw>
|
||||
<Optim>0</Optim>
|
||||
<oTime>2</oTime>
|
||||
<SplitLS>2</SplitLS>
|
||||
<OneElfS>2</OneElfS>
|
||||
<Strict>2</Strict>
|
||||
<EnumInt>2</EnumInt>
|
||||
<PlainCh>2</PlainCh>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<wLevel>0</wLevel>
|
||||
<uThumb>2</uThumb>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<uC99>2</uC99>
|
||||
<uGnu>2</uGnu>
|
||||
<useXO>2</useXO>
|
||||
<v6Lang>0</v6Lang>
|
||||
<v6LangP>0</v6LangP>
|
||||
<vShortEn>2</vShortEn>
|
||||
<vShortWch>2</vShortWch>
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>2</interw>
|
||||
<Ropi>2</Ropi>
|
||||
<Rwpi>2</Rwpi>
|
||||
<thumb>2</thumb>
|
||||
<SplitLS>2</SplitLS>
|
||||
<SwStkChk>2</SwStkChk>
|
||||
<NoWarn>2</NoWarn>
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<useXO>2</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
</Aads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f4xx_hal_spi.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -1115,8 +1157,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1144,12 +1184,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1171,8 +1205,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1200,12 +1232,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1312,8 +1338,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<GroupArmAds>
|
||||
@@ -1341,12 +1365,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
<interw>2</interw>
|
||||
@@ -1359,12 +1377,6 @@
|
||||
<uSurpInc>2</uSurpInc>
|
||||
<useXO>2</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
</GroupArmAds>
|
||||
</GroupOption>
|
||||
@@ -1386,8 +1398,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1415,12 +1425,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1442,8 +1446,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1471,12 +1473,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1498,8 +1494,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1527,12 +1521,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1554,8 +1542,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1583,12 +1569,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1610,8 +1590,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1639,12 +1617,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1666,8 +1638,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1695,12 +1665,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1722,8 +1686,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1751,12 +1713,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1778,8 +1734,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1807,12 +1761,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1834,8 +1782,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1863,12 +1809,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1890,8 +1830,6 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<FileArmAds>
|
||||
@@ -1919,12 +1857,6 @@
|
||||
<v6Lto>2</v6Lto>
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
@@ -1946,8 +1878,8 @@
|
||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||
<PublicsOnly>2</PublicsOnly>
|
||||
<StopOnExitCode>11</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<CustomArgument />
|
||||
<IncludeLibraryModules />
|
||||
<ComprImg>1</ComprImg>
|
||||
</CommonProperty>
|
||||
<GroupArmAds>
|
||||
@@ -1977,9 +1909,9 @@
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls>--diag_suppress=177</MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
<Define />
|
||||
<Undefine />
|
||||
<IncludePath />
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -1994,10 +1926,10 @@
|
||||
<useXO>2</useXO>
|
||||
<ClangAsOpt>1</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
<MiscControls />
|
||||
<Define />
|
||||
<Undefine />
|
||||
<IncludePath />
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
</GroupArmAds>
|
||||
@@ -2085,8 +2017,8 @@
|
||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||
<PublicsOnly>0</PublicsOnly>
|
||||
<StopOnExitCode>3</StopOnExitCode>
|
||||
<CustomArgument></CustomArgument>
|
||||
<IncludeLibraryModules></IncludeLibraryModules>
|
||||
<CustomArgument />
|
||||
<IncludeLibraryModules />
|
||||
<ComprImg>0</ComprImg>
|
||||
</CommonProperty>
|
||||
<GroupArmAds>
|
||||
@@ -2115,10 +2047,10 @@
|
||||
<v6WtE>2</v6WtE>
|
||||
<v6Rtti>2</v6Rtti>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
<MiscControls />
|
||||
<Define />
|
||||
<Undefine />
|
||||
<IncludePath />
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -2133,10 +2065,10 @@
|
||||
<useXO>2</useXO>
|
||||
<ClangAsOpt>0</ClangAsOpt>
|
||||
<VariousControls>
|
||||
<MiscControls></MiscControls>
|
||||
<Define></Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath></IncludePath>
|
||||
<MiscControls />
|
||||
<Define />
|
||||
<Undefine />
|
||||
<IncludePath />
|
||||
</VariousControls>
|
||||
</Aads>
|
||||
</GroupArmAds>
|
||||
@@ -3245,20 +3177,18 @@
|
||||
</Groups>
|
||||
</Target>
|
||||
</Targets>
|
||||
|
||||
<RTE>
|
||||
<apis/>
|
||||
<apis />
|
||||
<components>
|
||||
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="5.5.0" condition="ARMv6_7_8-M Device">
|
||||
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.8.0"/>
|
||||
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="5.8.0" />
|
||||
<targetInfos>
|
||||
<targetInfo name="STM32F407-Demo"/>
|
||||
<targetInfo name="STM32F407-Demo" />
|
||||
</targetInfos>
|
||||
</component>
|
||||
</components>
|
||||
<files/>
|
||||
<files />
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
@@ -3267,5 +3197,4 @@
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
|
||||
+23
-16
@@ -73,28 +73,32 @@ FREERTOS.Events01=sys_evt,Dynamic,NULL
|
||||
FREERTOS.FootprintOK=true
|
||||
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01,Events01
|
||||
FREERTOS.Queues01=netMsgQueue,8,net_msg_t,0,Dynamic,NULL,NULL
|
||||
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL;testTask,16,1024,start_test_task,As weak,NULL,Dynamic,NULL,NULL;uiTask,16,4096,StartUiTask,Default,NULL,Dynamic,NULL,NULL
|
||||
FREERTOS.Tasks01=defaultTask,24,1024,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL;testTask,16,2048,start_test_task,As weak,NULL,Dynamic,NULL,NULL;uiTask,16,4096,StartUiTask,Default,NULL,Dynamic,NULL,NULL
|
||||
FREERTOS.configENABLE_FPU=1
|
||||
FREERTOS.configTOTAL_HEAP_SIZE=49152
|
||||
File.Version=6
|
||||
GPIO.groupedBy=Group By Peripherals
|
||||
IWDG.IPParameters=Prescaler,Reload
|
||||
IWDG.Prescaler=IWDG_PRESCALER_64
|
||||
IWDG.Reload=1249
|
||||
KeepUserPlacement=false
|
||||
Mcu.CPN=STM32F407ZGT6
|
||||
Mcu.Family=STM32F4
|
||||
Mcu.IP0=DMA
|
||||
Mcu.IP1=FREERTOS
|
||||
Mcu.IP10=USART1
|
||||
Mcu.IP11=USART2
|
||||
Mcu.IP12=USART3
|
||||
Mcu.IP10=UART5
|
||||
Mcu.IP11=USART1
|
||||
Mcu.IP12=USART2
|
||||
Mcu.IP13=USART3
|
||||
Mcu.IP2=I2C1
|
||||
Mcu.IP3=NVIC
|
||||
Mcu.IP4=RCC
|
||||
Mcu.IP5=SPI1
|
||||
Mcu.IP6=SPI2
|
||||
Mcu.IP7=SYS
|
||||
Mcu.IP8=UART4
|
||||
Mcu.IP9=UART5
|
||||
Mcu.IPNb=13
|
||||
Mcu.IP3=IWDG
|
||||
Mcu.IP4=NVIC
|
||||
Mcu.IP5=RCC
|
||||
Mcu.IP6=SPI1
|
||||
Mcu.IP7=SPI2
|
||||
Mcu.IP8=SYS
|
||||
Mcu.IP9=UART4
|
||||
Mcu.IPNb=14
|
||||
Mcu.Name=STM32F407Z(E-G)Tx
|
||||
Mcu.Package=LQFP144
|
||||
Mcu.Pin0=PE5
|
||||
@@ -151,12 +155,13 @@ Mcu.Pin54=PB8
|
||||
Mcu.Pin55=PE0
|
||||
Mcu.Pin56=PE1
|
||||
Mcu.Pin57=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin58=VP_SYS_VS_tim7
|
||||
Mcu.Pin58=VP_IWDG_VS_IWDG
|
||||
Mcu.Pin59=VP_SYS_VS_tim7
|
||||
Mcu.Pin6=PB2
|
||||
Mcu.Pin7=PF11
|
||||
Mcu.Pin8=PF12
|
||||
Mcu.Pin9=PG0
|
||||
Mcu.PinsNb=59
|
||||
Mcu.PinsNb=60
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F407ZGTx
|
||||
@@ -484,7 +489,7 @@ PH1-OSC_OUT.Mode=HSE-External-Oscillator
|
||||
PH1-OSC_OUT.Signal=RCC_OSC_OUT
|
||||
PinOutPanel.RotationAngle=0
|
||||
ProjectManager.AskForMigrate=true
|
||||
ProjectManager.BackupPrevious=false
|
||||
ProjectManager.BackupPrevious=true
|
||||
ProjectManager.CompilerLinker=GCC
|
||||
ProjectManager.CompilerOptimize=6
|
||||
ProjectManager.ComputerToolchain=false
|
||||
@@ -515,7 +520,7 @@ ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
ProjectManager.UAScriptBeforePath=
|
||||
ProjectManager.UnderRoot=false
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true,8-MX_UART4_Init-UART4-false-HAL-true,9-MX_UART5_Init-UART5-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true,8-MX_UART4_Init-UART4-false-HAL-true,9-MX_UART5_Init-UART5-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_IWDG_Init-IWDG-false-HAL-true
|
||||
RCC.48MHZClocksFreq_Value=84000000
|
||||
RCC.AHBFreq_Value=168000000
|
||||
RCC.APB1CLKDivider=RCC_HCLK_DIV4
|
||||
@@ -575,6 +580,8 @@ USART3.IPParameters=VirtualMode
|
||||
USART3.VirtualMode=VM_ASYNC
|
||||
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
||||
VP_IWDG_VS_IWDG.Mode=IWDG_Activate
|
||||
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
|
||||
VP_SYS_VS_tim7.Mode=TIM7
|
||||
VP_SYS_VS_tim7.Signal=SYS_VS_tim7
|
||||
board=custom
|
||||
|
||||
@@ -358,4 +358,73 @@ void vApplicationMallocFailedHook(void)
|
||||
|
||||
dbg_console_write_raw(msg, (unsigned)(sizeof(msg) - 1u));
|
||||
}
|
||||
|
||||
/*
|
||||
* 断言失败钩子(2026-09-29,配合 IWDG;见 Inc/FreeRTOSConfig.h 的 configASSERT)。
|
||||
* 与栈溢出钩子同为"内核状态已不可信"路径:裸 UART 有界输出 + 主动复位,
|
||||
* 不走 printf / 内核对象 / 控制台锁。
|
||||
* 设计取舍(docs/子系统设计/看门狗设计说明.md §4.6):
|
||||
* - 上报 file/line 是断言唯一有价值的现场信息,故必须打印(早于 TCB 名之类);
|
||||
* - 打印后**主动 NVIC_SystemReset()** 而非空转:断言点未必能让 IWDG 抓到
|
||||
* (若恰在启动段,IWDG 尚未启动),主动复位保证任何断言都能自恢复;
|
||||
* 代价是 RCC_CSR 记 SFTRSTF 而非 IWDGRSTF——故上报串里写死 ASSERT 字样,
|
||||
* 使"重启原因"可由日志区分(软件复位 + 上一条是 ASSERT = 断言导致)。
|
||||
*/
|
||||
void vApplicationAssertFailed(const char *file, long line)
|
||||
{
|
||||
static const char msg_head[] = "\r\n[ERR] ASSERT FAILED ";
|
||||
const char *p = file;
|
||||
char num[16];
|
||||
int i;
|
||||
|
||||
/* 文件名只取末段(全路径太长且无信息量) */
|
||||
if (p != NULL) {
|
||||
const char *q = p;
|
||||
while (*q != '\0') {
|
||||
if ((*q == '/') || (*q == '\\')) {
|
||||
p = q + 1;
|
||||
}
|
||||
q++;
|
||||
}
|
||||
/* 有界拷贝:上限 48 字符 */
|
||||
{
|
||||
uint16_t len = 0u;
|
||||
char name[49];
|
||||
while ((len < 48u) && (p[len] != '\0')) {
|
||||
name[len] = p[len];
|
||||
len++;
|
||||
}
|
||||
name[len] = '\0';
|
||||
dbg_console_write_raw(msg_head, (unsigned)(sizeof(msg_head) - 1u));
|
||||
dbg_console_write_raw(name, (unsigned)len);
|
||||
}
|
||||
} else {
|
||||
dbg_console_write_raw(msg_head, (unsigned)(sizeof(msg_head) - 1u));
|
||||
dbg_console_write_raw("(no file)", 9u);
|
||||
}
|
||||
|
||||
dbg_console_write_raw(":", 1u);
|
||||
|
||||
/* 行号转十进制(不用 snprintf:钩子可能在临界区,且避免库依赖) */
|
||||
i = 0;
|
||||
if (line <= 0) {
|
||||
num[i++] = '0';
|
||||
} else {
|
||||
char rev[16];
|
||||
int n = 0;
|
||||
while ((line > 0) && (n < 15)) {
|
||||
rev[n++] = (char)('0' + (line % 10));
|
||||
line /= 10;
|
||||
}
|
||||
while (n > 0) {
|
||||
num[i++] = rev[--n];
|
||||
}
|
||||
}
|
||||
dbg_console_write_raw(num, (unsigned)i);
|
||||
|
||||
dbg_console_write_raw(" (resetting)\r\n", 15u);
|
||||
|
||||
HAL_Delay(200); /* 等 UART 移位寄存器排空 */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
/* USER CODE END Application */
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file iwdg.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the IWDG instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "iwdg.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
IWDG_HandleTypeDef hiwdg;
|
||||
|
||||
/* IWDG init function */
|
||||
void MX_IWDG_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN IWDG_Init 0 */
|
||||
|
||||
/* USER CODE END IWDG_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN IWDG_Init 1 */
|
||||
|
||||
/* USER CODE END IWDG_Init 1 */
|
||||
hiwdg.Instance = IWDG;
|
||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
|
||||
hiwdg.Init.Reload = 1249;
|
||||
/* USER CODE BEGIN IWDG_DEFER_START */
|
||||
/* ⚠ 生成区改动(唯一一处):原为 `HAL_IWDG_Init(&hiwdg)` 直呼。
|
||||
* 原因:HAL_IWDG_Init() 内部第一句即 __HAL_IWDG_START()(立即启动看门狗,
|
||||
* 之后不可停、只能复位)。而本函数被 CubeMX 插在 main() 的 MX_*_Init 序列里,
|
||||
* 早于 app_main_init()——那段含 NAND 初始化/RTC/ADC,耗时可达数秒且无喂狗点,
|
||||
* 按 2.5s 超时最坏值(≈1.7s)必然复位 → 开机死循环(2026-09-29 实测确认)。
|
||||
* 故本函数降级为**只填参数不启动**;启动动作移交
|
||||
* task_wd_start()(App/util/task_watchdog.c),由 defaultTask 在存储 bring-up
|
||||
* 完成后调用——即"启动段不喂狗、主循环段才喂"的设计(见
|
||||
* docs/子系统设计/看门狗设计说明.md §4.5)。
|
||||
* 若 CubeMX 重生成覆盖此处,表现为"开机即复位",按本注释恢复即可。 */
|
||||
/* USER CODE END IWDG_DEFER_START */
|
||||
/* USER CODE BEGIN IWDG_Init 2 */
|
||||
|
||||
/* USER CODE END IWDG_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
+15
-2
@@ -21,6 +21,7 @@
|
||||
#include "cmsis_os.h"
|
||||
#include "dma.h"
|
||||
#include "i2c.h"
|
||||
#include "iwdg.h"
|
||||
#include "spi.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
@@ -90,7 +91,17 @@ int main(void)
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* 复位原因锁存(2026-09-29,配合 IWDG):RCC_CSR 的复位标志只由上电复位(POR)
|
||||
* 清除,其余复位(看门狗/软件/引脚/欠压)会跨复位保留——若不主动清除,
|
||||
* 上一次的 IWDGRSTF 会一直挂着,导致每次启动都被误记为"看门狗复位"。
|
||||
* 故在 HAL_Init()(此时 RCC 可用、串口尚未就绪)之后**立即读取并清除**,
|
||||
* 锁存到 RCC_CSR 影子变量,待日志子系统起来后由 app_main_init 打印。
|
||||
* 注意顺序:读 → 写 RMVF 清除,两步之间不可插入其它可能复位的代码。 */
|
||||
{
|
||||
extern volatile uint32_t g_rcc_csr_latched; /* 定义于 app_main.c,供启动日志读取 */
|
||||
g_rcc_csr_latched = RCC->CSR; /* 锁存:含 IWDGRSTF/SFTRSTF/PORRSTF 等 */
|
||||
RCC->CSR |= RCC_CSR_RMVF; /* 写 1 清全部复位标志(只清标志,不影响时钟) */
|
||||
}
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
@@ -111,6 +122,7 @@ int main(void)
|
||||
MX_UART5_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
MX_IWDG_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
HAL_Delay(100);
|
||||
|
||||
@@ -155,8 +167,9 @@ void SystemClock_Config(void)
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLM = 4;
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ docs/
|
||||
| [`系统墙钟时间维护说明.md`](子系统设计/系统墙钟时间维护说明.md) | `sys_clock`:RTC 基准、tick 回绕防护、30 天惰性再基准化 |
|
||||
| [`控制台单写者日志设计说明.md`](子系统设计/控制台单写者日志设计说明.md) | 控制台日志单写者模型(避免多任务交错输出) |
|
||||
| [`运行与自检记录设计说明.md`](子系统设计/运行与自检记录设计说明.md) | `/log/run.log`·`selftest.log` 定长记录与待机显示 |
|
||||
| [`看门狗设计说明.md`](子系统设计/看门狗设计说明.md) | **调研+方案(待实施)**:IWDG 选型、任务心跳位图、复位原因分类、验证计划 |
|
||||
| [`看门狗设计说明.md`](子系统设计/看门狗设计说明.md) | **实施中**:IWDG(CubeMX 配置)+ 任务心跳位图;代码已落地编译通过,待台架故障注入/长跑验证 |
|
||||
| [`网络/BSD_Socket_API_使用指南.md`](网络/BSD_Socket_API_使用指南.md) | **上层视图**:BSD Socket API 公开语义、示例、常见问题 |
|
||||
| [`网络/BSD_Socket_API_函数调用关系.md`](网络/BSD_Socket_API_函数调用关系.md) | **内部视图**:netTask / 消息队列 / L3 挂起 / 重试对账的调用关系与设计意图 |
|
||||
| [`网络/Net层阻塞模型架构设计.md`](网络/Net层阻塞模型架构设计.md) | **等待模型**:pending 请求架构、五路完成语义、设计边界与性能特征 |
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| ER_IROM1 | 261,932 B (255.79 KB) | 1,048,576 B (1024 KB) | 25.0% |
|
||||
| RW_IRAM1 | 87,040 B (85.00 KB) | 131,072 B (128 KB) | 66.4% |
|
||||
| ER_IROM1 | 264,860 B (258.65 KB) | 1,048,576 B (1024 KB) | 25.3% |
|
||||
| RW_IRAM1 | 87,080 B (85.04 KB) | 131,072 B (128 KB) | 66.4% |
|
||||
| RW_CCM | 49,184 B (48.03 KB) | 65,536 B (64 KB) | 75.0% |
|
||||
| **Flash (ROM 合计)** | **262,660 B (256.5 KB)** | 1,048,576 B (1024 KB) | **25.0%** |
|
||||
| **Flash (ROM 合计)** | **265,616 B (259.4 KB)** | 1,048,576 B (1024 KB) | **25.3%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
|
||||
+132
-60
@@ -1,9 +1,10 @@
|
||||
# 看门狗设计说明
|
||||
|
||||
> **模块名称**:独立看门狗(IWDG)+ 任务心跳位图
|
||||
> **文档定位**:**调研 + 设计方案**——记录选型依据、在既有平台上落地的约束、
|
||||
> 推荐架构与分步实施路径。**尚未实施**,实施后本文件应改写为"现状设计说明"。
|
||||
> **状态**:📋 设计完成,待实施(登记于 [`../待处理内容.md`](../待处理内容.md) N-03)
|
||||
> **文档定位**:**实施中**——记录选型依据、在既有平台上落地的约束、实现现状与
|
||||
> 待台架验证项。**代码骨架已落地并编译通过**(§10 第 0~6 步);第 7~10 步
|
||||
> (故障注入 / 长跑 / 本文档转为"现状设计说明")待台架。
|
||||
> **状态**:🚧 代码已落地(`@build` 0/0),**待台架故障注入与长跑验证**;登记于 [`../待处理内容.md`](../待处理内容.md) N-03
|
||||
> **日期**:2026-09-29
|
||||
> **相关文档**:
|
||||
> [`../审查记录/项目审查与优化建议报告.md`](../审查记录/项目审查与优化建议报告.md)(N-03 缺陷原始登记)、
|
||||
@@ -33,8 +34,7 @@
|
||||
|
||||
> ⚠️ **实施路径因此改变**:`HAL_IWDG_MODULE_ENABLED` 不是一个"取消注释即可"的开关——
|
||||
> 取消后 `stm32f4xx_hal_conf.h` 会去 include 一个**不存在的头文件**,直接编译失败。
|
||||
> 本方案因此**不走 HAL 驱动,改用直接寄存器操作**(见 §2.2)——这反而是更优路径,
|
||||
> 因为 CMSIS 设备头**已提供完整的 IWDG 寄存器定义与实例指针**,零新增依赖。
|
||||
> 故须**由 CubeMX 勾选 IWDG 后重生成**,让驱动源码与 HUD 开关一并就位(见 §2.2)。
|
||||
|
||||
### 1.2 现存的两处"假保护"
|
||||
|
||||
@@ -108,7 +108,14 @@ T_IWDG = (4 × 2^PR) × RLR / F_LSI
|
||||
**本方案选定(见 §4.3)**:`PR=4`(64 分频)/ `RLR=1249` → 标称 **2498 ms**、
|
||||
最坏 **≈1701 ms**。
|
||||
|
||||
### 2.2 实施路径:直接寄存器操作,不引入 HAL IWDG 驱动
|
||||
### 2.2 实施路径:**走 CubeMX 生成**(原方案为直接寄存器,已变更)
|
||||
|
||||
> **变更说明(2026-09-29)**:本节初稿推荐"直接寄存器操作"(下称路径 C),依据是
|
||||
> HAL IWDG 驱动源码不在仓库。经与项目负责人确认,**改走 CubeMX 图形界面生成**
|
||||
> (路径 A)——让 `.ioc` 成为配置的唯一事实源、与其他外设保持一致。路径 A 的
|
||||
> 原评估"高风险"已被本次实践证伪:重生成带来的定制覆盖是**有限且可枚举**的
|
||||
> (实测见 §10 第 2 步),处理方式已固化为"重生成 → 逐项恢复 → 编译验证"。
|
||||
> 以下保留路径比较,作为决策记录。
|
||||
|
||||
**约束事实**(§1.1 表的第 3、4 行):HAL IWDG 驱动源码**不在仓库**、也**不在 MDK 工程**中。
|
||||
CubeMX 只在勾选该外设时才会把 `stm32f4xx_hal_iwdg.c/h` 拷进 `Drivers/STM32F4xx_HAL_Driver/`。
|
||||
@@ -120,16 +127,44 @@ CubeMX 只在勾选该外设时才会把 `stm32f4xx_hal_iwdg.c/h` 拷进 `Driver
|
||||
|
||||
| 路径 | 做法 | 评估 |
|
||||
|---|---|---|
|
||||
| A. 从 CubeMX 重新生成(勾选 IWDG) | 用 `.ioc` 勾选 IWDG 后生成 | ❌ **高风险**:CubeMX 重生成会重写 `Src/`/`Inc/` 生成区,项目有大量既存定制(见 `AGENTS.md`「平台约束」),且会带回行尾空白抖动(2026-09-20 已记录过该问题) |
|
||||
| B. 手工补入 `stm32f4xx_hal_iwdg.c/h` | 从 STM32CubeF4 包拷贝两文件 + 注册进 MDK 工程 | ⚠️ 可行但需**手改 `.uvprojx`**(XML 结构脆弱),且引入约 0.3 KB Flash 的 HAL 封装 |
|
||||
| **C. 直接寄存器操作**(**本方案选定**) | 用 CMSIS 已提供的 `IWDG` 实例指针 + 寄存器位域宏 | ✅ **零新增依赖、零工程文件改动、代码量约 20 行** |
|
||||
| **A. 从 CubeMX 重新生成(勾选 IWDG)**(**实际采用**) | 用 `.ioc` 勾选 IWDG 后生成 | ✅ **配置单一事实源、与其他外设一致**;代价 = 需恢复被覆盖的既有定制(实测 4 处,见 §10 第 2 步),且须按 `AGENTS.md` 处理行尾空白抖动 |
|
||||
| B. 手工补入 `stm32f4xx_hal_iwdg.c/h` | 从 STM32CubeF4 包拷贝两文件 + 注册进 MDK 工程 | ⚠️ 需**手改 `.uvprojx`**(XML 结构脆弱),且引入约 0.3 KB Flash 的 HAL 封装;`.ioc` 与代码脱节 |
|
||||
| C. 直接寄存器操作(初稿推荐,**已放弃**) | 用 CMSIS 已提供的 `IWDG` 实例指针 + 寄存器位域宏 | ✅ 零新增依赖、零工程文件改动、约 20 行;❌ 但**破坏了"外设配置统一由 CubeMX 表达"的约定**,后续维护者无处可查"这台设备的 IWDG 配了什么" |
|
||||
|
||||
**选 C 的依据**:CMSIS 设备头 `Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f407xx.h`
|
||||
**已完整提供**所需的一切(已实测确认):
|
||||
**选 A 的依据**:本项目的既有约定是"外设配置 = `.ioc`"(`AGENTS.md`「平台约束」:
|
||||
`Inc/`/`Src/` 中 CubeMX 生成文件带 `USER CODE` 标记,自定义代码只写标记区内)。
|
||||
IWDG 若用裸寄存器,则分频/重载值只散落在 `App/util/task_watchdog.c` 的宏里,
|
||||
与 `.ioc` 无关联——下一个维护者改超时值时**不会想到去改代码宏**。
|
||||
路径 A 让该配置出现在 CubeMX 界面里,符合项目惯例。
|
||||
|
||||
**CubeMX 侧配置值**(在 `.ioc` / CubeMX 图形界面填写):
|
||||
|
||||
| 项 | 值 | 说明 |
|
||||
|---|---|---|
|
||||
| Activated | ✅ 勾选 | Peripheral 树 → IWDG |
|
||||
| IWDG counter clock prescaler | **64** | 对应 `IWDG_PRESCALER_64`,即 `PR=4` |
|
||||
| IWDG down-counter reload value | **1249** | 12 位,范围 0~4095 |
|
||||
| Window value | —— | ⚠️ **本 HAL 版本 `IWDG_InitTypeDef` 无此字段**(仅 `Prescaler` / `Reload`),CubeMX 界面亦无该项;窗口寄存器保持复位默认 `0xFFF` = 禁用窗口,符合预期 |
|
||||
|
||||
生成结果:`Src/iwdg.c` / `Inc/iwdg.h`(新文件)、`Drivers/STM32F4xx_HAL_Driver/{Inc,Src}/stm32f4xx_hal_iwdg.{h,c}`、
|
||||
`Inc/stm32f4xx_hal_conf.h` 中 `HAL_IWDG_MODULE_ENABLED` 解除注释、`.uvprojx` 挂载驱动、
|
||||
`Src/main.c` 的 `MX_*_Init()` 序列新增 `MX_IWDG_Init()`。
|
||||
|
||||
> ⚠️ **路径 A 的固有陷阱(本次实测踩中,P0)**:CubeMX 把 `MX_IWDG_Init()` 插在
|
||||
> `app_main_init()` **之前**,而 `HAL_IWDG_Init()` 内部第一句即
|
||||
> `__HAL_IWDG_START(hiwdg)`(立即启动、之后不可停)。启动段(NAND 初始化等)耗时
|
||||
> 可达数秒且无喂狗点 → 按 2.5s 超时必然复位 → **开机死循环**。
|
||||
> **CubeMX 界面无法关闭这个自动启动**(HAL 行为,无对应选项)。
|
||||
> 解决办法见 §4.5 决策 C:把 `Src/iwdg.c` 里那一行 `HAL_IWDG_Init(&hiwdg)` 换成
|
||||
> 只填参数的 USER CODE 注释块,启动动作移交 `task_wd_start()`。
|
||||
> 这是路径 A 下**唯一必须手工修改生成文件**的地方,已在文件内留注释说明恢复方法。
|
||||
|
||||
**参考:CMSIS 设备头已提供的寄存器定义**(路径 C 曾依赖,现仅作 `task_wd_beat`/`task_wd_poll`
|
||||
里裸写 `IWDG->KR` 的依据):
|
||||
|
||||
| 已有定义 | 位置 | 内容 |
|
||||
|---|---|---|
|
||||
| `IWDG_TypeDef` | `:573-579` | `KR` / `PR` / `RLR` / `SR` 四寄存器结构体 |
|
||||
| `IWDG_TypeDef` | `stm32f407xx.h:573-579` | `KR` / `PR` / `RLR` / `SR` 四寄存器结构体 |
|
||||
| `IWDG_BASE` | `:944` | `APB1PERIPH_BASE + 0x3000` |
|
||||
| `IWDG` 实例指针 | `:1068` | `((IWDG_TypeDef *) IWDG_BASE)` |
|
||||
| `IWDG_KR_KEY_Msk` | `:9331` | 键值字段掩码 |
|
||||
@@ -137,7 +172,7 @@ CubeMX 只在勾选该外设时才会把 `stm32f4xx_hal_iwdg.c/h` 拷进 `Driver
|
||||
| `IWDG_RLR_RL_Msk` | `:9344` | 重装值字段(12 位) |
|
||||
| `IWDG_SR_PVU` / `IWDG_SR_RVU` | `:9349-9353` | 更新进行中标志(须轮询等它清零) |
|
||||
|
||||
**键值常量**(上游 HAL 在 `stm32f4xx_hal_iwdg.h` 定义,本方案需自行定义):
|
||||
**键值常量**(由 HAL 定义在 `stm32f4xx_hal_iwdg.h`,本方案在 `task_watchdog.c` 内裸写):
|
||||
|
||||
| 用途 | 值 |
|
||||
|---|---|
|
||||
@@ -149,9 +184,10 @@ CubeMX 只在勾选该外设时才会把 `stm32f4xx_hal_iwdg.c/h` 拷进 `Driver
|
||||
IWDG 是**"写键值"式外设**:写 `0x5555` 解锁 → 配 `PR`/`RLR` → 写 `0xCCCC` 启动
|
||||
(启动后**不可停**,只能复位)→ 此后周期性写 `0xAAAA` 喂狗。
|
||||
|
||||
> **为何这会被称为"更优路径"**:HAL 的 `HAL_IWDG_Init()` 内部做的事就是上面这几步,
|
||||
> 外加一个 `IWDG_HandleTypeDef` 状态机。本项目不需要那层封装——寄存器操作总共
|
||||
> 约 20 行,且完全落在 `App/util/task_watchdog.c` 内,**不触碰任何 CubeMX 生成文件**。
|
||||
> **喂狗为何仍走裸寄存器而非 `HAL_IWDG_Refresh()`**:喂狗是 100 ms 级高频操作,
|
||||
> HAL 封装带 `IWDG_HandleTypeDef` 有效性检查(读 `State` 字段、判 `LOCKED`),
|
||||
> 在高频路径上无收益。`Task_wd_poll()` 里写 `IWDG->KR = 0xAAAA` 是 1 条存储指令。
|
||||
> 这不是"绕过 HAL",而是"HAL 提供了该寄存器定义,直接用"——与路径选择无关。
|
||||
|
||||
---
|
||||
|
||||
@@ -558,22 +594,24 @@ void task_wd_poll(void)
|
||||
> 丢失"是看门狗抓到的"这一关键信息。**让 IWDG 自然溢出**,
|
||||
> 复位原因才是权威的 `watchdog reset`。代价是额外的 ≤2.5 s 延迟(可接受)。
|
||||
|
||||
### 5.4 各任务的埋点位置
|
||||
### 5.4 各任务的埋点位置(**2026-09-29 已全部落地**)
|
||||
|
||||
| 任务 | 埋点位置 | 备注 |
|
||||
| 任务 | 实际埋点位置 | 备注 |
|
||||
|---|---|---|
|
||||
| `defaultTask` | `default_task_func` 的 `for(;;)` 循环首行 | 50 ms 节拍,天然满足 |
|
||||
| `netTask` | 主循环 `for(;;)` 内(`net_poll` 之后) | 1 ms 节拍;另需在 `net_stack_bring_up` 的 PHY 等待循环内补埋点(§4.4) |
|
||||
| `ftpTask` | ⚠️ 见 §4.3 —— 第一步**剔除掩码**;后续改 `Lib/lftpd` 时再补 | 已知缺口 |
|
||||
| `uiTask` | `ui_task_func` 主循环(`osDelay(10)` 处) | 10 ms 节拍 |
|
||||
| `timeSyncTask` | `time_sync_task` 主循环 | 最长 `vTaskDelay(2000)`——⚠️ **2 s > 800 ms 容忍窗口**,需拆分:在 `vTaskDelay` 前多次分段置位,或把该 timeout 缩短 |
|
||||
| `testTask` | 由套件掩码决定 | 套件运行时可长阻塞,按 §4.1 排除 |
|
||||
| `defaultTask` | `App/task/default_task.c`:`for(;;)` 首行 `task_wd_poll()` + `task_wd_beat(TASK_WD_DEFAULT)` | 50 ms 节拍,天然满足;同时是唯一喂狗者 |
|
||||
| `netTask` | `App/task/net_task.c`:① 主循环 `for(;;)` 首行;② `net_stack_bring_up` 的 PHY 等待循环内 `osDelay(50)` 前;③ `ENABLE_HW_LAYER_TESTS` 自挂起分支(掩码已剔除,埋点无副作用) | ② 为 §4.4 白名单项:PHY 最长等待 3 s(60×50 ms),必须在其中补心跳 |
|
||||
| `ftpTask` | ⚠️ **首期不埋点**——由 `wd_required_mask()` **剔除**(见 §4.3) | 已知缺口:`Lib/lftpd` 事件循环改动面大,二期再补 |
|
||||
| `uiTask` | `App/task/ui_task.c`:`ui_port_step(10)` / `ui_net_sink_poll()` 之后 | 10 ms 节拍;等待 NET_READY 期间不喂属**预期**(该段卡死即应复位) |
|
||||
| `timeSyncTask` | `App/sync/time_sync.c`:① `time_sync_task` 主循环首行;② 监听重试的 500 ms / 2 s 延时前;③ accept 轮询 200 ms 延时前;④ 收尾 50 ms 延时前;⑤ **`time_sync_handle_conn` 内的等待循环**(关键:把 30 s 总预算切成 `TIME_SYNC_WAIT_SLICE_MS`=200 ms 的片,每片先喂心跳) | ⑤ 是本案最要害的一处:对端连上但不发时间包是完全正常的场景,若不切片,30 s 等待必然被判卡死 |
|
||||
| `testTask` | 不埋点——由套件掩码决定,按 §4.1 排除 | 套件运行时可长阻塞 |
|
||||
|
||||
> ⚠️ **`timeSyncTask` 是关键风险点**:其主循环有两处 `vTaskDelay(pdMS_TO_TICKS(2000))`
|
||||
> (`App/sync/time_sync.c:68/75`)。若心跳位只在循环首行,则 2 s 内位图恒缺席,
|
||||
> **必然触发停喂**。处理三选一:① 每 200 ms 分段置位;② 缩短该 delay;
|
||||
> ③ 该任务单独用"宽松窗口"(增大容忍次数到 25 次 = 2.5 s,但会逼近 IWDG 超时,不推荐)。
|
||||
> **推荐 ①**:把 2 s 拆成 10 × 200 ms 循环,每次置位并检查退出条件——语义不变,且提升响应性。
|
||||
> ⚠️ **实施时的新发现(补充 §4.4 白名单)**:`timeSyncTask` 的风险**不止**
|
||||
> 主循环里那两处 `vTaskDelay(2000)`——`time_sync_handle_conn` 内部的
|
||||
> `net_recv_to(..., rem)` 单次可睡满 **30 s 总预算**。初稿只注意到 `vTaskDelay`
|
||||
> 的两处,会漏掉这处。处理方式取"**切片**"而非"放宽窗口":
|
||||
> 新增 `TIME_SYNC_WAIT_SLICE_MS = 200U`,把单次等待的 `rem` 夹到 ≤200 ms,
|
||||
> 每片先 `task_wd_beat()`。总预算语义(≤30 s)完全不变,只是把一次长睡眠
|
||||
> 拆成多次短睡眠——同时提升了"对端提前到达"的响应粒度。
|
||||
|
||||
---
|
||||
|
||||
@@ -581,26 +619,41 @@ void task_wd_poll(void)
|
||||
|
||||
### 6.1 串口标记(供 `@test` 采集)
|
||||
|
||||
**实际实现**(2026-09-29 落地,`App/app/app_main.c` + `App/util/task_watchdog.c` +
|
||||
`Src/freertos.c`):
|
||||
|
||||
| 标记 | 时机 | 含义 |
|
||||
|---|---|---|
|
||||
| `[WD] reset cause=<类型>` | `app_main_init` 早期 | 复位原因(`power on` / `watchdog reset` / `soft reset` / `pin reset`) |
|
||||
| `[WD] watchdog armed (timeout=2500ms)` | `task_wd_start()` | IWDG 已启动(真机自检必查标记) |
|
||||
| `[WD] miss streak=<n> mask=0x%08X` | 每次未达标(限流打印) | 谁没动(`mask` 中 0 位 = 缺失任务) |
|
||||
| `[ERR] WATCHDOG: task stall` | 停喂时 | 即将复位,最后遗言 |
|
||||
| `[WD] beat ok` | 可选,调试期 | 心跳正常(默认关闭,避免刷屏) |
|
||||
| `[APP] reset cause: <类型> (CSR=0x%08X)` | `app_main_init` 早期 | 复位原因,类型为 `IWDG (independent watchdog)` / `WWDG (window watchdog)` / `software (NVIC_SystemReset)` / `power-on (POR)` / `external pin (NRST)` / `brown-out (BOR)` / `unknown`;同时打印 `RCC_CSR` 原值便于事后核对 |
|
||||
| `[WD] armed: timeout ~2498ms (worst ~1701ms), miss_tol=800ms` | `task_wd_start()` | IWDG 已启动(真机自检必查标记) |
|
||||
| `[WD] task stall: mask=0x%08X req=0x%08X miss=%lu` | 连续 8 窗未达标时(每窗一次,共打印至复位) | 即将停喂 → 约 2.5 s 后 IWDG 复位。`mask` 的 0 位 = 缺席任务 |
|
||||
| `[ERR] ASSERT FAILED <file>:<line> (resetting)` | `vApplicationAssertFailed()` | FreeRTOS 断言失败(`Src/freertos.c`),打印后主动复位 |
|
||||
| `[ERR] STACK OVERFLOW task=<name>` | `vApplicationStackOverflowHook` | 既有钩子(栈溢出) |
|
||||
| `[ERR] MALLOC FAILED (heap exhausted)` | `vApplicationMallocFailedHook` | 既有钩子(堆耗尽,只告警不复位) |
|
||||
|
||||
> 日志标签说明:`[APP]` 是 `App/app/app_main.c` 的 `DBG_TAG`;`[WD]` 是
|
||||
> `App/util/task_watchdog.c` 的 `DBG_TAG`(定义在两个 include 之间,
|
||||
> 是 `dbg_log.h` 的既有取标签方式)。全部为纯 ASCII,规避 `AGENTS.md` 记载的
|
||||
> ARMCC CP936 字符串字面量陷阱。
|
||||
|
||||
### 6.2 与 `run.log` 的集成
|
||||
|
||||
`sys_log_mcu.c` 的 `syslog_mcu_mounted()` 当前只写 `power on` / `reboot`
|
||||
(靠 `run.log` 末条 epoch 时间差推断)。**改为优先用硬件标志**:
|
||||
(靠 `run.log` 末条 epoch 时间差推断)。**现状:未改**——本次实施选择
|
||||
"先只在串口上报 `reset cause`",理由:
|
||||
|
||||
1. 串口标记已经能支撑 `@test` 判定与人工归因,`run.log` 的价值在于**长期累计**;
|
||||
2. 写 `run.log` 涉及 UI 字符集("看门狗"三字是否在位)与既有 600 s 时间窗分类逻辑,
|
||||
改动面比串口上报大,**留作二期**(`待处理内容.md` N-03 后续项)。
|
||||
|
||||
**二期计划**(复位原因映射表,优先级见 §4.8):
|
||||
|
||||
```
|
||||
复位原因(§4.8 优先级)→ 描述串映射:
|
||||
power on → "power on" (既有)
|
||||
watchdog reset → "watchdog" (新增,UI 字符集需补"看门狗"三字)
|
||||
soft reset → "soft reset" (新增)
|
||||
pin reset → "pin reset" (新增)
|
||||
其余 → 回退既有 600s 时间窗分类
|
||||
power-on (POR) → "power on" (既有)
|
||||
IWDG / WWDG → "watchdog" (新增,UI 字符集需补"看门狗"三字)
|
||||
software → "soft reset" (新增)
|
||||
external pin → "pin reset" (新增)
|
||||
其余 → 回退既有 600s 时间窗分类
|
||||
```
|
||||
|
||||
> ⚠️ **UI 字符集影响**:`docs/子系统设计/运行与自检记录设计说明.md` §6.1 记录了
|
||||
@@ -685,24 +738,42 @@ void task_wd_poll(void)
|
||||
|
||||
## 10. 实施步骤(按序执行,每步端到端验证)
|
||||
|
||||
| 步 | 内容 | 验证 |
|
||||
|---|---|---|
|
||||
| **1** | 新建 `App/util/task_watchdog.c/h`;实现 IWDG 寄存器级 `wd_iwdg_init/feed` + 心跳位图;**登记进 MDK 工程** | `@build` 0/0 |
|
||||
| **2** | `Src/main.c` 复位原因锁存 + 清标志;`syslog_mcu.c` 写描述串 | V7/V8(`cause` 正确) |
|
||||
| **3** | 实现抽样判定 + 串口标记(**暂不启动 IWDG**) | V1 观察 `[WD] beat ok`(调试期) |
|
||||
| **4** | 各任务埋点(含 `timeSyncTask` 拆分) | V5 短跑(5 min)无 `miss` 打印 |
|
||||
| **5** | `task_wd_start()` 启动 IWDG(写 `0xCCCC`) | V1 + V5 |
|
||||
| **6** | `configASSERT` 改造 + `vApplicationAssertFailed()` | V3 |
|
||||
| **7** | 故障注入(V2/V4) | 复位 + `cause` 正确 |
|
||||
| **8** | 模拟器 `--watchdogtest` + stub | S1 |
|
||||
| **9** | 长跑(V5,≥30 min,真实负载) | **零复位** |
|
||||
| **10** | 本文档改写为"现状设计说明";`待处理内容.md` N-03 销项;`README.md` 登记 | 门禁 |
|
||||
| 步 | 内容 | 验证 | 状态 |
|
||||
|---|---|---|---|
|
||||
| **0** | **(新增)** CubeMX 勾选 IWDG(Prescaler=64 / Reload=1249)→ 重生成 → **恢复被覆盖的定制** | `@build` 0/0 + 启动日志齐全 | ✅ **2026-09-29 完成**,覆盖 4 处见下 |
|
||||
| **1** | 新建 `App/util/task_watchdog.c/h`;实现心跳位图 + 抽样判定 + IWDG 延后启动;**登记进 MDK 工程**(`App` 组,`sys_clock.c` 之后) | `@build` 0/0 | ✅ 完成 |
|
||||
| **2** | `Src/main.c` 复位原因锁存 + 清标志;`App/app/app_main.c` 打印描述串 | `[APP] reset cause:` 出现 | ✅ 完成(`run.log` 写入留二期) |
|
||||
| **3** | `Src/iwdg.c` 阻止 `HAL_IWDG_Init()` 自动启动(P0) | 开机不死循环 | ✅ 完成 |
|
||||
| **4** | 各任务埋点(含 `timeSyncTask` **切片**而非拆 delay) | 编译 0/0;串口无 `miss` | ✅ 完成 |
|
||||
| **5** | `task_wd_start()` 由 `defaultTask` 在 bring-up 完成后调用 | `[WD] armed:` 出现 | ✅ 完成 |
|
||||
| **6** | `configASSERT` 改造 + `vApplicationAssertFailed()` | 编译 0/0 | ✅ 完成 |
|
||||
| **7** | 故障注入(V2/V4):人为制造任务卡死 | 复位 + `reset cause: IWDG` | ⏳ **待台架** |
|
||||
| **8** | 模拟器 `--watchdogtest` + stub | S1 | ⏳ 待做 |
|
||||
| **9** | 长跑(V5,≥30 min,真实负载) | **零复位** | ⏳ **待台架** |
|
||||
| **10** | 本文档改写为"现状设计说明";`待处理内容.md` N-03 销项;`README.md` 登记 | 门禁 | ⏳ 待第 7~9 步结论 |
|
||||
|
||||
> **每步改完必须 `@build` 0 错误 0 警告**(`AGENTS.md` 铁律)。
|
||||
>
|
||||
> **第 1 步的风险点**:`App/util/task_watchdog.c` 需在 `MDK-ARM/*.uvprojx` 中挂载。
|
||||
> 若挂载不顺,可临时把实现放进 `App/task/default_task.c`(已在工程内)验证逻辑,
|
||||
> 待工程文件可改时再抽成独立模块。**两种形态的逻辑完全一致**。
|
||||
### 10.1 第 0 步实测:CubeMX 重生成覆盖了哪 4 处
|
||||
|
||||
`.ioc` 的 `ProjectManager.DeletePrevious=true` + `KeepUserCode=true` 决定了
|
||||
**只有 `USER CODE BEGIN/END` 标记区内的代码受保护**。实测被覆盖的定制:
|
||||
|
||||
| 级别 | 文件 | 被覆盖内容 | 恢复方式 |
|
||||
|---|---|---|---|
|
||||
| **P0** | `Src/iwdg.c`(新文件) | CubeMX 生成的 `MX_IWDG_Init()` 直接调 `HAL_IWDG_Init()` → 开机死循环 | 改为只填参数;插 `USER CODE BEGIN IWDG_DEFER_START` 注释块说明(**唯一必需的手工改动**) |
|
||||
| **P1** | `Src/stm32f4xx_it.c` | `HardFault_Handler` 崩溃现场采集(91 行:PC/LR/xPSR/R0-R3/CFSR/HFSR/BFAR/MMFAR)被打回空 `while(1)` | 整块换回手工版(`__asm void` 汇编取 MSP/PSP + `hard_fault_report`) |
|
||||
| **P1** | `Inc/FreeRTOSConfig.h` | `configCHECK_FOR_STACK_OVERFLOW 2` + `configUSE_MALLOC_FAILED_HOOK 1` **整个块被删除** | 插回 `USER CODE BEGIN FREE_RTOS_CONFIG_HARDENING` 块 |
|
||||
| **P2** | `Src/freertos.c` | 三处中文注释丢失(任务栈大小的实测记录) | 恢复注释(栈**数值**未丢,`.ioc` 同步到位) |
|
||||
|
||||
> ⚠️ **P1 两处的教训**:它们都在 `USER CODE` 标记区**之外**(`stm32f4xx_it.c` 的
|
||||
> `HardFault_Handler` 由 CubeMX 直接生成;`FreeRTOSConfig.h` 的加固宏原本写在
|
||||
> 非 `USER CODE` 区)。**P1 的丢失不会立刻暴露**——栈溢出检测与堆失败钩子只在
|
||||
> 真发生溢出/耗尽时才起作用,且 `HardFault_Handler` 被打回空死循环后
|
||||
> **崩溃时连现场都打不出来**(只剩 IWDG 兜底复位,但归因信息全丢)。
|
||||
> 故本次已把这三个宏搬进 `USER CODE BEGIN 1` 区,并加注释
|
||||
> "⚠ 本段为手工添加,CubeMX 重生成会删除(2026-09-29 实测),改完须核对本块存在"。
|
||||
|
||||
> **每步改完必须 `@build` 0 错误 0 警告**(`AGENTS.md` 铁律)。第 0~6 步已一次性
|
||||
> 验证通过:`BUILD_OK: 0 errors, 0 warnings`。
|
||||
|
||||
---
|
||||
|
||||
@@ -711,7 +782,7 @@ void task_wd_poll(void)
|
||||
| 议题 | 结论 |
|
||||
|---|---|
|
||||
| **选型** | **IWDG**(独立 LSI),非 WWDG(依赖 APB1 + 中断,在关中断/HardFault 场景失效) |
|
||||
| **实施路径** | **直接寄存器操作**(不引入 HAL IWDG 驱动)——驱动源码不在仓库、也未经由 CubeMX 生成,CMSIS 设备头已提供全部寄存器定义(§2.2) |
|
||||
| **实施路径** | **CubeMX 勾选 IWDG 生成**(`.ioc` = 配置单一事实源,与其他外设一致);唯一手工改动 = `Src/iwdg.c` 中阻止 `HAL_IWDG_Init()` 立即启动(§2.2 / §4.5) |
|
||||
| **架构** | **任务心跳位图(各自置位,无锁单字)+ defaultTask 单一喂狗者**——避免"有人跑就喂狗"的假保护 |
|
||||
| **超时** | 2498 ms(PR=4 / RLR=1249);最坏(LSI 47 kHz)≈1701 ms;中间留 800 ms 停喂判定裕度 |
|
||||
| **启动时机** | **defaultTask bring-up 完成后**——绕开初始化深链超时陷阱,代价是启动段无保护 |
|
||||
@@ -768,4 +839,5 @@ void task_wd_poll(void)
|
||||
| 日期 | 变更 | 说明 |
|
||||
|---|---|---|
|
||||
| 2026-09-29 | 创建 | 调研 + 设计方案:IWDG + 任务心跳位图;含选型、九项设计决策、验证计划与风险清单 |
|
||||
| 2026-09-29 | 修正实施路径 | 实测发现 HAL IWDG 驱动源码不在仓库且未编入 MDK 工程 → 改为**直接寄存器操作**(§2.2 路径 C);超时数值按公式核算修正;补 `RCC_CSR`/`IWDG` 寄存器定义的实测行号 |
|
||||
| 2026-09-29 | 修正实施路径 | 实测发现 HAL IWDG 驱动源码不在仓库且未编入 MDK 工程 → 初稿改为**直接寄存器操作**(§2.2 路径 C);超时数值按公式核算修正;补 `RCC_CSR`/`IWDG` 寄存器定义的实测行号 |
|
||||
| 2026-09-29 | **路径再变更 + 实施落地** | 决策改走 **CubeMX 图形配置**(§2.2 路径 A):`HAL_IWDG_MODULE_ENABLED` 改为经 CubeMX 生成(避免"取消注释即编译失败")。同时落地 §5 骨架到 `App/util/task_watchdog.{c,h}`,各任务埋点(default/net/ui/time_sync),`RCC_CSR` 复位原因锁存(`Src/main.c` + `App/app/app_main.c`),`configASSERT` 改为 `vApplicationAssertFailed()`。实测 CubeMX 重生成覆盖 4 处既有定制(P0×1 + P1×2 + P2×1),已全部恢复,`@build` 0 错误 0 警告 |
|
||||
|
||||
+4
-3
@@ -30,6 +30,7 @@
|
||||
|
||||
| # | 事项 | 说明 | 出处 |
|
||||
|---|---|---|---|
|
||||
| N-03 | **引入独立看门狗(IWDG)+ 任务心跳位图**——现状全库无看门狗(HAL 驱动源码也不在仓库),任何形态死机不可自恢复;另 `configASSERT` 为关中断死循环(连日志都不打)。**设计方案已完成**(含选型、九项决策、验证计划、风险清单),待实施 | **设计见 [`子系统设计/看门狗设计说明.md`](子系统设计/看门狗设计说明.md)**;实施路径为直接寄存器操作(不引入 HAL IWDG 驱动);实施后本文档改写为现状设计说明并销项 | `审查记录/项目审查与优化建议报告.md` N-03a/b/c |
|
||||
| N-03a | `configASSERT(x)` = `taskDISABLE_INTERRUPTS(); for(;;);`(`Inc/FreeRTOSConfig.h:163`)→ 断言时无任何输出 | 修复方案见 `看门狗设计说明.md` §4.6(改为"先记录后复位");N-03 实施时一并处理 | 同上 N-03b |
|
||||
| N-03b | 启动段(`app_main_init` + `defaultTask` bring-up)在新方案下**无看门狗保护** | 显式代价:`看门狗设计说明.md` §4.5 决策 C + §9 R1;该段死机表现为"无输出 + LED 不闪" | 同上 N-03c |
|
||||
| N-03 | **引入独立看门狗(IWDG)+ 任务心跳位图**——现状全库无看门狗(HAL 驱动源码也不在仓库),任何形态死机不可自恢复;另 `configASSERT` 为关中断死循环(连日志都不打)。**代码已落地并编译通过(2026-09-29)**:CubeMX 生成 IWDG(Prescaler=64/Reload=1249)+ `App/util/task_watchdog.{c,h}` 心跳位图 + 6 任务埋点 + `RCC_CSR` 复位原因锁存 + `configASSERT` 改造 | **剩台架验证**(故障注入 V2/V4、长跑 V5 ≥30 min);文档 §10 第 7~10 步待办 | **见 [`子系统设计/看门狗设计说明.md`](子系统设计/看门狗设计说明.md)**(§10 有实施状态表) | `审查记录/项目审查与优化建议报告.md` N-03a/b/c |
|
||||
| N-03a | `configASSERT(x)` = `taskDISABLE_INTERRUPTS(); for(;;);`(`Inc/FreeRTOSConfig.h`)→ 断言时无任何输出 | ✅ **已修(2026-09-29)**:改为 `vApplicationAssertFailed(__FILE__, __LINE__)`,打印文件名+行号后主动复位(`Src/freertos.c`);宏已迁入 `USER CODE BEGIN 1` 区防重生成丢失 | 同上 N-03b |
|
||||
| N-03b | 启动段(`app_main_init` + `defaultTask` bring-up)在新方案下**无看门狗保护** | 显式代价(未变):`看门狗设计说明.md` §4.5 决策 C + §9 R1;该段死机表现为"无输出 + LED 不闪" | 同上 N-03c |
|
||||
| N-03c | **CubeMX 重生成会覆盖 `USER CODE` 标记区之外的定制** | ⚠️ **2026-09-29 实测确认**:重生成覆盖 4 处(P0 `Src/iwdg.c` 自动启动、P1 `HardFault_Handler` 打回空死循环、P1 `FreeRTOSConfig.h` 两个加固宏被删、P2 `freertos.c` 中文注释);已全部恢复并加"重生成会删除"警示注释;**今后每次 CubeMX 重生成后须重跑本文档 §10.1 的核对清单** | 本次实施记录 |
|
||||
|
||||
Reference in New Issue
Block a user