Files
STM32F4-Base/App/algo/sb_led_map.c
T
wandering1 0b84c43d2e 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 套件。
2026-10-30 00:39:57 +08:00

59 lines
2.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:屏板状态灯位映射(业务状态 → LED 位掩码)
* 模块功能:sb_led_map_eval()——状态快照进、32 位 LED 掩码出。位定义与理由全在
* sb_led_map.h(映射表唯一出处),本文件只做折算。
* 适用平台:平台无关(纯标准 C)
* 作者:王建锋
* 创建日期:2026-10-29
* 修改记录:
* 2026-10-29 王建锋 创建初始版本(批 3 的 3-1)
*/
#include <stddef.h> /* NULL:纯逻辑不经 main.h,NULL 要自己带来 */
#include "sb_led_map.h"
/* NULL 输入归一用的全零快照(static const:不占 RAM,语义就是"什么都没发生") */
static const sb_led_in_t s_in_zero = { 0UL, 0UL, 0UL, 0U, { 0U, 0U, 0U } };
/*
* 函数功能:把状态快照折算成屏板 LED 32 位掩码(契约见 sb_led_map.h)
* 入口参数:p_in - 状态快照,允许 NULL(= 全零输入,只跑心跳)
* now_ms - 毫秒时基(只用于运行灯相位)
* 返回值:32 位 LED 掩码(bit i = 灯 ID i;本函数不触碰 bit0 与 ID 6~19)
* 限定条件:任意上下文,纯函数
* 函数说明:心跳相位取 (now_ms / SB_LED_BLINK_HALF_MS) 的奇偶——用**除法取奇偶**
* 而不是"与上次比差值再翻转",因为后者要把相位存成静态量,纯函数就没了
* (单测要能不开机就验完整个闪烁序列)。回绕只截短一个半周期,无害。
*/
uint32_t sb_led_map_eval(const sb_led_in_t *p_in, uint32_t now_ms)
{
const sb_led_in_t *q = (p_in != NULL) ? p_in : &s_in_zero;
uint32_t mask = 0UL;
/* ID 1 运行心跳:偶数个 500 ms 段 = 亮 */
if (((now_ms / SB_LED_BLINK_HALF_MS) & 1UL) == 0UL)
{
mask |= SB_LED_BIT_RUN;
}
if (q->prot_active != 0UL)
{
mask |= SB_LED_BIT_ALARM;
}
if (q->iec104_run != 0U)
{
mask |= SB_LED_BIT_COMM;
}
if (q->adc_flags != 0UL)
{
mask |= SB_LED_BIT_ADC_FAULT;
}
if (q->prot_pick != 0UL)
{
mask |= SB_LED_BIT_PICKUP;
}
return mask;
}