8744c833e5
- 重写 docs/子系统设计/屏板链路设计说明.md:链路角色、串口与端口配置、 物理接线、协议实现口径、键值与状态灯映射、资源与耗时、对外接口、 已验证/未闭环、坑账本——只写现状事实,演进过程查 git 历史 - 删除 docs/任务规划/屏板链路.md(内容已全部沉淀进上述设计说明, 登记簿「完成即销项」;docs/任务规划/README.md 相应两行一并移除) - 代码与主机侧测试的文档指针改指设计说明对应章节: sb_link.h/.c、sb_proto.h/.c、sb_led_map.h、console_log.c、ui_task.c、 test/host 的 sb_link/sb_proto/sb_led_map 三套与两个台架脚本 - docs/README.md:设计文档索引行与设计说明描述更新,任务规划目录 7→6 文件 - docs/产品需求/产品需求设计文档.md:串口通道现状口径同步——第 11/12/13 条 已交付(4208 B 应答/状态灯掩码/键上行/双出口并发)、LOGO 下发出局不实现、 帧长实测固化、调试日志口 UART5/RS232#1(§4.2/§5.16/§6.6/§9.12/§9.13) - docs/子系统设计/控制台单写者日志设计说明.md v1.8:全文端口口径由 USART1 同步为 UART5/RS232#1(CON_UART* 单点宏),ORE 机理标注跨端口 同因,时间线补端口迁移行;头部修订指针改为实际章节名 说明:本任务经用户显式授权在任务树内编辑 docs/任务规划/ 与产品需求基线 (铁律「单写者」豁免一次);主树合并后统一跑全量 check_doc_links --all。
102 lines
5.9 KiB
C
102 lines
5.9 KiB
C
/*
|
||
* 模块名称:屏板状态灯位映射(业务状态 → LED 位掩码)
|
||
* 模块功能:把装置的业务状态(保护动作 / 保护启动 / 采样故障 / 104 主站在线 /
|
||
* 运行心跳)折算成屏板帧 B `info[0..3]` 的 32 位 LED 掩码。
|
||
* ⚠ 本层**纯逻辑**:不碰 HAL、不读全局、不打日志——输入是调用方
|
||
* (uiTask)采好的状态快照,输出是一个 uint32_t → 主机侧可纯逻辑单测
|
||
* (test/host/sb_led_map/)。与 Drivers/BSP/ScreenLink/sb_proto 同一分层理由。
|
||
* 适用平台:平台无关(纯标准 C)
|
||
* 作者:王建锋
|
||
* 创建日期:2026-10-29
|
||
* 修改记录:
|
||
* 2026-10-29 王建锋 创建初始版本(映射表口径见 docs/子系统设计/屏板链路设计说明.md §6)
|
||
*
|
||
* 这张表为什么必须"自定":屏板源码(DTU-LCD LED_Printf)只规定了"位 → 灯号"的
|
||
* 物理口径(bit1~bit19 → ID 1~19,ID 0 电源灯硬件常亮、不看位,bit20~31 未使用),
|
||
* **"哪路状态占哪一位"在参考主机源码里不存在**(参考的 LCD_LED_Update 实现在
|
||
* 未开源的屏板 BSP 库里)。出处 docs/产品需求/产品需求设计文档.md §5.16.3 ①。
|
||
*/
|
||
#ifndef SB_LED_MAP_H
|
||
#define SB_LED_MAP_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
#include <stdint.h>
|
||
|
||
/* ============================================================================
|
||
* 一、位定义(屏板物理口径:bit i = 灯 ID i;bit0 被屏板忽略,别指望用它)
|
||
* ==========================================================================*/
|
||
|
||
/* ID 1 = 运行灯:装置活着的心跳,500 ms 半周期闪烁(与主板 LED1~3 心跳节奏同源,
|
||
* docs/产品需求/产品需求设计文档.md §5.8)。它**不取决于任何输入状态**——只要这段
|
||
* 代码还在被调度,灯就在闪;灯不闪 = uiTask 停了,这正是操作员要看的信号。 */
|
||
#define SB_LED_BIT_RUN (1UL << 1)
|
||
|
||
/* ID 2 = 告警灯:任一保护元件处于**动作**态(prot_elm_active_mask != 0)。
|
||
* ⚠ 产品构建处于「未标定闭锁」(App/task/protect_task.c 的 VALID 门禁),
|
||
* 标定前恒灭——与屏上"保护动作 N"同一已知口径,不是本灯的缺陷。 */
|
||
#define SB_LED_BIT_ALARM (1UL << 2)
|
||
|
||
/* ID 3 = 通信灯:IEC 60870-5-104 链路处于 RUN(STARTDT 已确认 = 主站真的在线在
|
||
* 轮询)。选 RUN 而不选"TCP 已建连":连上不发 STARTDT 的扫描器不该点亮它。 */
|
||
#define SB_LED_BIT_COMM (1UL << 3)
|
||
|
||
/* ID 4 = 采样故障灯:ADC 采样有效性**电平**故障位非零(adc_health_flags,
|
||
* 静默/倒退等,当前活跃、可自愈熄灭)。选电平不选 sticky:这盏灯要能熄灭,
|
||
* "曾经故障过"的账在自检记录里,不该用一盏长明灯喊给操作员。 */
|
||
#define SB_LED_BIT_ADC_FAULT (1UL << 4)
|
||
|
||
/* ID 5 = 保护启动灯:任一保护元件处于**启动**(picked)态(prot_elm_pick_mask)。
|
||
* picked 早于 asserted,"越限启动了但没到动作点"这段过程只在这盏灯上可见
|
||
* (与 104「保护启动」记录同一动机,App/algo/prot_elm.h 的 pick_mask 注释)。
|
||
* 同样受未标定闭锁口径约束。 */
|
||
#define SB_LED_BIT_PICKUP (1UL << 5)
|
||
|
||
/* 已赋义位的并集(判据用:掩码里不得出现本表之外的置位)。
|
||
* ID 6~19 保留未用,恒 0;将来扩展从 ID 6 顺序取,跳号留白不回收语义。 */
|
||
#define SB_LED_BITS_DEFINED (SB_LED_BIT_RUN | SB_LED_BIT_ALARM | SB_LED_BIT_COMM | \
|
||
SB_LED_BIT_ADC_FAULT | SB_LED_BIT_PICKUP)
|
||
|
||
/* 运行灯闪烁半周期(ms):0 ~ SB_LED_BLINK_HALF_MS-1 亮,下一个 500 ms 灭,交替。
|
||
* 取 500 是为与主板 LED 心跳(defaultTask 500 ms 翻转)同拍,两套灯闪烁同相。 */
|
||
#define SB_LED_BLINK_HALF_MS (500U)
|
||
|
||
/* ============================================================================
|
||
* 二、状态输入快照(调用方每拍现采,本模块不缓存、不加锁)
|
||
* ==========================================================================*/
|
||
|
||
typedef struct
|
||
{
|
||
uint32_t prot_active; /* prot_elm_active_mask():bit i = 元件 i 动作 */
|
||
uint32_t prot_pick; /* prot_elm_pick_mask():bit i = 元件 i 启动 */
|
||
uint32_t adc_flags; /* adc_health_flags():ADC_HF_* 电平故障位 */
|
||
uint8_t iec104_run; /* 1 = IEC 104 链路 RUN(iec104_serv_link_run()) */
|
||
uint8_t pad[3]; /* 显式补齐:结构体大小固定 16 B,主机/目标端一致 */
|
||
} sb_led_in_t;
|
||
|
||
/* ============================================================================
|
||
* 三、求值入口
|
||
* ==========================================================================*/
|
||
|
||
/*
|
||
* 函数功能:把状态快照折算成屏板 LED 32 位掩码(纯函数,映射表唯一出处见本头 §一)
|
||
* 入口参数:p_in - 状态快照;**允许 NULL**:等价于全零输入(只跑运行灯心跳——
|
||
* 心跳证明的是"这段代码活着",与别的状态无关,不该被空输入连坐)
|
||
* now_ms - 当前毫秒时基(运行灯相位唯一依赖;osKernelGetTickCount 同域)
|
||
* 返回值:32 位 LED 掩码(bit i = 灯 ID i;bit0 与 ID 6~19 恒 0,直接进帧 B info[0..3])
|
||
* 限定条件:任意上下文(纯计算:无分支副作用、不读写任何静态量、时基回绕安全——
|
||
* 回绕瞬间至多把一个半周期截短或延长 1 拍,500 ms 的心跳灯看不出来)
|
||
* 函数说明:闪烁相位 = (now_ms / 500) 的奇偶,偶 = 亮。上电 first 500 ms 为亮,
|
||
* "刚上电灯就在闪"是最直观的自检信号。各状态位相互独立,任一非零即置位,
|
||
* 无优先级、无互斥(告警与通信可以同时亮,那是两件同时在真发生的事)。
|
||
*/
|
||
uint32_t sb_led_map_eval(const sb_led_in_t *p_in, uint32_t now_ms);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* SB_LED_MAP_H */
|