fix(ui): Task #32 P0/P1/P2 — 解耦 UI 心跳、修 adc 压环与截止期、加测量探针
Task #32 UI 看门狗停摆(docs/问题记录/UI任务看门狗停摆分析.md) P0 adc_task.c(已上板验证): - 仅 r==1 才压环+重算;上板印证 ring==frames(修前 ring=frames+idle) - osDelayUntil 返回值重同步,落后拉回基准,解除永久空转死锁 P1-4a ui_task.c v1.3: task_wd_beat 提到 ui_net_sink_poll 之前 → 心跳测"UI 活着"而非"netTask 响应",解开 §4.2 心跳依赖 → 未上 P1-3(提优先级会掩盖 §4.2/§4.4);P1-5 暂缓 P2 新增 App/util/task_prof.c/.h: DWT 常开探针,测各任务周期/耗时/ 推流往返/ADC 轮询/控制台排空/syslog 落盘/net_poll 最坏值;心跳位图 1→0 边沿裸 UART 直发 [PROF]/[PROF2] 快照;uvprojx 已登记 doc: 分析 doc §7 补良性启动 episode 与复位非诊断项;§8 加处置落地 验证: P0+P1 累计 32 次上板启动 0/32 复现(原 L2 基线 3/10),构建 0/0
This commit is contained in:
@@ -19,6 +19,10 @@
|
||||
* FTP 文件操作与 syslog/配置的卷访问自此串行化
|
||||
* (2026-10-02 台架:并发 FTL 写 → journal 竞争 →
|
||||
* 本任务主循环喂狗点饥饿 → IWDG 误复位)
|
||||
* v1.2 2026-10-10 王建锋 Task #32 的 P2 测量接线:主循环周期上报各任务最坏
|
||||
* 耗时(task_prof_report),并在**心跳位图出现 1→0 边沿**
|
||||
* 的瞬间留一份现场快照(task_prof_report_raw,裸 UART);
|
||||
* 另给控制台排空与 syslog 落盘各加一个耗时探针
|
||||
*/
|
||||
|
||||
#include "default_task.h"
|
||||
@@ -39,6 +43,7 @@
|
||||
#define DBG_LINE_BUF_MAX 128U
|
||||
#include "dbg_log.h"
|
||||
#include "task_watchdog.h"
|
||||
#include "task_prof.h" /* P2 测量:各任务最坏耗时上报(Task #32) */
|
||||
#include "vol_lock.h"
|
||||
|
||||
/* 任务句柄与属性块(CubeMX 生成全局,定义于 Src/freertos.c):
|
||||
@@ -185,6 +190,22 @@ void default_task_func(void *argument) {
|
||||
task_wd_seg(TASK_WD_SEG_POLL);
|
||||
/* 心跳抽样与喂狗判定(内部节流至 100ms;全员到位才喂,否则累计停喂) */
|
||||
task_wd_poll();
|
||||
/* P2 测量(Task #32):某位由"到过"变为"缺席"的瞬间留一份现场快照。
|
||||
* 走裸 UART 直发——缺席窗口内环形缓冲可能积压,这两行必须出去。
|
||||
*
|
||||
* ⚠ 判据用**位图边沿**,不能用 miss 累计数:`task_wd_miss_count()` 返回的是
|
||||
* 单调累计的 s_miss_total(永不清零),开机 bring-up 阶段任务尚未全部启动时
|
||||
* 就已经 >0 → 若以"归零"判恢复,则首次缺席之后再也不会触发。
|
||||
* 位图边沿(某位 1→0)天然"每个 episode 只报一次":此后 prev 也不含该位。 */
|
||||
{
|
||||
static uint32_t s_prof_prev_mask;
|
||||
const uint32_t mask = task_wd_last_mask();
|
||||
|
||||
if ((s_prof_prev_mask != 0u) && ((s_prof_prev_mask & ~mask) != 0u)) {
|
||||
task_prof_report_raw();
|
||||
}
|
||||
s_prof_prev_mask = mask;
|
||||
}
|
||||
/* 本任务自己的心跳 */
|
||||
task_wd_beat(TASK_WD_DEFAULT);
|
||||
/* 等待"保存网络配置"或"控制台待发":任一即醒;无事件 50ms 后返回
|
||||
@@ -197,7 +218,12 @@ void default_task_func(void *argument) {
|
||||
}
|
||||
/* 控制台唯一发送点:把环形缓冲中的日志按块发出(无待发时立即返回) */
|
||||
task_wd_seg(TASK_WD_SEG_DRAIN);
|
||||
/* P2 探针:控制台排空单独计时。它内部**忙等** UART TXE(单次预算
|
||||
* DBG_CON_DRAIN_BUDGET_MS=250ms),且本任务为 osPriorityNormal →
|
||||
* 是"某个 Normal 任务连续占用 CPU 把 UI 饿死"的头号候选 */
|
||||
task_prof_enter(TASK_PROF_DEF_DRAIN);
|
||||
dbg_console_drain();
|
||||
task_prof_exit(TASK_PROF_DEF_DRAIN);
|
||||
/* 控制台 TX 故障留痕:由本任务(syslog 唯一写者)在 drain **之外**补记 run.log。
|
||||
* console_log 内部刻意不调 syslog_post —— 那会构成日志调用图成环,
|
||||
* 让 armlink 静态栈深在每个任务上都多叠一条日志尾巴(见 console_log.c) */
|
||||
@@ -252,11 +278,21 @@ void default_task_func(void *argument) {
|
||||
#if !defined(TEST_SUITE_STORAGE)
|
||||
/* 排空运行期日志(上电/重启分类与自检故障落盘) */
|
||||
task_wd_seg(TASK_WD_SEG_SYSLOG);
|
||||
/* P2 探针:syslog 落盘(NAND/FTL 写,最坏数百 ms)单独计时 */
|
||||
task_prof_enter(TASK_PROF_DEF_SYSLOG);
|
||||
syslog_drain();
|
||||
task_prof_exit(TASK_PROF_DEF_SYSLOG);
|
||||
#endif
|
||||
/* 栈水位观测:首次 5s 后报告,此后每 2s 采样、出现更深峰值才打印 */
|
||||
task_wd_seg(TASK_WD_SEG_STACK);
|
||||
stack_probe_poll();
|
||||
/* P2 测量(Task #32):各任务最坏耗时 / 次数 / "仍在段内"快照。
|
||||
* 内部节流(首次 5s,此后每 2s);判据:
|
||||
* uisn 持续增长 → uiTask 卡在 ui_net_sink_poll 的往返里(阻塞)
|
||||
* uipn 持续增长而 uisn 为 0 → 被调度饿死(本轮迟迟跑不完)
|
||||
* uiw 大 → uiTask 自身渲染拖长
|
||||
* [PROF2] 的 defd/netp/adcp 谁在同一窗口抬起来 → 谁就是占用者 */
|
||||
task_prof_report();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user