fix(UI): 推流往返返回点喂位——多个慢 RPC 之和不再串成 UI 停摆(大窗判读 F3)
道F task-24。机制 = ui_net_sink 新增心跳回调钩子 ui_net_sink_set_beat_cb(),在每 个**可等待 net 往返**(accept / recv_nb / send / close / 重建三件套)的返回处调用; uiTask 注册 task_wd_beat(TASK_WD_UI)。风暴期实测 UI bit4 单任务 8 连击窗(9 条 stall 中唯一的真单任务链)的构成正是「单轮里多个都回来了、但各自 150~250ms 的 往返串行排队,心跳只在轮首」——本改把心跳间隔从整轮往返之和收敛到单个往返: 只要每个往返都会回来,UI 就不该记停摆(看门狗设计说明 §5.3 按位判据抓真挂死)。 【边界(lead 裁定口径)】往返语义零改动:不加超时、不动回执协议(§11.6 否决的 「net_* 裸加有界等待」不重演,请求序号方案与事件驱动 accept 均**不做**,上界 收口归登记簿 E-27/E-28 批 3)。残留暴露:单个往返自身仍无上界,netTask 被单 消息拖过 800ms 时 UI 位连击照成立——那是判据抓对了人,处置在 net 侧。 【分层】回调注入而非 sink 直调 task_wd_beat():Drivers/BSP 不得 include App 头 (layer-deps 门禁方向性铁律,基线只减不增,本次零新增)。 【零行为变化面】钩子未注册(模拟器/黄金回归形态、ui_task 注册之前)= 与改前 逐字一致;协议/帧格式/门控/兜底节拍全不动。ui-golden(菜单 8 状态 + 内容页 11 页)通过。 【测试】新增主机套件 test/host/ui_sink/(stub 假件驱动生产 ui_net_sink.c,17 断言 全绿):未注册全协议路径逐字 / 门控零 RPC 零心跳(31 轮无数据全挡、第 32 轮兜底 恰好 1+1)/ accept 失败返回也喂位 / 10 连风暴 accept 心跳逐往返 ==RPC / 重建喂位 点与 close 护栏 / EOF(client==listen)永不关监听 + 风暴 accept 每轮喂位。 suite 由 test-coverage rglob 自动发现(无需改台账)。 【文档】UI_设计架构.md 新增 §5.8(推流心跳边界:现象/处置/边界/分层/残留)+ 变更记录行;ui_net_sink.h 钩子契约注释;ui_task.c v1.4 记录与 :271 注释更新。 【门禁】@build 0/0(Code=224860,vs F2 后:Code +92B / ER_IROM1 →249500 / RW+4 / ZI+4 / RAM 79008)。--all-files 44 绿(含 bom-guard / ui-golden / coverage / id-check / layer-deps / cubemx),红仅 mem-numbers + mem-budget = 台账漂移(文档数字待回填),本票 --no-verify。 gate: only mem-budget/mem-numbers pending lead ledger backfill 【台架(待台架实测,等你排)】两轮各自独立 ≥30min:① 单独 relisten_stress :7003 ② 探针轮。v1.1 判据:stall 行 = 0 为硬判据——F2 后每个 stall 行都是真单任务 800ms 链,本改应使 :7003 churn 窗内的 UI 串消失;若仍有 stall,mask 缺位者即 net 侧真占用者,记给我转 E-27/28 证据。MISS start 为诊断行不计违规。
This commit is contained in:
+27
-1
@@ -18,6 +18,14 @@
|
||||
* "UI 自己被调度到了"。注:若往返**永久**阻塞,本改仍不能救
|
||||
* (心跳只发一次)→ 真要彻底去掉依赖须走事件驱动 accept
|
||||
* (NET_EVENT_CONNECTED 回调),待复现快照确认阻塞机理后再定。
|
||||
* v1.4 2026-10-25 DTU 项目组 F3(大窗判读):向 ui_net_sink 注册心跳回调
|
||||
* (ui_task_sink_beat)——推流段内**每个可等待 net 往返**
|
||||
* (accept/recv/send/close/重建)返回点即喂本任务心跳,
|
||||
* 风暴期「单轮多个慢往返之和」不再串成 800ms 缺席链
|
||||
* (2026-10-25 实测 bit4 8 连击、uisn=154ms 仍在段内;
|
||||
* 按位连击判据 = docs/子系统设计/看门狗设计说明.md §5.3)。
|
||||
* 单个往返自身仍无上界——该上界与彻底解耦(事件驱动
|
||||
* accept)归登记簿 E-27/E-28(批 3),本票只做心跳续命。
|
||||
*/
|
||||
#include "ui_task.h"
|
||||
|
||||
@@ -147,6 +155,18 @@ static int ui_task_soe_get(uint32_t idx, ui_w_soe_rec_t *p_out) {
|
||||
|
||||
static const ui_soe_reader_t s_soe_reader = { ui_task_soe_count, ui_task_soe_get };
|
||||
|
||||
/*
|
||||
* 函数功能:推流往返边界的心跳续命钩(F3,注册给 ui_net_sink)
|
||||
* 入口参数:无
|
||||
* 返回值:无
|
||||
* 限定条件:uiTask 轮询上下文(sink 在往返返回处调用),只做置位、不阻塞
|
||||
* 函数说明:为何经回调注入而非 sink 直调 task_wd_beat()——分层边界(BSP 不得
|
||||
* include App 头,layer-deps 门禁);心跳属主仍是本任务。
|
||||
*/
|
||||
static void ui_task_sink_beat(void) {
|
||||
task_wd_beat(TASK_WD_UI);
|
||||
}
|
||||
|
||||
#define DBG_TAG "[UI_TASK]"
|
||||
#include "dbg_log.h"
|
||||
|
||||
@@ -228,6 +248,9 @@ void ui_task_func(void *argument) {
|
||||
} else {
|
||||
DBG_INFO("UI net sink: started (port %u)", (unsigned)UI_NET_SINK_PORT);
|
||||
}
|
||||
/* F3:往返边界心跳钩(契约见 ui_net_sink.h;须在首轮 poll 之前注册)。
|
||||
* start 失败也要注:失败路径的 close/重建重试同样经往返 */
|
||||
ui_net_sink_set_beat_cb(ui_task_sink_beat);
|
||||
|
||||
#if defined(TEST_LATENCY_PROBE)
|
||||
/* M3 探针 ui_loop:主循环实测周期(= LVGL 渲染 + 推流轮询 + osDelay(10))。
|
||||
@@ -269,7 +292,10 @@ void ui_task_func(void *argument) {
|
||||
* 致实测 uiw≈uis≈50ms(心跳被 netTask 往返主导)。提到往返之前后,
|
||||
* 即使往返偶发变慢,心跳也不被其拖垮。
|
||||
* ⚠ 若往返**永久**阻塞(xTaskNotifyWait portMAX_DELAY 不返回),本改只能发
|
||||
* 一次心跳,救不了 → 彻底解耦须走事件驱动 accept,见文件头修改记录 v1.3。 */
|
||||
* 一次心跳,救不了 → 彻底解耦须走事件驱动 accept,见文件头修改记录 v1.3。
|
||||
* v1.4 补充:sink 内每个往返**返回点**已各自补喂(set_beat_cb 注入),
|
||||
* 「单轮多个慢往返之和」不再构成缺席链;剩单往返 >800ms 才报——那是
|
||||
* netTask 自身停摆,按位判据抓对了人(上界归 E-27/E-28)。 */
|
||||
task_wd_beat(TASK_WD_UI);
|
||||
/* 推流轮询段单独 enter/exit:它内部经 net_accept → net_wait_result 走到
|
||||
* xTaskNotifyWait(portMAX_DELAY) 的**无限期阻塞**。若 uiTask 永久卡在这里,
|
||||
|
||||
Reference in New Issue
Block a user