/* * 模块名称:UI SOE 记录页共享组件(ui_w_soe) * 模块功能:把"/log/soe.log 二进制定长 64 B 事件记录 → 每记录 2 行(偶数行时标、 * 奇数行"元件 + 事件类型")+ 单条读盘缓存 + 空态伪行"无记录"这套逻辑 * 收成一份,与文本记录组件 ui_w_records 同构(用户学习成本为零); * 数据经注入式 reader 函数表取,本头**不含任何 App 头** * 与文本记录的区别:SOE 是结构化二进制记录(时标/类型/元件号/序号/值), * 不是"时间戳 + 描述文本",不能让文本读者混读——故另立组件与另立 * 记录视图结构(照 ui_w_records.h 的注入模式,不复用其 desc 字段) * 显示名映射(本组件私有,属表现层):事件类型与元件都按**不透明编号**入参, * 编号值与 App 侧枚举逐项相等(一致性由 test/host/ui_data 主机单测 * 现场核对,不是照抄文档转述);文案是显示规格,不进快照也不进 App 层 * (口径 docs/UI设计/UI_数据供给设计说明.md §8) * 适用范围:Drivers/BSP/UI(分层方向由 scripts/check_layer_deps.py 守护) * 说明:reader 注入点已备好但**两端均未绑定**——SOE 文件的只读 API * (条数 / 按序号读一条)尚未在落盘侧提供,绑定与页面接线属道E 后续 * 任务;未绑定期间本组件按空态渲染("无记录"伪行),不崩不读野 * 作者:王建锋 * 创建日期:2026-10-25 * 修改记录: * v1.0 2026-10-25 王建锋 创建(道E task-14:事件类型/元件显示名映射 + * reader 契约;映射含未标定闭锁/复归两类新事件) */ #ifndef UI_W_SOE_H #define UI_W_SOE_H #ifdef __cplusplus extern "C" { #endif #include /* 时间戳缓冲容量(与文本记录组件同宽:19 字符 + NUL) */ #define UI_W_SOE_TS_LEN 20u /* * 事件类型不透明编号:UI 侧只认编号,不认识 App 的 soe_type_t。 * ⚠ 编号值与 App/log/soe_rec.h 的 soe_rec.h 枚举逐项相等(现场核对 2026-10-25: * 1 元件动作 / 2 元件返回 / 3 软压板退出 / 4 软压板投入 / 5 采样闭锁 / * 6 采样恢复 / 7 未标定闭锁 / 8 标定复归 / 9 = 哨兵),漂移由主机单测拦 * (test/host/ui_data 的 TC-UIDATA-012);新增类型 = 枚举尾追加 + 这里加编号 * + 名字表加一行 + 单测加一条 */ #define UI_W_SOE_T_NONE 0u /* UI 私有:未知/未映射编号(读失败行) */ #define UI_W_SOE_T_ELM_ASSERT 1u /* 元件动作(值 = 状态打包) */ #define UI_W_SOE_T_ELM_RETURN 2u /* 元件返回(值 = 返回前状态快照) */ #define UI_W_SOE_T_PLATE_OUT 3u /* 软压板退出 */ #define UI_W_SOE_T_PLATE_IN 4u /* 软压板投入 */ #define UI_W_SOE_T_SAMPLE_BLOCK 5u /* 采样闭锁(值 = 采样故障闭锁位图) */ #define UI_W_SOE_T_SAMPLE_RESUME 6u /* 采样恢复 */ #define UI_W_SOE_T_CAL_BLOCK 7u /* 未标定闭锁(值 = VALID 未齐的通道位图) */ #define UI_W_SOE_T_CAL_RESUME 8u /* 标定复归 */ #define UI_W_SOE_T_COUNT 9u /* 哨兵 = 名字表长度(不是有效类型) */ /* 元件编号:与保护元件枚举同序(0..8),0xFF = 非元件事件 * (一致性由同名单测 TC-UIDATA-013 现场核对) */ #define UI_W_SOE_ELM_N 9u #define UI_W_SOE_ELM_NONE 0xFFu /* 记录标志位:bit7 = 记录时时钟无效(时标不可信,页面须显式标记而非显示假时间) */ #define UI_W_SOE_FLG_IV 0x80u /* * SOE 记录视图(reader 的输出形态;字段原样搬运,不做时标换算与业务判断) * 单条 32 B:读盘缓存按实例存,一页 8 行 = 4 条记录也只缓存当前正在渲染的那条 */ typedef struct { char ts[UI_W_SOE_TS_LEN]; /* "YYYY-MM-DD HH:MM:SS";IV 或未对时时为空串 */ uint8_t type; /* UI_W_SOE_T_*(未知编号原样透传,名字表回 "--") */ uint8_t elm; /* 0..UI_W_SOE_ELM_N-1 或 UI_W_SOE_ELM_NONE */ uint8_t flags; /* UI_W_SOE_FLG_IV */ uint8_t rsv; /* 预留(对齐填充) */ uint32_t seq; /* 记录序号(上电内单调) */ uint32_t value; /* 类型相关值(页面当前不展开,留作详情行) */ } ui_w_soe_rec_t; /* * 注入式 SOE reader(只读函数表;契约与 ui_w_records.h 的 ui_rec_reader_t 同构, * 只是数据是二进制记录,所以取回的是整条视图而不是两段文本) * 实现体在 App / 模拟器侧,uiTask 上下文同步调用——绘制路径上的读盘时序与 * 文本记录页一致,无新增并发面 */ typedef struct { /* * 函数功能:取 SOE 记录总条数 * 入口参数:无 * 返回值:条数(0 = 空态,页面显示"无记录"伪行) uint16_t */ uint16_t (*count)(void); /* * 函数功能:读第 idx 条 SOE 记录(解码成视图) * 入口参数:a_idx - 记录序号(0 起) uint32_t * a_out - 输出视图(非 NULL) ui_w_soe_rec_t * * 返回值:0 = 成功;-1 = 序号越界;-2 = 读失败或校验和不符 * (码值与文本记录 reader 同族) int */ int (*get)(uint32_t a_idx, ui_w_soe_rec_t *a_out); } ui_soe_reader_t; /* SOE 记录页实例(读盘缓存必须按实例存,理由同 ui_w_records.h 的实例说明) */ typedef struct { uint8_t cache_valid; /* 1 = rec 是 last_rec 那条 */ uint32_t last_rec; /* 已缓存的记录序号 */ ui_w_soe_rec_t rec; /* 当前记录缓存 */ } ui_w_soe_t; /* * 函数功能:注入 SOE reader(启动时一次;NULL = 撤销注入,页面回空态) * 入口参数:a_reader - 只读函数表(生命周期由注入方保证,组件只存指针) * const ui_soe_reader_t * * 返回值:无 * 限定条件:uiTask 启动期注入(ui_menu_init 之前,与记录 reader 同址同纪律) */ void ui_w_soe_bind(const ui_soe_reader_t *a_reader); /* * 函数功能:事件类型编号 → 显示名(表现层映射表) * 入口参数:a_type - 类型编号(UI_W_SOE_T_*) uint8_t * 返回值:Flash 字符串指针(恒非 NULL;未知编号回 "--",不空指针、不空白) const char * * 限定条件:无 * 函数说明:元件类事件(动作/返回)的名字短(2 字),放**值列**; * 非元件事件(压板/采样/标定四类,4 字)放**名列**——两列宽度不同, * 由 ui_w_soe_refresh 按 elm 是否有效决定落在哪一列 */ const char *ui_w_soe_type_name(uint8_t a_type); /* * 函数功能:元件编号 → 显示名(表现层映射表) * 入口参数:a_elm - 元件编号(0..UI_W_SOE_ELM_N-1) uint8_t * 返回值:Flash 字符串指针(恒非 NULL;越界或非元件事件回 "--") const char * * 限定条件:无 * 函数说明:名称最长 4 字(零序过压/过流Ⅰ段),名列可用宽约 94 px = 7 汉字 * (口径 docs/UI设计/页面扩充详细方案.md §2.3 第 4 条) */ const char *ui_w_soe_elm_name(uint8_t a_elm); /* * 函数功能:总行数(每条记录 2 行;空态 = 单条伪行"无记录") * 入口参数:a_inst - SOE 页实例 ui_w_soe_t * * 返回值:总行数 uint16_t * 限定条件:无(未注入 reader 视同 0 条) */ uint16_t ui_w_soe_count(ui_w_soe_t *a_inst); /* * 函数功能:逐行取数(偶数行 = 时标,奇数行 = 元件 + 事件类型) * 入口参数:a_inst - SOE 页实例 ui_w_soe_t * * a_row - 全局行下标 uint16_t * a_name - 名输出缓冲(框架 UI_BUF_STRLEN) char * * a_value - 值输出缓冲(同上) char * * 返回值:无 * 限定条件:页面打开中(框架绘制/按键上下文,uiTask) * 函数说明:时标行——时钟无效(IV 位)或时标为空时名列显示 "--", * **不显示猜测时间**(诚实性判据,同待机屏空串先例); * 内容行——元件事件名 = 元件、值 = 动作/返回;非元件事件名 = 类型、 * 值 = 空串(值列宽约 59 px = 4 汉字,非元件事件词放这里放不下) */ void ui_w_soe_refresh(ui_w_soe_t *a_inst, uint16_t a_row, char *a_name, char *a_value); #ifdef __cplusplus } #endif #endif /* UI_W_SOE_H */