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:
@@ -282,6 +282,21 @@ void iec104_serv_get_stats(iec104_serv_stats_t *p_out)
|
||||
*p_out = s;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:读 104 链路是否处于 RUN 态(契约见 iec104_serv.h 的 iec104_serv_link_run)
|
||||
* 入口参数:无
|
||||
* 返 回 值:1 = RUN;0 = 其它 uint8_t
|
||||
* 限定条件:任意上下文;单枚举字读,原子
|
||||
* 函数说明:直接透传 iec104_link_state(),不另存镜像量——镜像量一旦和状态机
|
||||
* 分家(比如 open/close 路径漏更),屏灯就成第二本假账。link_state
|
||||
* 本身只读实例里的 state 字段(App/protocol/iec104/iec104_link.c),
|
||||
* 无副作用,跨任务读安全。
|
||||
*/
|
||||
uint8_t iec104_serv_link_run(void)
|
||||
{
|
||||
return (iec104_link_state(&s_link) == IEC104_ST_RUN) ? 1U : 0U;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:单次服务循环(代次自愈 → accept → 门控收 → 喂 link → 节拍)
|
||||
* 返回值:无
|
||||
|
||||
@@ -52,4 +52,17 @@ typedef struct {
|
||||
*/
|
||||
void iec104_serv_get_stats(iec104_serv_stats_t *p_out);
|
||||
|
||||
/*
|
||||
* 函数功能:读 104 链路是否处于 RUN 态(STARTDT 已确认 = 主站在线在轮询)
|
||||
* 返 回 值:1 = RUN;0 = 其它(IDLE/OPEN/STOPPED 或未创建任务) uint8_t
|
||||
* 限定条件:**任意上下文可读**——单枚举字读,不取锁、不碰 socket、不阻塞
|
||||
* (与 iec104_serv_get_stats 同一形态与同一读者群)。
|
||||
* 函数说明:写者 = iec104Task(link 状态机推进),读者按需采样;单字读写在
|
||||
* Cortex-M4 上原子,最多读到"晚一拍"的状态,无撕裂风险。
|
||||
* 消费点 = 屏板状态灯 ID 3(App/algo/sb_led_map.h 的通信灯)。
|
||||
* ⚠ 别拿它换算 conn_up:RUN 是电平,conn_up 是累计边沿,语义不可互换
|
||||
* (同文件统计注释里的"不得互相换算"纪律)。
|
||||
*/
|
||||
uint8_t iec104_serv_link_run(void);
|
||||
|
||||
#endif /* IEC104_SERV_H */
|
||||
|
||||
+19
-3
@@ -54,6 +54,9 @@
|
||||
#include "ui_tokens.h" /* UI 设计令牌:循环周期 UI_TASK_TICK_MS / 待机阈值 UI_STANDBY_IDLE_MS */
|
||||
#include "sys_clock.h"
|
||||
#include "prot_elm.h" /* 道F task-3 装置维护:强制复归请求 + 动作态元件位图 */
|
||||
#include "adc_health.h" /* 屏板状态灯 ID 4:ADC 电平故障位(adc_health_flags) */
|
||||
#include "sb_led_map.h" /* 屏板状态灯位映射(批 3:业务状态 → info[0..3] 掩码) */
|
||||
#include "iec104_serv.h" /* 屏板状态灯 ID 3:104 链路 RUN 态(任意上下文可读) */
|
||||
#include "test_config.h" /* TEST_LATENCY_PROBE(链路时延探针编译开关) */
|
||||
#include "net_latency_test.h" /* M3 探针:ui_loop(生产循环实测周期) */
|
||||
#include "task_watchdog.h"
|
||||
@@ -527,10 +530,23 @@ void ui_task_func(void *argument) {
|
||||
* 排在推流往返**之前**,是因为那个往返最坏能等 ≈4 s(LCDMEM 应答 3204 B),
|
||||
* 排在它后面会让屏板画面跟着网络一起卡(同一份显存、两个出口,出口不能互相拖)。
|
||||
* 显存直接取活帧缓冲:不留 3200 B 影子副本,sb_link 内部与帧里的点阵段 memcmp。
|
||||
* LED 掩码暂传 0(批 3 才落状态灯映射表),故 info[0..3] 现恒为 0。 */
|
||||
* LED 掩码(批 3):每拍现采四路状态源经 sb_led_map_eval 折算——四个源
|
||||
* 都是"任意上下文可读"的观测口(不取锁不阻塞,见各自头文件契约),
|
||||
* 折算本身纯计算;心跳灯相位跟着这一拍的 tick 走(uiTask 10 ms 节拍
|
||||
* 远高于 500 ms 半周期,闪烁边沿误差 ≤1 拍)。 */
|
||||
{
|
||||
bsp_err_t sb_ret = sb_link_frame_update(ui_port_get_framebuffer(), 0u);
|
||||
uint8_t board_key;
|
||||
sb_led_in_t led_in;
|
||||
uint32_t led_mask;
|
||||
bsp_err_t sb_ret;
|
||||
uint8_t board_key;
|
||||
|
||||
led_in.prot_active = prot_elm_active_mask();
|
||||
led_in.prot_pick = prot_elm_pick_mask();
|
||||
led_in.adc_flags = adc_health_flags();
|
||||
led_in.iec104_run = iec104_serv_link_run();
|
||||
led_mask = sb_led_map_eval(&led_in, osKernelGetTickCount());
|
||||
|
||||
sb_ret = sb_link_frame_update(ui_port_get_framebuffer(), led_mask);
|
||||
|
||||
/* BSP_ERR_BUSY 是常态(上一帧还在 59.6 ms 的发送窗口里),不必留痕;
|
||||
* 其余失败打一行即可(见 s_sb_frame_err_logged 的说明)。 */
|
||||
|
||||
Reference in New Issue
Block a user