Files
STM32F4-Base/Drivers/BSP/UI/ui_w_records.c
T
wandering1 64abefaa00 refactor(UI): U2 合并运行/自检记录两页为共享组件 ui_w_records
ui_page_runlog.c 与 ui_page_selftest.c 各 102 行,逐行比对后差异全是命名:
唯一的功能变量是日志 ID(SYSLOG_RUN / SYSLOG_SELFTEST),计数、每记录 2 行、
同记录读盘缓存、空态伪行的实现两边逐字相同。是真重复,不是推测出的抽象。

## 落地
新建 Drivers/BSP/UI/ui_w_records.{c,h}(已在 uvprojx + CMakeLists 双端注册;
生成器只自动管 ui_page_*.c,故这两处手工加)。两页各留一个实例与两个薄跳板,
.count_cb/.refresh 名字不变 => 注册表与生成器零改动。
净效果:两页 90 删 / 28 增(−62 行),重复逻辑收成一份。

## 合并唯一的真陷阱:缓存归属
count_cb/refresh 签名里没有 user context,最容易写的版本是把
s_cache_valid / s_last_rec / s_ts / s_desc 留成组件级静态——那样两页共用一份
缓存,从 A 页切到 B 页会因记录号相同而直接命中缓存,显示另一页的陈旧行,
是静默错数据而非崩溃。故缓存内嵌进实例(ui_w_records_t),每页各一份。

## 验证
@build 0 错 0 警;golden 经真实 ui-golden 钩子跑通:菜单 8 状态 + 内容页
11 页(含这两页)逐字节一致,未用 --update 刷基线 => 语义搬迁行为等价有证。
ER_IROM1 232,052 → 231,936 B(−116 B)。RW_IRAM1 75,232 → 75,240 B(+8 B),
原因如实记录:原先 4 个文件级静态零初始化落 ZI,现在 s_rec 带 .id 初值整个
结构体落 .data(RW),两页合计净 +8 B;要压回 0 需把 .id 留零再加 init 钩子,
为 8 字节引入运行时初始化顺序不值得,故保留并把账写在此处。
stack_report FAIL 行数 0(间接层未顶破栈预算);mem-budget / mem-numbers 已
按 @build 后规定回填台账。

## 过程中的两处自我失误(已修复,记录以免重犯)
① 用 stem[:2] 生成函数前缀,对 selftest 得到 se_ 而非 st_,锚点失配。
② 撤销脚本里 ${UI_DIR} 被 PowerShell here-string 插值吞掉,导致"边校验边写"
   把树留在引用组件但未注册的链接错误态。教训:回滚脚本必须比正向脚本更保守,
   全部校验通过后才允许写盘。
2026-10-20 22:57:13 +08:00

71 lines
2.3 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.
/*
* 模块名称:UI 记录页共享组件实现
* 模块功能:见 ui_w_records.h(逻辑照搬合并前的 ui_page_runlog.c / ui_page_selftest.c,
* 两文件差异仅为日志 ID 与符号名,其余逐字相同)
* 适用范围:Drivers/BSP/UI
* 作者:王建锋
* 创建日期:2026-10-20
* 修改记录:
* v1.0 2026-10-20 王建锋 创建(W6 U2)
*/
#include <string.h>
#include "ui_w_records.h"
#include "ui_tokens.h"
/* 函数定义区 */
/*
* 函数功能:总行数(动态;每条记录 2 行,空日志 = 单条伪行"无记录")
* 入口参数:a_inst - 记录页实例 ui_w_records_t *
* 返回值:总行数 uint16_t
*/
uint16_t ui_w_records_count(ui_w_records_t *a_inst) {
uint32_t n = syslog_count(a_inst->id);
if (n == 0u) {
return 1u; /* 空态伪行(页脚"共 1 页",避免"共 0 页") */
}
return (uint16_t)(n * 2u);
}
/*
* 函数功能:逐行取数(偶数行 = 时间戳、奇数行 = 描述;值列恒空)
* 入口参数:a_inst - 记录页实例 ui_w_records_t *
* a_row - 全局行下标 uint16_t
* a_name - 名输出缓冲 char *
* a_value- 值输出缓冲(恒写空串) char *
* 限定条件:页面打开中(框架绘制/按键上下文,uiTask)
*/
void ui_w_records_refresh(ui_w_records_t *a_inst, uint16_t a_row, char *a_name, char *a_value) {
uint32_t n = syslog_count(a_inst->id);
a_value[0] = '\0';
if (n == 0u) {
(void)memcpy(a_name, "无记录", sizeof("无记录"));
return;
}
{
uint32_t rec = a_row / 2u;
if (!a_inst->cache_valid || rec != a_inst->last_rec) {
if (syslog_get_record(a_inst->id, rec, a_inst->ts, sizeof(a_inst->ts),
a_inst->desc, sizeof(a_inst->desc)) != 0) {
a_name[0] = '\0'; /* 读失败(越界/存储异常):空行防御 */
return;
}
a_inst->last_rec = rec;
a_inst->cache_valid = 1u;
}
if ((a_row % 2u) == 0u) {
(void)memcpy(a_name, a_inst->ts, sizeof(a_inst->ts));
}
else {
(void)memcpy(a_name, a_inst->desc, sizeof(a_inst->desc));
}
}
}