feat(屏板): 状态灯位映射 sb_led_map + 104 RUN 观测口(批 3);附 4-1 并发压测脚本

批 3(LOGO 按用户裁定出局,不实现、sb_proto 的 LOGO 组帧挂待删标注):
- 新增 App/algo/sb_led_map.c/h:业务状态 → 屏板 LED 位掩码的唯一映射表
  (纯逻辑,主机单测可跑)。ID1 运行心跳 500ms 半周期闪(与主板 LED 同拍)、
  ID2 保护动作、ID3 104 链路 RUN、ID4 采样电平故障(不选 sticky——灯要能灭)、
  ID5 保护启动 picked;bit0 与 ID 6~19 恒 0。这张表参考源码里没有,属自定,
  出处 docs/产品需求/产品需求设计文档.md §5.16.3 ①。
- iec104_serv 新增 iec104_serv_link_run()(透传 link 状态机,不另存镜像量)。
- ui_task.c 帧组装块每拍现采四路状态源(均为任意上下文可读观测口)折算后
  传 sb_link_frame_update——替换批 2 的恒 0 占位;掩码变了帧就重组,
  复用 busy/dirty 机制,无新通路。
- 主机单测 test/host/sb_led_map 17/17(位语义/恒零位/闪烁相位/tick 回绕/
  NULL 契约);注册豁免走 SIM_EXEMPT(模拟器无屏板串口)。

批 4 的 4-1 双通道并发回归(真屏板在线实测):
- 新增 test/host/remolcd_pull_test.py:RemoDispBus 拉帧压测客户端
  (INIT→LCDMEM 10 Hz、逐帧 XOR+长度校验、往返延迟统计、--dump PBM)。
- 实测:网络侧两轮 2200 拉帧零错零超时(min 35/avg 63/max 131 ms);
  屏板侧 60 s 隔离窗口 rx +233 全收、drop 零新增、bad=0、off=0、无
  OFFLINE——两侧互不拖。观察项 len=7(断帧尺寸≠6,累计 7 次)出现窗口
  无法归因压测、隔离窗口零新增、有效帧零损失,已挂设计说明 §5.7 待查。

附带:sb_link.h frame_update 注释回填实测耗时(509/688 µs 取代旧估算)。
Keil 0 错误 0 警告;ci_local 全绿(SKIP=nested-comment,主树脚本另查 0 新发);
Code=239,064 B / RW_IRAM1 65.5 % / RW_CCM 87.9 %;覆盖率 90.1 % / 44 套件。
This commit is contained in:
2026-10-30 00:39:57 +08:00
parent 9c6d150261
commit 0b84c43d2e
17 changed files with 768 additions and 39 deletions
+41 -21
View File
@@ -80,6 +80,14 @@
"lines_covered": 41,
"lines_valid": 41
},
"App/algo/sb_led_map.c": {
"func_rate": 1.0,
"funcs_covered": 1,
"funcs_valid": 1,
"line_rate": 1.0,
"lines_covered": 15,
"lines_valid": 15
},
"App/cfg/cfg_file.c": {
"func_rate": 0.963,
"funcs_covered": 26,
@@ -193,12 +201,12 @@
"lines_valid": 100
},
"App/task/iec104_serv.c": {
"func_rate": 0.8182,
"func_rate": 0.75,
"funcs_covered": 9,
"funcs_valid": 11,
"line_rate": 0.7706,
"funcs_valid": 12,
"line_rate": 0.7572,
"lines_covered": 131,
"lines_valid": 170
"lines_valid": 173
},
"App/util/boot_stats.c": {
"func_rate": 1.0,
@@ -482,9 +490,9 @@
},
"iec104_serv": {
"files": {
"App/task/iec104_serv.c": 170
"App/task/iec104_serv.c": 173
},
"lines_total": 170,
"lines_total": 173,
"ok": true
},
"lftpd": {
@@ -623,6 +631,13 @@
"lines_total": 961,
"ok": true
},
"sb_led_map": {
"files": {
"App/algo/sb_led_map.c": 15
},
"lines_total": 15,
"ok": true
},
"sb_link": {
"files": {
"Drivers/BSP/ScreenLink/sb_link.c": 207,
@@ -739,6 +754,7 @@
"App/algo/prot_set.c",
"App/algo/run_par.c",
"App/algo/sample_ring.c",
"App/algo/sb_led_map.c",
"App/cfg/cfg_file.c",
"App/cfg/cfg_file_store_mcu.c",
"App/cfg/prot_set_store.c",
@@ -780,16 +796,16 @@
],
"totals": {
"files_generated_excluded": 5,
"files_tested": 48,
"files_untested": 165,
"func_rate": 0.9339,
"funcs_covered": 551,
"funcs_valid": 590,
"line_rate": 0.9011,
"lines_covered": 7334,
"lines_valid": 8139,
"modules_ok": 43,
"modules_total": 43
"files_tested": 49,
"files_untested": 166,
"func_rate": 0.9324,
"funcs_covered": 552,
"funcs_valid": 592,
"line_rate": 0.9009,
"lines_covered": 7349,
"lines_valid": 8157,
"modules_ok": 44,
"modules_total": 44
},
"untested_sources": [
{
@@ -833,7 +849,7 @@
"path": "App/task/adc_task.c"
},
{
"code_lines": 245,
"code_lines": 253,
"path": "App/task/ui_task.c"
},
{
@@ -1116,6 +1132,10 @@
"code_lines": 27,
"path": "Drivers/BSP/UI/ui_w_setview.h"
},
{
"code_lines": 26,
"path": "App/algo/sb_led_map.h"
},
{
"code_lines": 26,
"path": "App/util/task_prof.h"
@@ -1264,6 +1284,10 @@
"code_lines": 12,
"path": "App/app/app_main.h"
},
{
"code_lines": 12,
"path": "App/task/iec104_serv.h"
},
{
"code_lines": 12,
"path": "Drivers/BSP/GD5F2GQ5UE/nand_ftl.h"
@@ -1280,10 +1304,6 @@
"code_lines": 11,
"path": "App/sync/time_sync.h"
},
{
"code_lines": 11,
"path": "App/task/iec104_serv.h"
},
{
"code_lines": 11,
"path": "App/task/net_task.h"