门禁扩容:新增 lv-conf-sync、simulator/ 纳入全部钩子;含 L3 定值/元件框架落地
本轮把"自研代码落在门禁之外"的口子收掉,同时落地 LVGL 特性裁剪与 L3 保护定值/元件框架。 门禁(.pre-commit-config.yaml,26 个钩子) - 新增 scripts/check_lv_conf_sync.py + 钩子 lv-conf-sync:比对两份 lv_conf.h 的**生效值**(未定义则取 lv_conf_internal.h 兜底默认), 抓 MISMATCH / LVGL 不认的宏名 / 同文件重复定义 - 顶层 exclude 删掉 simulator/:其下 21 个 tracked 文件全是本项目自研 代码,生成物(build/、SDL2/、tests/ref/、shot*)已在 .gitignore; doc-links 的 exclude 同步删除 - lv-conf-sync 的 files: 覆盖两端配置 → 只改 simulator/lv_conf.h 也触发 (pre-commit 4.x 已移除 always: true,实测只告警并跳过,无兜底开关) - 新增 prot-set-unit-test / prot-elm-unit-test 两个主机侧单测钩子 - S11(2.3.5) 判定细化:禁的是"用路径找文件",尖括号系统头带子目录 (如 <sys/stat.h>)不再误报;全仓库复核仅 2 处项目代码判定变化 模拟器代码整改(纳入钩子后暴露,全部修代码而非豁免) - cppcheck 4 处:sim_syslog.c 判空分支内解引用 p_epoch(真实 bug)、 2 处 struct tm 未初始化、1 处指针可加 const - coding-standard 61 处:44 处函数左大括号并到右括号同行、8 处补函数 注释、3 处补文件头注释块、2 处 __ 前缀保护宏改 XXX_H、2 处 sprintf 改 snprintf(写入字节数与原来完全一致) LVGL 特性裁剪(F-1/F-2/F-3) - 两端 lv_conf.h 对齐同一特性子集:删 26 个 LVGL 9.3 不存在的选项名、 3 处重复定义,10 项靠默认值隐式生效的改为显式固化 - 实测对镜像体积中性;价值在防漂移,且模拟器 golden 回归跑的正是固件 实际编译的配置 L3 软件侧 - App/algo/prot_set.* Q10 定值模型(范围校验 / 整表 all-or-nothing / 校验和封存-自检-闭锁)+ prot_elm.* 通用"滞回+定时限"元件框架 7 实例 - test/host/prot_set、test/host/prot_elm 主机侧单测;uvprojx 挂载两处 文档同步 - pre-commit使用说明:§2.8 S11 口径、§2.15 lv-conf-sync 详解、新增 §5.5 复盘(教训:exclude 只写真正不该进钩子的路径) - AGENTS.md、UI_设计架构 §1.4 第 10 条、RAM 分析、审查报告刷新与销项 验证 - @build BUILD_OK 0/0(Code=194276 RO=15872 RW=876 ZI=139892) - 模拟器重建:菜单 8 状态像素逐字节一致(池 5368 B)、11 内容页黄金参考 全过(往返 5448 B)、remo sink 0/25600 位差异、--logtest/--cfgtest PASS - 全仓库 cppcheck / coding-standard / no-mojibake --all-files 全过 - check_doc_links --all 129/0;check_mem_numbers --check 内存数字一致 - 端到端:往 simulator/lv_conf.h 注入一行漂移 → 钩子 FAIL(exit 1)
This commit is contained in:
@@ -141,4 +141,4 @@ if (Test-Path $exe) {
|
||||
}
|
||||
Write-Host "[build_sim] 构建退出码 0 但未找到 $exe" -ForegroundColor Red
|
||||
exit 1
|
||||
|
||||
|
||||
|
||||
+12
-3
@@ -1,4 +1,13 @@
|
||||
/*
|
||||
* 模块名称:模拟器调试日志 stub(dbg_log.h)
|
||||
* 模块功能:覆盖 MCU 工程的 Drivers/BSP/dbg_log.h,把 DBG_* 直接映射到宿主 printf
|
||||
* (模拟器无 sys_clock/RTC,日志走 PC 控制台)
|
||||
* 适用平台:Windows / Linux / macOS(PC 模拟器)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-08-31
|
||||
* 修改记录:
|
||||
* v1.0 2026-08-31 王建锋 创建:模拟器侧 DBG_* stub
|
||||
*
|
||||
* dbg_log.h — 模拟器专用调试日志 stub(覆盖 MCU 工程的 Drivers/BSP/dbg_log.h)
|
||||
*
|
||||
* 模拟器不使用 sys_clock.h / RTC,因此把 DBG_* 宏直接映射到 printf,
|
||||
@@ -6,8 +15,8 @@
|
||||
* DBG_TAG 仍需各 .c 文件在 include 前定义,这里保留该约定。
|
||||
*/
|
||||
|
||||
#ifndef __DBG_LOG_H
|
||||
#define __DBG_LOG_H
|
||||
#ifndef DBG_LOG_H
|
||||
#define DBG_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -35,4 +44,4 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DBG_LOG_H */
|
||||
#endif /* DBG_LOG_H */
|
||||
|
||||
+32
-23
@@ -1,4 +1,16 @@
|
||||
/**
|
||||
* 模块名称:LVGL 配置 —— PC 模拟器侧(simulator/lv_conf.h)
|
||||
* 模块功能:LVGL v9.3.0 编译期特性裁剪与 SDL2 适配(160x160 1bpp 单色)
|
||||
* 适用平台:Windows(CMake + SDL2)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-08-31
|
||||
* 修改记录:
|
||||
* v1.0 2026-08-31 王建锋 创建:基于 Lib/lv_conf.h 适配 PC 模拟器
|
||||
*
|
||||
* ⚠ 本文件与 `Lib/lv_conf.h`(MCU 端)必须保持**同一特性子集**,已由门禁校验:
|
||||
* `python scripts/check_lv_conf_sync.py`(pre-commit 钩子 lv-conf-sync,
|
||||
* 两端任一改动都会触发)。规则正文见 docs/UI设计/UI_设计架构.md §1.4 第 10 条。
|
||||
*
|
||||
* @file lv_conf.h
|
||||
* @brief LVGL v9.3.0 配置 — Windows SDL2 模拟器(160x160 1bpp 单色)
|
||||
* @note 基于项目 Lib/lv_conf.h 适配,用于 PC 模拟器 UI 开发
|
||||
@@ -51,7 +63,8 @@
|
||||
|
||||
/** 复杂绘制:主界面顶部开口浅 V 装饰含斜线(lv_line 斜段依赖 LV_DRAW_SW_COMPLEX),须与 MCU 端一致保持开启,否则两腿不渲染 */
|
||||
#define LV_DRAW_SW_COMPLEX 1
|
||||
#define LV_DRAW_SW_COMPLEX_GRADIENTS 0
|
||||
/* 注:9.3 没有 LV_DRAW_SW_COMPLEX_GRADIENTS / LV_DRAW_SW_YIELD / LV_DRAW_SW_ASYNC
|
||||
* (9.4 才引入),原定义无效,已删 */
|
||||
#define LV_DRAW_SW_SHADOW_CACHE_SIZE 0
|
||||
#define LV_DRAW_SW_CIRCLE_CACHE_SIZE 4 /* LV_DRAW_SW_COMPLEX 依赖非零(零长数组 C2466);与 MCU 端默认一致 */
|
||||
#define LV_DRAW_LAYER_SIMPLE_BUF_SIZE 0
|
||||
@@ -72,16 +85,13 @@
|
||||
#define LV_DRAW_SW_SUPPORT_I1 1
|
||||
#define LV_DRAW_SW_I1_LUM_THRESHOLD 127
|
||||
|
||||
/** 关闭 GPU/矢量绘制 */
|
||||
/** 关闭 GPU/矢量绘制(注:9.3 无 LV_USE_DRAW_NEMA_GFX / PPA / EVE / NANOVG,
|
||||
* 属更新版本 lv_conf_template 残留,原定义无效,已删) */
|
||||
#define LV_USE_DRAW_VG_LITE 0
|
||||
#define LV_USE_DRAW_DAVE2D 0
|
||||
#define LV_USE_DRAW_NEMA_GFX 0
|
||||
#define LV_USE_DRAW_PXP 0
|
||||
#define LV_USE_DRAW_PPA 0
|
||||
#define LV_USE_DRAW_DMA2D 0
|
||||
#define LV_USE_DRAW_EVE 0
|
||||
#define LV_USE_DRAW_G2D 0
|
||||
#define LV_USE_DRAW_NANOVG 0
|
||||
#define LV_USE_DRAW_OPENGLES 0
|
||||
#define LV_USE_DRAW_SDL 0
|
||||
#define LV_USE_THORVG 0
|
||||
@@ -105,11 +115,10 @@
|
||||
#define LV_OBJ_ID_AUTO_ASSIGN 1
|
||||
#define LV_USE_OBJ_ID_BUILTIN 1
|
||||
#define LV_USE_OBJ_PROPERTY 0
|
||||
#define LV_USE_EXT_DATA 0
|
||||
#define LV_USE_FLOAT 0
|
||||
#define LV_USE_OBSERVER 0
|
||||
#define LV_USE_TRANSLATION 0
|
||||
#define LV_USE_COLOR_FILTER 0
|
||||
/* 注:9.3 无 LV_USE_EXT_DATA / LV_USE_TRANSLATION(9.4 才有),原两行无效,已删 */
|
||||
|
||||
/*============================================================================
|
||||
* LOGGING
|
||||
@@ -126,7 +135,7 @@
|
||||
/*============================================================================
|
||||
* LAYOUTS
|
||||
*============================================================================*/
|
||||
#define LV_USE_FLEX 1
|
||||
#define LV_USE_FLEX 0 /* 2026-10-11 与 MCU 端一致:全仓无 lv_obj_set_flex_* 调用 */
|
||||
#define LV_USE_GRID 0
|
||||
|
||||
/*============================================================================
|
||||
@@ -142,7 +151,6 @@
|
||||
#define LV_USE_BMP 0
|
||||
#define LV_USE_TJPGD 0
|
||||
#define LV_USE_LIBJPEG_TURBO 0
|
||||
#define LV_USE_LIBWEBP 0
|
||||
#define LV_USE_SVG 0
|
||||
|
||||
/*============================================================================
|
||||
@@ -190,7 +198,7 @@
|
||||
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(ui_font_cn_12)
|
||||
#define LV_FONT_DEFAULT &ui_font_cn_12
|
||||
|
||||
#define LV_USE_CUSTOM_FONT_DEFAULT 0
|
||||
/* 注:9.3 无 LV_USE_CUSTOM_FONT_DEFAULT,原行无效,已删 */
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
#define LV_USE_FONT_COMPRESSED 0
|
||||
#define LV_USE_FONT_PLACEHOLDER 1
|
||||
@@ -207,11 +215,10 @@
|
||||
#define LV_USE_3DTEXTURE 0
|
||||
#define LV_USE_ANIMIMG 0
|
||||
#define LV_USE_ARC 0
|
||||
#define LV_USE_ARCLABEL 0
|
||||
#define LV_USE_BAR 0
|
||||
#define LV_USE_BARCODE 0
|
||||
#define LV_USE_BUTTON 1
|
||||
#define LV_USE_BUTTONMATRIX 1
|
||||
#define LV_USE_BUTTON 0
|
||||
#define LV_USE_BUTTONMATRIX 0
|
||||
#define LV_USE_CALENDAR 0
|
||||
#define LV_USE_CANVAS 0
|
||||
#define LV_USE_CHART 0
|
||||
@@ -219,13 +226,16 @@
|
||||
#define LV_USE_DROPDOWN 0
|
||||
#define LV_USE_FFMPEG 0
|
||||
#define LV_USE_GIF 0
|
||||
#define LV_USE_GLTF 0
|
||||
#define LV_USE_GSTREAMER 0
|
||||
#define LV_USE_IMAGE 1
|
||||
/* 注:9.3 无 LV_USE_GLTF / LV_USE_GSTREAMER / LV_USE_ARCLABEL(更新版本残留),已删 */
|
||||
/* 2026-10-11(F-2/F-3 对齐 MCU 端 Lib/lv_conf.h):本项目 UI 全部自绘,
|
||||
* 三处代码(Drivers/BSP/UI、App、simulator)零控件构造函数、零 flex/grid 调用。
|
||||
* 关掉后模拟器与固件跑的是同一套特性子集,golden 回归才能真正验证 MCU 配置。
|
||||
* 若将来引入控件型页面(U2 原型库),两端同步逐项打开并复跑 ui-verify。 */
|
||||
#define LV_USE_IMAGE 0
|
||||
#define LV_USE_IMAGEBUTTON 0
|
||||
#define LV_USE_IME_PINYIN 0
|
||||
#define LV_USE_KEYBOARD 1
|
||||
#define LV_USE_LABEL 1
|
||||
#define LV_USE_KEYBOARD 0
|
||||
#define LV_USE_LABEL 0
|
||||
#define LV_LABEL_TEXT_SELECTION 0
|
||||
#define LV_LABEL_LONG_TXT_HINT 0
|
||||
#define LV_LABEL_WAIT_CHAR_COUNT 0
|
||||
@@ -244,7 +254,7 @@
|
||||
#define LV_USE_SPINBOX 0
|
||||
#define LV_USE_SPINNER 0
|
||||
#define LV_USE_SWITCH 0
|
||||
#define LV_USE_TEXTAREA 1
|
||||
#define LV_USE_TEXTAREA 0
|
||||
#define LV_USE_TABLE 0
|
||||
#define LV_USE_TABVIEW 0
|
||||
#define LV_USE_TILEVIEW 0
|
||||
@@ -288,13 +298,12 @@
|
||||
#define LV_USE_WINDOWS 0
|
||||
|
||||
/*============================================================================
|
||||
* THEMES (补充)
|
||||
* THEMES 子选项(LV_USE_THEME_DEFAULT / SIMPLE 本体已在上面 THEMES 块定义,
|
||||
* 此处勿重复定义——同文件重复 #define 后者生效,极易误读)
|
||||
*============================================================================*/
|
||||
#define LV_USE_THEME_DEFAULT 0
|
||||
#define LV_THEME_DEFAULT_DARK 0
|
||||
#define LV_THEME_DEFAULT_GROW 0
|
||||
#define LV_THEME_DEFAULT_TRANSITION_TIME 0
|
||||
#define LV_USE_THEME_SIMPLE 0
|
||||
|
||||
/*============================================================================
|
||||
* EXPORTS
|
||||
|
||||
+55
-38
@@ -1,4 +1,12 @@
|
||||
/**
|
||||
* 模块名称:PC 模拟器入口(simulator/main.c)
|
||||
* 模块功能:在 PC 上以 SDL2 跑**与固件同一套** UI 源码,提供窗口调试与多种无头自检模式
|
||||
* 适用平台:Windows(CMake + SDL2)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-08-31
|
||||
* 修改记录:
|
||||
* v1.0 2026-08-31 王建锋 创建:基于 lv_port_pc_vscode 适配
|
||||
*
|
||||
* @file main.c
|
||||
* @brief LVGL 模拟器入口 — 160x160 1bpp 单色菜单 UI
|
||||
* @note 基于 lv_port_pc_vscode 适配,用于 PC 上 UI 开发与调试
|
||||
@@ -69,30 +77,35 @@
|
||||
static uint8_t g_shot_buf[SIM_SCREEN_W * SIM_SCREEN_H / 8];
|
||||
|
||||
/*
|
||||
* @brief 离屏截图用空 delay 回调
|
||||
* @note 默认 lv_delay_ms 会忙等 tick 前进,但离屏渲染时 tick 不会在等待期间推进,
|
||||
* 导致死循环挂死。window 模式经 SDL 设了真实 delay,离屏这里用空实现代替。
|
||||
* 函数功能:离屏截图用的空 delay 回调
|
||||
* 入口参数:ms - 请求延时的毫秒数(未使用) uint32_t
|
||||
* 返回值:无
|
||||
* 说明:默认 lv_delay_ms 会忙等 tick 前进,但离屏渲染时 tick 不会在等待期间推进,
|
||||
* 导致死循环挂死。window 模式经 SDL 设了真实 delay,离屏这里用空实现代替。
|
||||
*/
|
||||
static void shot_delay_cb(uint32_t ms)
|
||||
{
|
||||
static void shot_delay_cb(uint32_t ms) {
|
||||
(void)ms;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 离屏截图 flush 回调(不写真实设备,直接标记就绪)
|
||||
* 函数功能:离屏截图 flush 回调(不写真实设备,直接标记就绪)
|
||||
* 入口参数:disp - LVGL 显示对象 lv_display_t *
|
||||
* area - 刷新区域(未使用) const lv_area_t *
|
||||
* color_p - 像素缓冲(未使用) uint8_t *
|
||||
* 返回值:无
|
||||
*/
|
||||
static void shot_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p)
|
||||
{
|
||||
static void shot_flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * color_p) {
|
||||
(void)area;
|
||||
(void)color_p;
|
||||
lv_display_flush_ready(disp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 键序列字符 → LVGL 键值(非键字符返回 0 = 忽略)
|
||||
* 函数功能:键序列字符 → LVGL 键值映射(--keys 无头回归用)
|
||||
* 入口参数:c - 键序列字符(u=↑ d=↓ l=← r=→ e=确认 s=返回) char
|
||||
* 返回值:LVGL 键值;非键字符返回 0 = 忽略 uint32_t
|
||||
*/
|
||||
static uint32_t sim_map_key_char(char c)
|
||||
{
|
||||
static uint32_t sim_map_key_char(char c) {
|
||||
switch (c) {
|
||||
case 'u': return LV_KEY_UP;
|
||||
case 'd': return LV_KEY_DOWN;
|
||||
@@ -105,12 +118,14 @@ static uint32_t sim_map_key_char(char c)
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 待机屏底部时钟提供回调(平台差异:模拟器 = 宿主 time())
|
||||
* 函数功能:待机屏底部时钟提供回调(平台差异:模拟器 = 宿主 time())
|
||||
* 入口参数:buf - 输出缓冲(格式化时间串) char *
|
||||
* len - 缓冲长度 size_t
|
||||
* 返回值:无
|
||||
*/
|
||||
static void sim_time_cb(char *buf, size_t len)
|
||||
{
|
||||
static void sim_time_cb(char *buf, size_t len) {
|
||||
time_t t = time(NULL);
|
||||
struct tm tmv;
|
||||
struct tm tmv = {0}; /* 显式清零:localtime_s/r 是"输出型"参数,静态分析按未初始化报 */
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
localtime_s(&tmv, &t);
|
||||
@@ -123,14 +138,13 @@ static void sim_time_cb(char *buf, size_t len)
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 无窗口离屏渲染(可注入键序列)并导出末帧像素
|
||||
* @param keys 键序列(u=上 d=下 l=左 r=右 e=确认 s=返回;空 = 不注键)
|
||||
* @param path 输出文件(写入 160x160 I1 原始像素)
|
||||
* @param standby 非 0 = 注键后强制进入待机屏再截图(--standby 模式)
|
||||
* @return 0 成功,非 0 失败
|
||||
* 函数功能:无窗口离屏渲染(可注入键序列)并导出末帧像素
|
||||
* 入口参数:keys - 键序列(u=上 d=下 l=左 r=右 e=确认 s=返回;空 = 不注键) const char *
|
||||
* path - 输出文件(写入 160x160 I1 原始像素) const char *
|
||||
* standby - 非 0 = 注键后强制进入待机屏再截图(--standby 模式) int
|
||||
* 返回值:0 - 成功;非 0 - 失败 int
|
||||
*/
|
||||
static int run_headless(const char * keys, const char * path, int standby)
|
||||
{
|
||||
static int run_headless(const char * keys, const char * path, int standby) {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
lv_init();
|
||||
lv_delay_set_cb(shot_delay_cb);
|
||||
@@ -209,7 +223,7 @@ static int run_headless(const char * keys, const char * path, int standby)
|
||||
uint32_t snap_h = snap->header.h;
|
||||
/* I1 缓冲区布局:[palette 8B][pixel data],跳过 palette 只写像素 */
|
||||
uint32_t pal_bytes = LV_COLOR_INDEXED_PALETTE_SIZE(LV_COLOR_FORMAT_I1) * (uint32_t)sizeof(lv_color32_t);
|
||||
uint8_t * px = snap->data + pal_bytes;
|
||||
const uint8_t * px = snap->data + pal_bytes; /* 只读:写文件时不再改动快照 */
|
||||
uint32_t px_bytes = (uint32_t)snap->header.stride * (uint32_t)snap_h;
|
||||
FILE *fp = fopen(path, "wb");
|
||||
if (fp == NULL) {
|
||||
@@ -239,13 +253,13 @@ static const char s_cfgtest_doc[] =
|
||||
static const uint8_t s_cfgtest_ip[4] = { 10u, 0u, 0u, 1u };
|
||||
|
||||
/*
|
||||
* @brief 配置轮询自检(无窗口、无需 LVGL/SDL,进程内闭环)
|
||||
* @note 验证链:net_cfg_load(只读 INI)→ poll 建基线 → 伪造外部编辑
|
||||
* → poll 两次(沉降去抖)→ 重载并更新 RAM 副本
|
||||
* @return 0 PASS,非 0 FAIL
|
||||
* 函数功能:配置轮询自检(无窗口、无需 LVGL/SDL,进程内闭环)
|
||||
* 入口参数:无
|
||||
* 返回值:0 - PASS;非 0 - FAIL int
|
||||
* 说明:验证链 net_cfg_load(只读 INI)→ poll 建基线 → 伪造外部编辑
|
||||
* → poll 两次(沉降去抖)→ 重载并更新 RAM 副本
|
||||
*/
|
||||
static int run_cfgtest(void)
|
||||
{
|
||||
static int run_cfgtest(void) {
|
||||
int i;
|
||||
const net_cfg_t *p_cfg;
|
||||
|
||||
@@ -367,13 +381,13 @@ static int run_cfgtest(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief 日志引擎自检(无窗口、进程内闭环)
|
||||
* @note 验证链:清理旧档 → post N 条 → count/get 回读断言 + 宿主文件字节级校验
|
||||
* (64B 定长、ISO 时间戳格式、epoch 字段 ≈ now、NUL 填充)
|
||||
* @return 0 PASS,非 0 FAIL
|
||||
* 函数功能:日志引擎自检(无窗口、进程内闭环)
|
||||
* 入口参数:无
|
||||
* 返回值:0 - PASS;非 0 - FAIL int
|
||||
* 说明:验证链 清理旧档 → post N 条 → count/get 回读断言 + 宿主文件字节级校验
|
||||
* (64B 定长、ISO 时间戳格式、epoch 字段 ≈ now、NUL 填充)
|
||||
*/
|
||||
static int run_logtest(void)
|
||||
{
|
||||
static int run_logtest(void) {
|
||||
uint32_t ep;
|
||||
char ts[SYSLOG_TS_LEN + 1u];
|
||||
char desc[SYSLOG_DESC_MAX + 1u];
|
||||
@@ -464,10 +478,13 @@ static int run_logtest(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 程序入口
|
||||
* 函数功能:模拟器入口(解析模式开关 → 窗口模式或无头自检)
|
||||
* 入口参数:argc - 参数个数 int
|
||||
* argv - 参数数组(--screenshot / --keys / --standby / --cfgtest /
|
||||
* --logtest / --idle) char **
|
||||
* 返回值:0 - 正常退出或自检 PASS;非 0 - 失败 int
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
/* 截图/自检模式:--screenshot / --keys / --standby / --cfgtest / --logtest */
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--screenshot") == 0 && (i + 1) < argc) {
|
||||
|
||||
@@ -53,8 +53,7 @@ static int s_generation = 0; /* 网络代次(模拟器恒为 0
|
||||
* 限定条件:无
|
||||
* 函数说明:任何 Socket 操作前先调用;已初始化则直接返回
|
||||
*/
|
||||
static int ensure_wsa(void)
|
||||
{
|
||||
static int ensure_wsa(void) {
|
||||
static int s_done = 0;
|
||||
|
||||
if (s_done == 0) {
|
||||
@@ -75,8 +74,7 @@ static int ensure_wsa(void)
|
||||
* 限定条件:s_socks 已定义
|
||||
* 函数说明:线性扫描,返回首个 in_use == 0 的控制块索引
|
||||
*/
|
||||
static int alloc_fd(void)
|
||||
{
|
||||
static int alloc_fd(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NET_MAX_SOCKETS; i++) {
|
||||
@@ -96,8 +94,7 @@ static int alloc_fd(void)
|
||||
* 限定条件:两结构体布局一致(均 16 字节,字段偏移相同)
|
||||
* 函数说明:字段偏移一致,按 sizeof 直接拷贝
|
||||
*/
|
||||
static void to_ws_addr(const struct net_sockaddr *addr, struct sockaddr_in *out)
|
||||
{
|
||||
static void to_ws_addr(const struct net_sockaddr *addr, struct sockaddr_in *out) {
|
||||
memcpy(out, addr, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
@@ -110,8 +107,7 @@ static void to_ws_addr(const struct net_sockaddr *addr, struct sockaddr_in *out)
|
||||
* 限定条件:两结构体布局一致(均 16 字节,字段偏移相同)
|
||||
* 函数说明:字段偏移一致,按 sizeof 直接拷贝
|
||||
*/
|
||||
static void from_ws_addr(const struct sockaddr_in *in, struct net_sockaddr *out)
|
||||
{
|
||||
static void from_ws_addr(const struct sockaddr_in *in, struct net_sockaddr *out) {
|
||||
memcpy(out, in, sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
@@ -123,8 +119,7 @@ static void from_ws_addr(const struct sockaddr_in *in, struct net_sockaddr *out)
|
||||
* 限定条件:无
|
||||
* 函数说明:与 MCU 端 net_init 语义对齐,供上层统一调用
|
||||
*/
|
||||
int net_init(const char *ip, const char *mask, const char *gateway, const uint8_t *mac)
|
||||
{
|
||||
int net_init(const char *ip, const char *mask, const char *gateway, const uint8_t *mac) {
|
||||
(void)ip;
|
||||
(void)mask;
|
||||
(void)gateway;
|
||||
@@ -145,8 +140,7 @@ int net_init(const char *ip, const char *mask, const char *gateway, const uint8_
|
||||
* 限定条件:无
|
||||
* 函数说明:模拟器无网络重建,代次恒 0,使上层代次自愈逻辑空转
|
||||
*/
|
||||
uint32_t net_get_generation(void)
|
||||
{
|
||||
uint32_t net_get_generation(void) {
|
||||
return (uint32_t)s_generation;
|
||||
}
|
||||
|
||||
@@ -157,8 +151,7 @@ uint32_t net_get_generation(void)
|
||||
* 限定条件:无
|
||||
* 函数说明:模拟器不会触发,保留接口以对齐 API
|
||||
*/
|
||||
void net_generation_inc(void)
|
||||
{
|
||||
void net_generation_inc(void) {
|
||||
s_generation++;
|
||||
}
|
||||
|
||||
@@ -169,8 +162,7 @@ void net_generation_inc(void)
|
||||
* 限定条件:无
|
||||
* 函数说明:模拟器无 CH395F 中断,空操作
|
||||
*/
|
||||
int net_poll(void)
|
||||
{
|
||||
int net_poll(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,8 +175,7 @@ int net_poll(void)
|
||||
* 限定条件:Winsock 已就绪
|
||||
* 函数说明:分配空闲控制块,创建 Winsock SOCKET 并置非阻塞
|
||||
*/
|
||||
int net_socket(int domain, int type)
|
||||
{
|
||||
int net_socket(int domain, int type) {
|
||||
int idx;
|
||||
int is_udp;
|
||||
SOCKET ws;
|
||||
@@ -238,8 +229,7 @@ int net_socket(int domain, int type)
|
||||
* 限定条件:socket 已创建
|
||||
* 函数说明:设置 SO_REUSEADDR 后 bind,便于断线后重监听复用端口
|
||||
*/
|
||||
int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen)
|
||||
{
|
||||
int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen) {
|
||||
struct sockaddr_in wsaddr;
|
||||
int yes = 1;
|
||||
|
||||
@@ -273,8 +263,7 @@ int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen)
|
||||
* 限定条件:socket 已绑定
|
||||
* 函数说明:backlog 为 1(单客户端),监听 Socket 保持非阻塞
|
||||
*/
|
||||
int net_listen(int sockfd)
|
||||
{
|
||||
int net_listen(int sockfd) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
s_net_errno = NET_ERR_BADF;
|
||||
return -1;
|
||||
@@ -301,8 +290,7 @@ int net_listen(int sockfd)
|
||||
* 函数说明:非阻塞监听下无新连接时返回 -1 并置 NET_ERR_WOULDBLOCK;
|
||||
* 与 MCU 端不同,Winsock 的 accept 返回独立于监听 Socket 的新 fd
|
||||
*/
|
||||
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen)
|
||||
{
|
||||
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
|
||||
struct sockaddr_in wscli;
|
||||
int wslen;
|
||||
SOCKET cws;
|
||||
@@ -356,8 +344,7 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen)
|
||||
* 而 accept 本就是非阻塞的、**没有 MCU 端的 RPC 成本** → 恒返回 1,
|
||||
* 使上层门控在模拟器上等价于"改前行为"(逐位一致,不引入新语义)
|
||||
*/
|
||||
int net_can_accept(int sockfd)
|
||||
{
|
||||
int net_can_accept(int sockfd) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -372,8 +359,7 @@ int net_can_accept(int sockfd)
|
||||
* 函数说明:同 net_can_accept——Winsock recv 非阻塞、无 RPC 成本 → 恒返回 1,
|
||||
* 上层门控在模拟器上不改变既有行为(含"每轮都 recv"的自愈特性)
|
||||
*/
|
||||
int net_can_read(int sockfd)
|
||||
{
|
||||
int net_can_read(int sockfd) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -390,8 +376,7 @@ int net_can_read(int sockfd)
|
||||
* 限定条件:socket 已创建
|
||||
* 函数说明:非阻塞 Socket 上连接未完成时返回 -1 + NET_ERR_WOULDBLOCK
|
||||
*/
|
||||
int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen)
|
||||
{
|
||||
int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen) {
|
||||
struct sockaddr_in wsaddr;
|
||||
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
@@ -430,8 +415,7 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen)
|
||||
* 函数说明:非阻塞单次发送(保持 UI 主循环不阻塞);协议帧小且对端主动
|
||||
* 读取,实践中一次即发完
|
||||
*/
|
||||
int net_send(int sockfd, const void *buf, int len, int flags)
|
||||
{
|
||||
int net_send(int sockfd, const void *buf, int len, int flags) {
|
||||
int r;
|
||||
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
@@ -473,8 +457,7 @@ int net_send(int sockfd, const void *buf, int len, int flags)
|
||||
* 函数说明:与 MCU 端语义一致——>0 有数据,0 对端关闭,<0 且 errno 区分
|
||||
* "暂无数据"与"真错误"
|
||||
*/
|
||||
int net_recv(int sockfd, void *buf, int len, int flags)
|
||||
{
|
||||
int net_recv(int sockfd, void *buf, int len, int flags) {
|
||||
int r;
|
||||
|
||||
(void)flags;
|
||||
@@ -519,8 +502,7 @@ int net_recv(int sockfd, void *buf, int len, int flags)
|
||||
* 限定条件:socket 已创建,buf/dest_addr 非空
|
||||
*/
|
||||
int net_sendto(int sockfd, const void *buf, int len, int flags,
|
||||
const struct net_sockaddr *dest_addr, int addrlen)
|
||||
{
|
||||
const struct net_sockaddr *dest_addr, int addrlen) {
|
||||
struct sockaddr_in wsaddr;
|
||||
int r;
|
||||
|
||||
@@ -563,8 +545,7 @@ int net_sendto(int sockfd, const void *buf, int len, int flags,
|
||||
* 限定条件:socket 已创建,buf 非空
|
||||
*/
|
||||
int net_recvfrom(int sockfd, void *buf, int len, int flags,
|
||||
struct net_sockaddr *src_addr, int *addrlen)
|
||||
{
|
||||
struct net_sockaddr *src_addr, int *addrlen) {
|
||||
struct sockaddr_in wsaddr;
|
||||
int wslen;
|
||||
int r;
|
||||
@@ -606,8 +587,7 @@ int net_recvfrom(int sockfd, void *buf, int len, int flags,
|
||||
* 限定条件:socket 已打开(in_use == 1)
|
||||
* 函数说明:关闭 Winsock 句柄并释放控制块(in_use 清零,net_get_sock 转返回 NULL)
|
||||
*/
|
||||
int net_close(int sockfd)
|
||||
{
|
||||
int net_close(int sockfd) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
|
||||
s_net_errno = NET_ERR_BADF;
|
||||
return -1;
|
||||
@@ -636,8 +616,7 @@ int net_close(int sockfd)
|
||||
* 限定条件:socket 已创建
|
||||
* 函数说明:模拟器以非阻塞 I/O 直接感知事件,回调仅存储不主动触发
|
||||
*/
|
||||
int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg)
|
||||
{
|
||||
int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS || s_socks[sockfd].in_use == 0) {
|
||||
s_net_errno = NET_ERR_BADF;
|
||||
return -1;
|
||||
@@ -656,8 +635,7 @@ int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg)
|
||||
* 返回值:最近一次 net_* 操作设置的错误码(NET_OK / NET_ERR_xxx)
|
||||
* 限定条件:无
|
||||
*/
|
||||
int net_get_errno(void)
|
||||
{
|
||||
int net_get_errno(void) {
|
||||
return s_net_errno;
|
||||
}
|
||||
|
||||
@@ -669,8 +647,7 @@ int net_get_errno(void)
|
||||
* 限定条件:无
|
||||
* 函数说明:逐段解析后按 NET_HTONL 转网络字节序(与 MCU 端实现一致)
|
||||
*/
|
||||
uint32_t net_inet_addr(const char *cp)
|
||||
{
|
||||
uint32_t net_inet_addr(const char *cp) {
|
||||
uint32_t addr = 0;
|
||||
int i;
|
||||
|
||||
@@ -701,8 +678,7 @@ uint32_t net_inet_addr(const char *cp)
|
||||
* 返回值:buf 指针(buf 为 NULL 时返回 NULL)
|
||||
* 限定条件:buf 非空且长度足够
|
||||
*/
|
||||
char *net_inet_ntoa(uint32_t addr, char *buf)
|
||||
{
|
||||
char *net_inet_ntoa(uint32_t addr, char *buf) {
|
||||
uint32_t naddr = NET_NTOHL(addr);
|
||||
|
||||
if (buf == NULL) {
|
||||
@@ -724,8 +700,7 @@ char *net_inet_ntoa(uint32_t addr, char *buf)
|
||||
* 返回值:网络序端口
|
||||
* 限定条件:无
|
||||
*/
|
||||
uint16_t net_htons(uint16_t hostshort)
|
||||
{
|
||||
uint16_t net_htons(uint16_t hostshort) {
|
||||
return NET_HTONS(hostshort);
|
||||
}
|
||||
|
||||
@@ -735,8 +710,7 @@ uint16_t net_htons(uint16_t hostshort)
|
||||
* 返回值:主机序端口
|
||||
* 限定条件:无
|
||||
*/
|
||||
uint16_t net_ntohs(uint16_t netshort)
|
||||
{
|
||||
uint16_t net_ntohs(uint16_t netshort) {
|
||||
return NET_NTOHS(netshort);
|
||||
}
|
||||
|
||||
@@ -746,8 +720,7 @@ uint16_t net_ntohs(uint16_t netshort)
|
||||
* 返回值:网络序 IP
|
||||
* 限定条件:无
|
||||
*/
|
||||
uint32_t net_htonl(uint32_t hostlong)
|
||||
{
|
||||
uint32_t net_htonl(uint32_t hostlong) {
|
||||
return NET_HTONL(hostlong);
|
||||
}
|
||||
|
||||
@@ -757,8 +730,7 @@ uint32_t net_htonl(uint32_t hostlong)
|
||||
* 返回值:主机序 IP
|
||||
* 限定条件:无
|
||||
*/
|
||||
uint32_t net_ntohl(uint32_t netlong)
|
||||
{
|
||||
uint32_t net_ntohl(uint32_t netlong) {
|
||||
return NET_NTOHL(netlong);
|
||||
}
|
||||
|
||||
@@ -769,8 +741,7 @@ uint32_t net_ntohl(uint32_t netlong)
|
||||
* 限定条件:无
|
||||
* 函数说明:上层据此判断"监听 Socket 是否随客户端一同失效"(单连接模型)
|
||||
*/
|
||||
net_sock_t *net_get_sock(int sockfd)
|
||||
{
|
||||
net_sock_t *net_get_sock(int sockfd) {
|
||||
if (sockfd < 0 || sockfd >= NET_MAX_SOCKETS) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -790,8 +761,7 @@ net_sock_t *net_get_sock(int sockfd)
|
||||
* 限定条件:socket 已创建
|
||||
* 函数说明:经 Winsock getsockname 读取实际绑定地址
|
||||
*/
|
||||
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen)
|
||||
{
|
||||
int net_getsockname(int sockfd, struct net_sockaddr *addr, int *addrlen) {
|
||||
struct sockaddr_in wsaddr;
|
||||
int wslen;
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ static lv_indev_t *g_kbd_indev = NULL;
|
||||
* 2. 创建键盘输入设备及默认输入组
|
||||
* 3. 不创建鼠标/触摸设备(模拟器仅用键盘导航)
|
||||
*/
|
||||
int sim_port_init(int32_t hor_res, int32_t ver_res)
|
||||
{
|
||||
int sim_port_init(int32_t hor_res, int32_t ver_res) {
|
||||
/* 创建默认输入组 */
|
||||
lv_group_t *g = lv_group_create();
|
||||
if (g == NULL) {
|
||||
@@ -65,8 +64,7 @@ int sim_port_init(int32_t hor_res, int32_t ver_res)
|
||||
* 返回值:显示设备指针 lv_display_t * 可能为 NULL
|
||||
* 限定条件:sim_port_init() 已成功调用
|
||||
*/
|
||||
void *sim_port_get_display(void)
|
||||
{
|
||||
void *sim_port_get_display(void) {
|
||||
return (void *)lv_display_get_default();
|
||||
}
|
||||
|
||||
@@ -83,8 +81,7 @@ void *sim_port_get_display(void)
|
||||
* 转换,直接读 get_buf_active 不可靠;读回屏幕呈现像素最稳,
|
||||
* 且完全避开快照离屏重渲染(SDL 驱动下会卡派发循环)
|
||||
*/
|
||||
int sim_port_get_screen_mono(uint8_t *buf, uint32_t buf_size)
|
||||
{
|
||||
int sim_port_get_screen_mono(uint8_t *buf, uint32_t buf_size) {
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
* 适用平台:Windows / Linux / macOS (SDL2)
|
||||
* 说明:替代 MCU 端的 ui_port.c,用于 PC 上 UI 开发与调试
|
||||
*/
|
||||
#ifndef __SIM_PORT_H
|
||||
#define __SIM_PORT_H
|
||||
#ifndef SIM_PORT_H
|
||||
#define SIM_PORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -47,4 +47,4 @@ int sim_port_get_screen_mono(uint8_t *buf, uint32_t buf_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SIM_PORT_H */
|
||||
#endif /* SIM_PORT_H */
|
||||
|
||||
@@ -32,16 +32,16 @@ static const uint32_t s_caps[SYSLOG_COUNT] = { SYSLOG_RUN_MAX, SYSLOG_SELFTEST_M
|
||||
*/
|
||||
static void s_now(char *p_ts, uint32_t *p_epoch) {
|
||||
time_t t = time(NULL);
|
||||
struct tm tmv;
|
||||
struct tm tmv = {0}; /* 显式清零:localtime_s/r 是"输出型"参数,静态分析按未初始化报 */
|
||||
|
||||
#if defined(_WIN32)
|
||||
localtime_s(&tmv, &t);
|
||||
#else
|
||||
localtime_r(&t, &tmv);
|
||||
#endif
|
||||
(void)sprintf(p_ts, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tmv.tm_year + 1900, tmv.tm_mon + 1, tmv.tm_mday,
|
||||
tmv.tm_hour, tmv.tm_min, tmv.tm_sec);
|
||||
(void)snprintf(p_ts, SYSLOG_TS_LEN + 1u, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
tmv.tm_year + 1900, tmv.tm_mon + 1, tmv.tm_mday,
|
||||
tmv.tm_hour, tmv.tm_min, tmv.tm_sec);
|
||||
*p_epoch = (uint32_t)t;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,9 @@ static int s_append(syslog_id_t id, const char *desc) {
|
||||
s_now(ts, &epoch);
|
||||
memcpy(rec, ts, SYSLOG_TS_LEN);
|
||||
rec[SYSLOG_TS_LEN] = ' ';
|
||||
(void)sprintf((char *)(rec + SYSLOG_EPOCH_OFFS), "%010u", (unsigned int)epoch);
|
||||
/* +1 = 容纳 NUL;字段本身固定 10 位数字,与旧 sprintf 写入字节数完全一致 */
|
||||
(void)snprintf((char *)(rec + SYSLOG_EPOCH_OFFS), SYSLOG_EPOCH_LEN + 1u,
|
||||
"%010u", (unsigned int)epoch);
|
||||
rec[SYSLOG_DESC_OFFS - 1u] = ' ';
|
||||
dl = strlen(desc);
|
||||
if (dl > SYSLOG_DESC_MAX) {
|
||||
@@ -185,7 +187,12 @@ int syslog_last_epoch(syslog_id_t id, uint32_t *p_epoch) {
|
||||
uint32_t v = 0u;
|
||||
uint32_t i;
|
||||
|
||||
if (p_epoch == NULL || syslog_count(id) == 0u) {
|
||||
/* 先判空再写:旧写法 `if (p_epoch == NULL || ...)` 之后立刻 *p_epoch = 0,
|
||||
* 一旦调用方真传 NULL 就是空指针解引用(cppcheck nullPointerRedundantCheck 实报) */
|
||||
if (p_epoch == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (syslog_count(id) == 0u) {
|
||||
*p_epoch = 0u;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
* 限定条件:无
|
||||
* 函数说明:远端按键码与 LVGL 按键码一一对应
|
||||
*/
|
||||
static uint32_t sim_map_key(uint8_t remo_key)
|
||||
{
|
||||
static uint32_t sim_map_key(uint8_t remo_key) {
|
||||
switch (remo_key) {
|
||||
case UI_KEY_UP: return LV_KEY_UP;
|
||||
case UI_KEY_DOWN: return LV_KEY_DOWN;
|
||||
@@ -43,8 +42,7 @@ static uint32_t sim_map_key(uint8_t remo_key)
|
||||
* 函数说明:窗口模式显示缓冲经 I1→ARGB8888 转换,不能直读,
|
||||
* 故读回屏幕像素再按红通道阈值打包 1bpp(布局与 MCU 端一致)
|
||||
*/
|
||||
int ui_net_sink_get_lcdmem(uint8_t *out, uint32_t out_size)
|
||||
{
|
||||
int ui_net_sink_get_lcdmem(uint8_t *out, uint32_t out_size) {
|
||||
if (out == NULL || out_size < UI_NET_SINK_MONO_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
@@ -58,8 +56,7 @@ int ui_net_sink_get_lcdmem(uint8_t *out, uint32_t out_size)
|
||||
* 限定条件:默认输入组已建立
|
||||
* 函数说明:映射为 LV_KEY_* 后经 lv_group_send_data 发向焦点对象
|
||||
*/
|
||||
void ui_net_sink_inject_key(uint8_t remo_key)
|
||||
{
|
||||
void ui_net_sink_inject_key(uint8_t remo_key) {
|
||||
lv_group_t *g;
|
||||
uint32_t key;
|
||||
|
||||
|
||||
@@ -106,7 +106,9 @@ STRIDE = W // 8 # I1:20 字节/行
|
||||
# 页面结构变更导致漂移时,先确认新值合理再更新此常量(内存回归门禁)。
|
||||
# 2026-09-14: 4864 → 5520(+656B)= run_headless 新增 ui_standby_init():待机模块
|
||||
# 常驻屏 s_scr + 容器 s_cont 两个 lv_obj,随菜单基线同移(见 check_menu_rows.py)。
|
||||
POOL_AFTER_ROUNDTRIP = 5520
|
||||
# 2026-10-11: 5520 → 5448(−72B)= 裁剪 LVGL 控件类(F-2),随菜单基线 5440→5368 同移;
|
||||
# **一次性残留不变,仍是 80 B**(5448 − 5368),说明泄漏特征未变,只是每对象样式表更小。
|
||||
POOL_AFTER_ROUNDTRIP = 5448
|
||||
|
||||
|
||||
def run_sim(seq, out):
|
||||
|
||||
@@ -57,7 +57,11 @@ ROOT_X0, ROOT_Y0, ROOT_W, ROOT_H = 0, 44, 66, 107
|
||||
# 先确认新值合理再更新此常量(内存回归门禁,见 docs/UI设计/UI_自动化测试流程.md)
|
||||
# 2026-09-14: 4784 → 5440(+656B)= run_headless 新增 ui_standby_init():待机模块
|
||||
# 常驻屏 s_scr + 容器 s_cont 两个 lv_obj(先于池测量创建),属有意结构变更。
|
||||
MENU_POOL_BASELINE = 5440
|
||||
# 2026-10-11: 5440 → 5368(−72B)= 裁剪 LVGL 控件类(F-2:label/button/buttonmatrix/
|
||||
# bar/textarea 全关,simulator/lv_conf.h 与 Lib/lv_conf.h 对齐为同一特性子集)。
|
||||
# 像素逐字节未变(11 页黄金参考在**裁剪前**生成、裁剪后全部一致);差值来自
|
||||
# lv_theme_apply 不再为已不存在的控件类登记样式条目 → 每对象样式表更小。更优。
|
||||
MENU_POOL_BASELINE = 5368
|
||||
|
||||
|
||||
def load(path):
|
||||
|
||||
Reference in New Issue
Block a user