feat(UI/采集/104): 通讯设置页 + 开机账本 + adc_cal 可诊断化——三车道同树一次构建入库

三条道在同一棵树上交付,故合并成**一次权威构建**(@build 0 错 0 警,Code=235236 RO=26308 RW=1572
ZI=136924)后同笔入库;台账已按该构建回填(`ram_baseline.py --update` + `--write`、`chec
k_mem_numbers.py
 --write`),凭证与实际 .map 同源。归属如下:

· **通讯设置页**(道G task-9):新增 `Drivers/BSP/UI/ui_page_comm.{c,h}`(通道六注入,与死
区页同骨架同纪
  律),`#page=comm` 绑定使 bound **21 → 22**、内容页黄金 **47 → 53**(旧 47 页字节零变化,
新增六态含
  WAIT/OK 两张);`iec104_comm` 脏位 + store_save(**无事件位**)挂 defaultTask 同点位
轮询;`port_104` 由
  宏改走 getter、`IEC104_SERV_PORT` 删除;字体 +听/监(185 字全覆)。**实机链已闭环**:FTP 外改
[comm]
  的 ca/port → 复位 → 串口出现 `section 'comm' (2 keys)` 与 `i104: listening o
n 9004` → 还原 2404,全程无
  FAIL ⇒「重启即生效 + 端口真值」不是推断是实测。上限核对 6/8 段、2/16 键,超限现象由 TC-CONFIG-056/057
  钉死(注册 -1 + `comm init: FAIL` 锚 + getter 回 ROM),**不抬宏**。
· **开机账本**(道F task-12):新增 `App/util/boot_stats.{c,h}`——上电次数落 SD2506 用户
 SRAM(magic +
  小端计数 + 版本 + 异或校验),一次上电 = 1 读 + ≤1 写,**零 NAND、零卷锁、零配置段**;四态互斥
  UNKNOWN / FRESH / CONTINUED / RESTARTED(BLF=1 才算电池域掉过电),**读失败绝不回写**;
文案口径「自 RTC
  电池周期起」,**禁写终身次数**。复位原因优先级链从 `app_main.c` 的 if-else 收进一份真源(串口与屏幕同
  源);104 四个只增不清计数 + `iec104_serv_get_stats()` 留在 serv、未塞进 link(会被 open
/close 洗掉)。
  运行时长按用户裁定 = **只报本次开机以来**,零新增代码。新套件 `test/host/boot_stats` 21/21,五处注入
  **全部有牙**(含「漂一字节被校验和挡下而不是报 256 倍错账」)。
· **adc_cal 可诊断化**(道E task-43):三个 volatile 计数 + `adc_cal_get_stats()`
/ `adc_cal_note_persisted()`
  (水位**盖写非自增**,因为一次 save 覆盖整档,数 save 会留假未落盘);「差额 × 脏位」三态语义唯一落在
  `adc_cal.h`,其中「差额 > 0 且脏位恒 0」= 绕过语义 setter 的静默丢失;TC-ADCCAL-019~023。

三条**必须留档的自纠**(都是执行道自己报的,我不替他们润色):
① stdint 那条断链是**宿主套件抓到、通讯道先修**,采集道承认自己是重复添加者并删掉自己那份;
② 「exit 2 不是证据,断言变红才是」——采集道第一版反证注入了未声明标识符导致编译错,差点当成功;
③ 套件汇总行原写 `s_total/s_total`,失败时会打印「21/21 PASSED (failed=1)」这种自相矛盾的行,已改。

另修:`check_registration.py` 的 `SIM_EXEMPT` 加一行豁免 `App/util/boot_stats.c
`(依赖 I2C 与 RCC 位掩码,
MCU 专属;核过 `sys_clock.c`/`sha256.c` 同形态先例),注册反向校验 exit 1 → 0。发号 TC-IEC1
04-034、
TC-UIDATA-029 已实抬游标(`TC-IEC104-033→034`、`TC-UIDATA-026→029`)。

门禁:id-check --strict 与 plain 均 rc=0、doc-links --all rc=0、注册校验 0、cppche
ck / coding-standard /
bom-drift 0;iec104 179/179、ui_data 295/295、boot_stats 21/21、adc_cal 11
7/117、run_par 67/67;菜单 8 状态
池 5368 不变、内容页 53/53。**已知遗留**:内容页数 47 → 53 的全仓文本同步尚未做(另卡跟踪),本笔只保
证代码与黄金一致;面板注键真机那一腿缺 CLI,交台架道补。
This commit is contained in:
2026-10-27 11:29:23 +08:00
parent 0ae9c10f24
commit 728d60675f
47 changed files with 2364 additions and 123 deletions
+61
View File
@@ -28,6 +28,7 @@
* 作者:王建锋
* 创建日期:2026-10-25
* 修改记录:
* v1.x 2026-10-27 DTU 项目组 道G task-9:通道六通讯参数转发实现。
* v1.0 2026-10-25 王建锋 创建(道E task-14)
* v1.1 2026-10-26 DTU 项目组 道F task-1:新增定值写路径环形队列(深度 4、满返 -1)
* 与状态机(IDLE/WAIT/OK/ERR_RANGE/ERR_LOCKED/ERR_BUSY),
@@ -1026,3 +1027,63 @@ uint8_t ui_data_yt_pending(void) {
}
return s_yt->pending();
}
/* ============================================================
* 通道六:通讯参数([comm])整定注入(道G task-9,通讯设置页)
*
* 与通道五同一组存在理由(ui_data.h 通道六表注:分层 / 模拟器 / 原子性);
* 本层同样**不持有任何 [comm] 值**——真源在 App/protocol/iec104/iec104_comm.c
* 的 RAM 副本,落盘动力在 defaultTask 每轮无条件 iec104_comm_store_save()。
* 未注入语义按"能力不可用"退化(row/set → -1、pending → 0),页面不崩不猜。
* ============================================================ */
static const ui_data_comm_ops_t *s_comm;
/*
* 函数功能:注入通讯参数执行侧函数表(启动期一次)
* 入口参数:ops - 三件齐;NULL = 撤销注入
* 返回值:0 - 已注入/已撤销;-1 - 残表(存量不动,理由逐字同 yt/maint bind) int
* 限定条件:uiTask 启动期,先于 ui_menu_init()
*/
int ui_data_comm_bind(const ui_data_comm_ops_t *a_ops) {
if (a_ops == NULL) {
s_comm = NULL;
return 0;
}
if ((a_ops->row == NULL) || (a_ops->set == NULL) ||
(a_ops->pending == NULL)) {
return -1;
}
s_comm = a_ops;
return 0;
}
/*
* 函数功能:读第 idx 行通讯参数现状
* 返回值:0 - 已整份写出;-1 - 未注入 / 指针空(出参不预清,返 0 才可读——
* 通道五同一条契约) int
*/
int ui_data_comm_row(uint8_t a_idx, ui_data_comm_row_t *a_out) {
if ((s_comm == NULL) || (a_out == NULL)) {
return -1;
}
return s_comm->row(a_idx, a_out);
}
/*
* 函数功能:写第 idx 行通讯参数——通讯设置页唯一写出口
* 返回值:0 - 副本已写且已置脏;-1 - 未注入或带外拒(同码口径同通道五) int
*/
int ui_data_comm_set(uint8_t a_idx, uint32_t a_val) {
if (s_comm == NULL) {
return -1;
}
return s_comm->set(a_idx, a_val);
}
/* 函数功能:[comm] 段落盘脏位(保存行三态判据;不加边沿记忆,锁存归页面) uint8_t */
uint8_t ui_data_comm_pending(void) {
if (s_comm == NULL) {
return 0u;
}
return s_comm->pending();
}
+76
View File
@@ -22,6 +22,8 @@
* 作者:王建锋
* 创建日期:2026-10-25
* 修改记录:
* v1.x 2026-10-27 DTU 项目组 道G task-9:通道六通讯参数注入表
* (ui_data_comm_ops_t,通讯设置页消费)。
* v1.0 2026-10-25 王建锋 创建(道E task-14:契约 §4 快照层落地;相对契约
* 两通道新增第三条 info,划分理由见本头"通道划分"注
* 与契约 §4.4)
@@ -834,6 +836,80 @@ uint8_t ui_data_yt_cal_blocked(void);
*/
uint8_t ui_data_yt_pending(void);
/* ── 通道六:通讯参数([comm])整定注入(道G task-9,通讯设置页)───────
*
* 理由与通道五逐字同构(分层方向 layer-deps / 模拟器不链 App/protocol /
* "写值+置脏"原子性归执行侧),此处只记差异:
* ① 行数不进表——[comm] 就两个键(ca/port),行名与行数是**页面形状**,
* 不是数据源;lo/hi 与值由 row() 现给(合法带唯一出口 = iec104_comm.h
* 的带宏与 getter 守卫),页面不得抄数(通道五"第二真源"条同口径)。
* ② 生效语义与通道五不同档:port 下次重 bind 监听生效、ca **改后重启**
* 生效(页脚与保存行不承诺"立即生效",措辞口径见 ui_page_comm.c 头)。
* ③ 值域 u16 级,但通道口径走 uint32——编辑器值通道是 int32 定点,
* set() 收到 >65535 由执行侧带外拒(副本不动),页面不做二次守卫。
*/
/* 行下标(行序 = 页面行序,装配与页面各自钉死,TC 双向锁) */
#define UI_DATA_COMM_ROW_CA 0u /* 公共地址 1..65535(改后重启生效) */
#define UI_DATA_COMM_ROW_PORT 1u /* 监听端口 1024..65535(下次重 bind 生效) */
#define UI_DATA_COMM_ROW_N 2u
/* 一行通讯参数的现状(执行侧现给;无浮点,uint32 直达) */
typedef struct {
uint32_t val; /* 当前值(RAM 副本 getter) */
uint32_t lo; /* 合法带下限(含)——iec104_comm.h 带宏现给 */
uint32_t hi; /* 合法带上限(含)——同上 */
} ui_data_comm_row_t;
/* 执行侧函数表(常驻注入;整表校验、拒残表——通道四/五同款纪律) */
typedef struct {
/*
* 函数功能:读第 idx 行现状(值 + 合法带)
* 返回值:0 - 已整份写出;-1 - idx 越界 / 指针空 / 未注入侧无此行 int
*/
int (*row)(uint8_t a_idx, ui_data_comm_row_t *a_out);
/*
* 函数功能:写第 idx 行(真机 = iec104_comm_ca_set / iec104_comm_port_set)
* 返回值:0 - 副本已写且已置脏;-1 - 带外拒(副本未动、不置脏) int
*/
int (*set)(uint8_t a_idx, uint32_t a_val);
/*
* 函数功能:段级落盘脏位探查——真机 = iec104_comm_dirty_peek()
* 返回值:1 - 有已改未落盘;0 - 干净。落盘动力 = defaultTask 每轮无条件
* iec104_comm_store_save()(通道五注释里查实的那条链同款)。
* 页面按「结果锁存」画 WAIT/OK(他人 104 侧无自动写者,比通道五
* 更干净,但锁存纪律不变——同一条口径别做两套)
*/
uint8_t (*pending)(void);
} ui_data_comm_ops_t;
/*
* 函数功能:注入通讯参数执行侧函数表(启动期一次;形状对齐 ui_data_yt_bind)
* 入口参数:ops - 函数表(三件都不得为 NULL);NULL = 撤销注入(宿主测试用)
* 返回值:0 - 已注入/已撤销;-1 - 残表(存量不动;页面按"不可用"渲染) int
* 限定条件:uiTask 启动期、先于 ui_menu_init()(真机 = 装配层 tick 首轮懒绑,
* 与通道五同点位相邻)
*/
int ui_data_comm_bind(const ui_data_comm_ops_t *a_ops);
/*
* 函数功能:读第 idx 行通讯参数现状
* 返回值:0 - 已写出;-1 - 未注入 / 参数空 / idx 越界(退化显示,不猜) int
*/
int ui_data_comm_row(uint8_t a_idx, ui_data_comm_row_t *a_out);
/*
* 函数功能:写第 idx 行通讯参数
* 返回值:0 - 已写并置脏;-1 - 未注入或带外拒(未注入与拒绝同码,同通道五) int
*/
int ui_data_comm_set(uint8_t a_idx, uint32_t a_val);
/*
* 函数功能:[comm] 段落盘脏位探查(保存行三态判据)
* 返回值:1 - 有已改未落盘;0 - 干净或未注入 uint8_t
*/
uint8_t ui_data_comm_pending(void);
#ifdef __cplusplus
}
#endif
+76 -64
View File
@@ -463,6 +463,11 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
0x0, 0x3, 0xfe, 0x40, 0x48, 0x9, 0xff, 0x20,
0x20,
/* U+542C "听" */
0x0, 0xde, 0xe2, 0x50, 0x4a, 0x9, 0x7f, 0x29,
0x25, 0x24, 0xa4, 0xf4, 0x92, 0x90, 0x12, 0x4,
0x40,
/* U+542F "启" */
0x4, 0x0, 0x40, 0xff, 0x90, 0x12, 0x2, 0x7f,
0xc8, 0x1, 0xff, 0x30, 0x2a, 0x5, 0x7f, 0xc8,
@@ -848,6 +853,11 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
0x6, 0xc7, 0x7, 0x11, 0x2, 0x20, 0x84, 0x20,
0x80,
/* U+76D1 "监" */
0x9, 0x9, 0x21, 0x27, 0xa5, 0x4, 0xc8, 0x10,
0x80, 0x3, 0xfe, 0x4a, 0x49, 0x49, 0x29, 0x7f,
0xf0,
/* U+76F4 "直" */
0x8, 0x3f, 0xf0, 0x81, 0xfe, 0x40, 0x9f, 0xe4,
0x9, 0xfe, 0x40, 0x9f, 0xe4, 0xb, 0xff,
@@ -1323,20 +1333,20 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 990, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1007, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1024, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1041, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1055, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1041, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1058, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1072, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1089, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1106, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1123, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1140, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1156, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1140, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1157, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1173, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1190, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1207, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1224, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1241, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1255, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1241, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1258, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1272, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1289, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1306, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1345,8 +1355,8 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 1357, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1374, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1391, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1408, .adv_w = 192, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1422, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1408, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1425, .adv_w = 192, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1439, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1456, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1473, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1366,13 +1376,13 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 1711, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1728, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1745, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1762, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1778, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1791, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1808, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1824, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1841, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1855, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1762, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1779, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1795, .adv_w = 192, .box_w = 9, .box_h = 11, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 1808, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1825, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1841, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1858, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1872, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1889, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 1906, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1384,8 +1394,8 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 2008, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2025, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2042, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2059, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2075, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2059, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2076, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2092, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2109, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2126, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1397,17 +1407,17 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 2228, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2245, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2262, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2279, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2293, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2279, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2296, .adv_w = 192, .box_w = 10, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2310, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2327, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 2342, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2359, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2376, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2392, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2409, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2425, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2442, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2327, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2344, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2361, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 2376, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2393, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2410, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2426, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2443, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2459, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2476, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2493, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1417,9 +1427,9 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 2561, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2578, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2595, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2612, .adv_w = 192, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 2626, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2643, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2612, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2629, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2646, .adv_w = 192, .box_w = 9, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 2660, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2677, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 2694, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
@@ -1445,31 +1455,33 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 3034, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3051, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3068, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3085, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3101, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3118, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3085, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3102, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3119, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3135, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3152, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3169, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3186, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3203, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3220, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3237, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3252, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3267, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3284, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3237, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3254, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3271, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3286, .adv_w = 192, .box_w = 10, .box_h = 12, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3301, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3318, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3335, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3352, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3368, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3385, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3352, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3369, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3386, .adv_w = 192, .box_w = 11, .box_h = 11, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3402, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3419, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3436, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3453, .adv_w = 192, .box_w = 2, .box_h = 4, .ofs_x = 2, .ofs_y = 0},
{.bitmap_index = 3454, .adv_w = 192, .box_w = 2, .box_h = 6, .ofs_x = 2, .ofs_y = 0},
{.bitmap_index = 3456, .adv_w = 165, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1} /* U+25B6 */
{.bitmap_index = 3453, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3470, .adv_w = 192, .box_w = 11, .box_h = 12, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3487, .adv_w = 192, .box_w = 2, .box_h = 4, .ofs_x = 2, .ofs_y = 0},
{.bitmap_index = 3488, .adv_w = 192, .box_w = 2, .box_h = 6, .ofs_x = 2, .ofs_y = 0},
{.bitmap_index = 3490, .adv_w = 165, .box_w = 8, .box_h = 10, .ofs_x = 1, .ofs_y = -1} /* U+25B6 */
};
/*---------------------
@@ -1481,25 +1493,25 @@ static const uint16_t unicode_list_1[] = {
0x2d44, 0x2d96, 0x2ded, 0x2dee, 0x2dfc, 0x2e7d, 0x2e81, 0x2edc,
0x3005, 0x300c, 0x3011, 0x3013, 0x309a, 0x30a6, 0x30d6, 0x30ed,
0x3148, 0x31b6, 0x31da, 0x322b, 0x3262, 0x326c, 0x3276, 0x3283,
0x3297, 0x32a8, 0x32cf, 0x32ea, 0x357e, 0x35d0, 0x35e0, 0x362b,
0x37ad, 0x37b6, 0x39f0, 0x39f7, 0x39f8, 0x3a3a, 0x3a3e, 0x3a66,
0x3c92, 0x3cd8, 0x3d14, 0x3d2f, 0x3d46, 0x3d96, 0x3da2, 0x3daf,
0x3dda, 0x3df2, 0x3df3, 0x3df5, 0x3ea1, 0x3edb, 0x3f02, 0x3f0f,
0x40d7, 0x40eb, 0x4135, 0x4136, 0x4144, 0x4145, 0x420e, 0x4245,
0x4247, 0x4249, 0x436d, 0x43e5, 0x43e8, 0x4410, 0x4414, 0x4480,
0x4485, 0x4496, 0x44de, 0x45a0, 0x45a8, 0x45bf, 0x45ca, 0x45cc,
0x461f, 0x4685, 0x46a7, 0x46c1, 0x46d7, 0x4760, 0x48c1, 0x49c0,
0x49c1, 0x4a1b, 0x4a55, 0x4ae2, 0x4b82, 0x4be1, 0x4beb, 0x4c28,
0x4ca5, 0x4cc9, 0x4f59, 0x50e7, 0x50e8, 0x5156, 0x53c8, 0x53d5,
0x53ec, 0x5594, 0x55ab, 0x56a1, 0x570c, 0x570e, 0x57da, 0x5872,
0x58ab, 0x598f, 0x59cc, 0x5b1b, 0x5b9b, 0x5d5f, 0x5d68, 0x5d94,
0x5df1, 0x5e0e, 0x608a, 0x614f, 0x6217, 0x66ec, 0x6765, 0x6a06,
0x6a44, 0x6a4f, 0x6a50, 0x6a5e, 0x6a82, 0x6a8f, 0x6a97, 0x6bbf,
0x6c2a, 0x6c93, 0x6e0f, 0x6e1d, 0x6e33, 0x6e67, 0x6e70, 0x6e71,
0x6e74, 0x6ea0, 0x6eba, 0x6ef3, 0x6f05, 0x6f88, 0x6fed, 0x7067,
0x706d, 0x706f, 0x733f, 0x7345, 0x73a1, 0x73b9, 0x741f, 0x748d,
0x7494, 0x7498, 0x74d2, 0x7504, 0x753c, 0x7596, 0x7602, 0x7715,
0x7731, 0x7828, 0x792c, 0x7d78, 0xddac, 0xddba
0x3297, 0x32a8, 0x32cc, 0x32cf, 0x32ea, 0x357e, 0x35d0, 0x35e0,
0x362b, 0x37ad, 0x37b6, 0x39f0, 0x39f7, 0x39f8, 0x3a3a, 0x3a3e,
0x3a66, 0x3c92, 0x3cd8, 0x3d14, 0x3d2f, 0x3d46, 0x3d96, 0x3da2,
0x3daf, 0x3dda, 0x3df2, 0x3df3, 0x3df5, 0x3ea1, 0x3edb, 0x3f02,
0x3f0f, 0x40d7, 0x40eb, 0x4135, 0x4136, 0x4144, 0x4145, 0x420e,
0x4245, 0x4247, 0x4249, 0x436d, 0x43e5, 0x43e8, 0x4410, 0x4414,
0x4480, 0x4485, 0x4496, 0x44de, 0x45a0, 0x45a8, 0x45bf, 0x45ca,
0x45cc, 0x461f, 0x4685, 0x46a7, 0x46c1, 0x46d7, 0x4760, 0x48c1,
0x49c0, 0x49c1, 0x4a1b, 0x4a55, 0x4ae2, 0x4b82, 0x4be1, 0x4beb,
0x4c28, 0x4ca5, 0x4cc9, 0x4f59, 0x50e7, 0x50e8, 0x5156, 0x53c8,
0x53d5, 0x53ec, 0x5571, 0x5594, 0x55ab, 0x56a1, 0x570c, 0x570e,
0x57da, 0x5872, 0x58ab, 0x598f, 0x59cc, 0x5b1b, 0x5b9b, 0x5d5f,
0x5d68, 0x5d94, 0x5df1, 0x5e0e, 0x608a, 0x614f, 0x6217, 0x66ec,
0x6765, 0x6a06, 0x6a44, 0x6a4f, 0x6a50, 0x6a5e, 0x6a82, 0x6a8f,
0x6a97, 0x6bbf, 0x6c2a, 0x6c93, 0x6e0f, 0x6e1d, 0x6e33, 0x6e67,
0x6e70, 0x6e71, 0x6e74, 0x6ea0, 0x6eba, 0x6ef3, 0x6f05, 0x6f88,
0x6fed, 0x7067, 0x706d, 0x706f, 0x733f, 0x7345, 0x73a1, 0x73b9,
0x741f, 0x748d, 0x7494, 0x7498, 0x74d2, 0x7504, 0x753c, 0x7596,
0x7602, 0x7715, 0x7731, 0x7828, 0x792c, 0x7d78, 0xddac, 0xddba
};
/*Collect the unicode lists and glyph_id offsets*/
@@ -1510,12 +1522,12 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
.unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY
},
{
.range_start = 9654, .range_length = 1, .glyph_id_start = 278,
.range_start = 9654, .range_length = 1, .glyph_id_start = 280,
.unicode_list = NULL, .glyph_id_ofs_list = NULL, .list_length = 0, .type = LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY
},
{
.range_start = 8544, .range_length = 56763, .glyph_id_start = 96,
.unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 182, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
.unicode_list = unicode_list_1, .glyph_id_ofs_list = NULL, .list_length = 184, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
}
};
+278
View File
@@ -0,0 +1,278 @@
/*
* 模块名称:UI Page Comm (通讯设置内容页)
* 模块功能:通讯参数 → 通讯设置 叶子(#P 受密码保护)的内容页——两行数值表
* (公共地址 CA / 监听端口)+ 保存行;本文件零 App include:行现状
* (值/合法带)经 ui_data.h 通道六注入表现取,写与落盘确认全走
* ui_w_setlist 组件 + 本页自带的 60 行胶水(写记账/落盘锁存——
* ui_w_ytview 是 [run_par] 档专用形态(float 域 + 徽标),两档语义
* 不同不硬并)
* 两态一页:123 修改权限 → 可编辑(编辑器 + 保存行);000 查看权限 → 只读
* (attach 内不绑 commit → 无保存行,key_cb 整页交回框架——死区页
* 同一条分派纪律)
* 生效语义(屏上必须诚实的地方):保存行 OK 只证明 **落盘完成**,不证明
* "已在新值上运行"——端口 = 下一次重 bind 监听生效(拆链/网络代次
* 重建自然到位,不必整机重启),公共地址 = **改后重启生效**
* (iec104Task 启动时取一次 getter;docs/子系统设计/
* IEC104上行设计说明.md §8)。页面上不加"立即生效"字样,也不为
* ca 画第二枚徽标——生效时刻的完整口径归上面那份设计说明。
* 徽标说明:本页不画"未标定"类徽标(与两点标定无关,稀释真告警——死区页
* 同条纪律)
* 适用平台:STM32F407ZGTx / PC 模拟器(共用源码)
* 作者:DTU 项目组
* 创建日期:2026-10-27
* 修改记录:
* v1.0 2026-10-27 DTU 项目组 创建(道G task-9;判据 = docs/任务规划/
* UI补齐.md §2 第 1 行「重启即生效 + 104 侧读回
* 真值 + 段数键数上限核对」,台架判据见该卡与
* IEC104上行设计说明.md §8)
*/
/* 头文件包含区 */
#include <string.h>
#include "ui_page_comm.h"
#include "ui_data.h" /* 通道六:行现状/写入口/脏位(本层唯一的数与守卫的来源) */
#include "ui_tokens.h"
#include "ui_w_setlist.h"
/* 私有宏定义区 */
/* 保存行显示态(值与 ui_w_ytview 的 YT_ST_* 同序同义,胶水面独立一份) */
#define CM_ST_ENTER 0u /* 空闲:保存行显示 ENTER */
#define CM_ST_WAIT 1u /* 按过保存、脏位仍在:WAIT */
#define CM_ST_OK 2u /* 脏位归零(或按时无脏):OK,锁存不回退 */
#define CM_ST_ERR 3u /* 最近一次写被执行侧拒:粘滞 ERR */
#define CM_BAD_ALL 0x03u /* 两行反显位图全掩码 */
/* 静态变量定义区 */
/* 行表在 RAM 现建(合法带唯一出口在执行侧,本文件零范围字面量——通道六
* 表注第①条;行名是本机界面文案归本页,行序即 UI_DATA_COMM_ROW_* 下标) */
static const char *const k_comm_name[UI_DATA_COMM_ROW_N] = {
"公共地址",
"监听端口"
};
static ui_w_setlist_row_t s_rows[UI_DATA_COMM_ROW_N];
static uint8_t s_n; /* 实际建出行数(半表纪律:读失败即停) */
static uint8_t s_st; /* 保存行显示态 CM_ST_* */
static uint8_t s_badmap; /* 写被拒行反显位图(bit0=CA bit1=PORT) */
/* 本页定值表实例(组件状态独占一份,勿跨页共用) */
static ui_w_setlist_t s_sl;
/* 函数定义区 */
/*
* 函数功能:写结果记账(成功/被拒共一个入口——死区页 yt_note_write 同款)
* 入口参数:a_id - 行下标 uint8_t;a_rc - 注入口返回值 int
* 返回值:无
* 限定条件:set 回调链内(uiTask 按键)
* 函数说明:拒绝 → 该行反显 + 粘滞 ERR;成功 → 只清这一行反显 + 作废上一次
* 保存结果(改过任何一位,上一轮的 OK/ERR 都不该再挂屏)
*/
static void cm_note_write(uint8_t a_id, int a_rc) {
if (a_rc != 0) {
s_badmap = (uint8_t)(s_badmap | (uint8_t)(1u << a_id));
s_st = CM_ST_ERR;
} else {
s_badmap = (uint8_t)(s_badmap & (uint8_t)~(1u << a_id));
s_st = CM_ST_ENTER;
}
}
/*
* 函数功能:保存行按键(值早在逐行 ENTER 时写入副本并置脏;这里只是落盘
* 确认的起点)
* 入口参数:无
* 返回值:无
* 限定条件:可编辑态、保存行 ENTER;uiTask 按键链
* 函数说明:先清反显再评估;脏位仍在 → WAIT 锁存观察,无脏 → 直接 OK。
* 真机落盘 = defaultTask 每轮无条件 iec104_comm_store_save(),
* WAIT 窗口 ≤50 ms;模拟器假件刻意不自动清脏(由无头 pump 清),
* 否则 WAIT 态永远不会被像素回归覆盖(道F 裁定④同一条理由)
*/
static void cm_commit(void) {
s_badmap = 0u;
s_st = (ui_data_comm_pending() != 0u) ? CM_ST_WAIT : CM_ST_OK;
}
/*
* 函数功能:保存行值列回读(WAIT → OK 边沿在此收尾)
* 入口参数:无
* 返回值:组件态枚举 ui_w_setlist_st_t
* 限定条件:绘制链内
* 函数说明:锁存 = 只前进不回退("我这次动作的结果"与"档位此刻的状态"分开;
* 通道六里 ca/port 没有 104 侧自动写者,比通道五更干净,但锁存
* 纪律不做两套)
*/
static ui_w_setlist_st_t cm_state(void) {
if ((s_st == CM_ST_WAIT) && (ui_data_comm_pending() == 0u)) {
s_st = CM_ST_OK;
}
switch (s_st) {
case CM_ST_WAIT:
return UI_W_SETLIST_ST_WAIT;
case CM_ST_OK:
return UI_W_SETLIST_ST_OK;
case CM_ST_ERR:
return UI_W_SETLIST_ST_FAIL;
default:
return UI_W_SETLIST_ST_IDLE;
}
}
/* 函数功能:某行是否需越界反显(写被拒的账挂在这行值上) 返回值:反显 bool */
static bool cm_bad(uint16_t a_row) {
if (a_row >= 8u) {
return false;
}
return ((s_badmap >> a_row) & 0x1u) != 0u;
}
/*
* 函数功能:读某行当前值(int32 定点通道,decimals 恒 0 = u16 域直达)
* 入口参数:a_id - 行下标 uint8_t
* 返回值:当前值 int32_t
* 函数说明:读失败回 0 不回旧缓存——组件零缓存,0 是唯一诚实的退化值
* (ui_data 通道五同口径)
*/
static int32_t cm_get(uint8_t a_id) {
ui_data_comm_row_t r;
if ((a_id >= s_n) || (ui_data_comm_row(a_id, &r) != 0)) {
return 0;
}
return (int32_t)r.val;
}
/*
* 函数功能:写某行(经通道六 → iec104_comm_*_set;守卫与置脏在带内执行侧)
* 入口参数:a_id - 行下标 uint8_t;a_val - 编辑器提交的整数 int32_t
* 返回值:无(结果经 cm_note_write 记账)
* 限定条件:set 回调链内
* 函数说明:负数(编辑器理论不产)原样送 setter 拒掉,本页不做第二次守卫
* ——合法带唯一出口在 iec104_comm.h,抄一份就是第二真源
*/
static void cm_write(uint8_t a_id, int32_t a_val) {
if (a_id >= s_n) {
return;
}
cm_note_write(a_id, ui_data_comm_set(a_id, (uint32_t)a_val));
}
/*
* 函数功能:开页建表 + 绑视图(接 init_cb)
* 入口参数:无
* 返回值:无
* 限定条件:框架开页链内(本次进入权限已装载——先装权限再调 init_cb 的
* 时序依据见 ui_page_view_param.c 同位置注释)
* 函数说明:两行逐行现取(lo/hi/值全现给);读到第 i 行失败停在 i 行——
* 半张表比空表危险的反面论证同 ui_w_ytview.yt_fill;未注入 =
* 0 行空表页,一个像素都不画假数据
*/
static void pg_init(void) {
uint8_t i;
s_st = CM_ST_ENTER;
s_badmap = 0u;
s_n = 0u;
for (i = 0u; i < (uint8_t)UI_DATA_COMM_ROW_N; i++) {
ui_data_comm_row_t r;
if (ui_data_comm_row(i, &r) != 0) {
break;
}
s_rows[i].name = k_comm_name[i];
s_rows[i].id = i;
s_rows[i].kind = UI_W_SETLIST_KIND_NUM;
s_rows[i].decimals = 0u;
s_rows[i].min = (int32_t)r.lo;
s_rows[i].max = (int32_t)r.hi;
s_rows[i].opts = NULL;
s_rows[i].unit = NULL; /* CA 与端口都不是物理量,不挂单位 */
s_n++;
}
(void)memset(&s_sl, 0, sizeof(s_sl));
s_sl.rows = s_rows;
s_sl.count = s_n;
s_sl.get = cm_get;
s_sl.set = cm_write;
s_sl.bad = cm_bad;
if (ui_content_page_is_editable() != false) {
s_sl.commit = cm_commit;
s_sl.state = cm_state;
}
ui_w_setlist_reset(&s_sl);
}
/*
* 函数功能:总行数(数据行实给 + 可编辑态才有保存行;接 count_cb)
* 入口参数:无
* 返回值:总行数 uint16_t
* 限定条件:框架绘制/翻页链内
*/
static uint16_t pg_count(void) {
return ui_w_setlist_count(&s_sl);
}
/*
* 函数功能:逐行取数(行现状在组件与注入表里现取,本层无缓存)
* 入口参数:a_row / a_name / a_value - 契约见 ui_content_page.h
* 返回值:无
* 限定条件:框架绘制链内
*/
static void pg_refresh(uint16_t a_row, char *a_name, char *a_value) {
ui_w_setlist_refresh(&s_sl, a_row, a_name, a_value);
}
/*
* 函数功能:自绘层(编辑光标反显 + 写被拒行反显)
* 入口参数:a_layer / a_clip - 契约见 ui_content_page.h
* 返回值:无
* 限定条件:框架绘制链内,内置区块画完之后
*/
static void pg_draw(lv_layer_t *a_layer, const lv_area_t *a_clip) {
ui_w_setlist_draw(&s_sl, a_layer, a_clip);
}
/*
* 函数功能:按键转发(接 key_cb)
* 入口参数:a_key - LVGL 键值 lv_key_t
* 返回值:true - 本页已消费;false - 交回框架(↑↓ 移选、← 关页)
* 限定条件:描述符 edit_capable=1 + key_intercept=1(编辑中 ←→ 移数字光标,
* 必须先给页面——整定四页同款实证)
* 函数说明:第一条门 = 只读进入(未绑 commit)整页交回框架,与"本页没有
* key_cb"逐字等价(黄金只读态为证)
*/
static bool pg_key(lv_key_t a_key) {
if (s_sl.commit == NULL) {
return false;
}
return (ui_w_setlist_key(&s_sl, a_key) != 0u);
}
/*
* 页面描述符(外部链接:生成物 ui_page_registry.c 按菜单树 #page=comm 绑定引用)
* 列表页骨架 + 可编辑 + ← 拦截;row_count 给静态上限(2 数据行 + 保存行 = 3),
* 运行时以注入表现报为准;band_h>0 选中反显(死区页同款几何令牌)
*/
const content_page_def_t ui_page_comm_desc = {
.id = "comm",
.title = "通讯设置",
.selectable = 1u,
.edit_capable = 1u,
.key_intercept = 1u,
.top_y = UI_LIST_TOP,
.pitch = UI_ROW_PITCH,
.band_h = UI_ROW_BAND_H,
.text_dy = 0,
.left_x = UI_LIST_LEFT_X,
.right_x = UI_LIST_RIGHT_X,
.rows_per_page = UI_LIST_ROWS,
.row_count = 3u,
.init_cb = pg_init,
.count_cb = pg_count,
.refresh = pg_refresh,
.draw_cb = pg_draw,
.key_cb = pg_key,
};
+25
View File
@@ -0,0 +1,25 @@
/*
* 模块名称:UI Page Comm (通讯设置内容页对外声明)
* 模块功能:供生成物 ui_page_registry.c 引用的页面描述符声明
* 适用平台:STM32F407ZGTx / PC 模拟器(共用源码)
* 作者:DTU 项目组
* 创建日期:2026-10-27
* 修改记录:
* v1.0 2026-10-27 DTU 项目组 创建(道G task-9)
*/
#ifndef UI_PAGE_COMM_H
#define UI_PAGE_COMM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ui_content_page.h"
extern const content_page_def_t ui_page_comm_desc;
#ifdef __cplusplus
}
#endif
#endif /* UI_PAGE_COMM_H */
+2
View File
@@ -13,6 +13,7 @@
#include "ui_page_calib.h"
#include "ui_page_clear.h"
#include "ui_page_clock.h"
#include "ui_page_comm.h"
#include "ui_page_dc.h"
#include "ui_page_deadband.h"
#include "ui_page_device_info.h"
@@ -46,6 +47,7 @@ const ui_page_entry_t g_ui_page_map[UI_PAGE_MAP_COUNT] = {
{ 24u, &ui_page_clock_desc }, /* node 24 时钟设置 */
{ 25u, &ui_page_reset_desc }, /* node 25 强制复归 */
{ 27u, &ui_page_clear_desc }, /* node 27 清除记录 */
{ 29u, &ui_page_comm_desc }, /* node 29 通讯设置 */
{ 30u, &ui_page_net_cfg_desc }, /* node 30 网口设置 */
{ 33u, &ui_page_soe_desc }, /* node 33 SOE记录 */
{ 39u, &ui_page_selftest_desc }, /* node 39 自检记录 */
+1 -1
View File
@@ -25,7 +25,7 @@ typedef struct {
const content_page_def_t *desc; /* 页面描述符(Flash const) */
} ui_page_entry_t;
#define UI_PAGE_MAP_COUNT 21u /* 绑定了内容页的叶子数 */
#define UI_PAGE_MAP_COUNT 22u /* 绑定了内容页的叶子数 */
extern const ui_page_entry_t g_ui_page_map[UI_PAGE_MAP_COUNT];