a6cdebde62
- D-6 目录规范化:docs 根目录散落文档归入 UI设计/子系统设计/架构设计/审查记录/ 环境与部署/网络 等子目录,去掉目录名空格,重命名 嵌入式C语言代码规范_V1.0.md - D-7 三档一致性门禁:新增 scripts/check_doc_links.py(链接存在性)、 scripts/gen_task_table.py(FreeRTOS 任务表数值)、scripts/check_mem_numbers.py (内存/Flash 体积),均支持 --check/--write/--diff,pre-commit 钩子同步注册 - D-5 文档索引:新建 docs/README.md,新建 docs/文档规范.md 约束目录命名与链接写法 - D-1 芯片手册瘦身:删除 1069 张无引用孤儿图片(77.06 MB), docs/芯片手册 120 MB → 41 MB,已引用图片零断链 - 同步 C 源码注释中的文档路径引用(D-6 重组后),构建 0 错误 0 警告
100 lines
3.4 KiB
C
100 lines
3.4 KiB
C
/*
|
||
* 模块名称:UI Page SelfTest (自检记录内容页)
|
||
* 模块功能:自检记录叶子节点(node 39)的内容页数据——动态列表,每条记录 2 行
|
||
* (偶数行 = 时间戳、奇数行 = 故障描述),可移选分页;数据源 = sys_log API
|
||
* (/log/selftest.log,开机自检故障,仅故障才写);空日志显示单条伪行"无记录";
|
||
* 向框架 ui_content_page 提供页面描述符(零 LVGL 对象)
|
||
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
|
||
* 作者:王建锋
|
||
* 创建日期:2026-09-14
|
||
* 修改记录:
|
||
* v1.0 2026-09-14 王建锋 创建初始版本(设计见 docs/子系统设计/运行与自检记录设计说明.md §5.4)
|
||
*/
|
||
|
||
/* 头文件包含区 */
|
||
#include <string.h>
|
||
|
||
#include "ui_page_selftest.h"
|
||
|
||
#include "sys_log.h"
|
||
|
||
/* 静态变量定义区 */
|
||
|
||
/* 最近读取的记录缓存(偶数行读盘后,奇数行复用;避免同记录重复 I/O) */
|
||
static uint8_t s_cache_valid; /* 缓存有效标志(0 = 无缓存) */
|
||
static uint32_t s_last_rec; /* 已缓存的记录序号 */
|
||
static char s_ts[SYSLOG_TS_LEN + 1u];
|
||
static char s_desc[SYSLOG_DESC_MAX + 1u];
|
||
|
||
/* 函数定义区 */
|
||
|
||
/*
|
||
* 函数功能:总行数(动态;每条记录 2 行,空日志 = 单条伪行"无记录")
|
||
* 入口参数:无
|
||
* 返回值:总行数 uint16_t
|
||
*/
|
||
static uint16_t st_count_cb(void) {
|
||
uint32_t n = syslog_count(SYSLOG_SELFTEST);
|
||
|
||
if (n == 0u) {
|
||
return 1u; /* 空态伪行(页脚"共 1 页",避免"共 0 页") */
|
||
}
|
||
return (uint16_t)(n * 2u);
|
||
}
|
||
|
||
/*
|
||
* 函数功能:逐行取数(偶数行 = 时间戳、奇数行 = 故障描述;值列恒空)
|
||
* 入口参数:row - 全局行下标 uint16_t
|
||
* name - 名输出缓冲(框架栈缓冲 CP_ROW_BUF_LEN=32,含 NUL) char *
|
||
* value - 值输出缓冲(同上;本页恒写空串) char *
|
||
* 限定条件:页面打开中(框架绘制/按键上下文,uiTask)
|
||
*/
|
||
static void st_refresh(uint16_t row, char *name, char *value) {
|
||
uint32_t n = syslog_count(SYSLOG_SELFTEST);
|
||
|
||
value[0] = '\0';
|
||
if (n == 0u) {
|
||
(void)memcpy(name, "无记录", sizeof("无记录"));
|
||
return;
|
||
}
|
||
|
||
{
|
||
uint32_t rec = row / 2u;
|
||
|
||
if (!s_cache_valid || rec != s_last_rec) {
|
||
if (syslog_get_record(SYSLOG_SELFTEST, rec, s_ts, sizeof(s_ts), s_desc, sizeof(s_desc)) != 0) {
|
||
name[0] = '\0'; /* 读失败(越界/存储异常):空行防御 */
|
||
return;
|
||
}
|
||
s_last_rec = rec;
|
||
s_cache_valid = 1u;
|
||
}
|
||
if ((row % 2u) == 0u) {
|
||
(void)memcpy(name, s_ts, sizeof(s_ts));
|
||
}
|
||
else {
|
||
(void)memcpy(name, s_desc, sizeof(s_desc));
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 页面描述符(外部链接:框架描述符表 s_defs[] 直接引用):
|
||
* 动态列表页——每记录 2 行、8 行/页 = 4 条/页;band_h=13(同 AC/DC 约定:
|
||
* selectable 页选中行黑字必须配白带,band_h=0 会致选中行不可见);
|
||
* 时间戳 19 ASCII ≈114px < 屏宽可容
|
||
*/
|
||
const content_page_def_t ui_page_selftest_desc = {
|
||
.title = "自检记录",
|
||
.selectable = 1u,
|
||
.top_y = 24,
|
||
.pitch = 14,
|
||
.band_h = 13,
|
||
.text_dy = 0,
|
||
.left_x = 7,
|
||
.right_x = 101,
|
||
.rows_per_page = 8u,
|
||
.count_cb = st_count_cb,
|
||
.refresh = st_refresh,
|
||
};
|