feat(ui/remo): 7003 总线新增 STATUS 身份查询与 GOTO 直达页(#69)
STATUS(命令 4)一帧回答"现在在哪个画面":kind(MENU/PAGE/STANDBY) + 菜单路径/选中 + 页 id,布局契约与字节序见 ui_net_sink.h。由 uiTask 轮询驱动,同上下文读静态导航状态:零画面副作用、免锁、不发日志。 新增只读接口 ui_menu_get_nav_state / ui_content_page_current_desc。 GOTO(命令 5)按页 id 查生成表直开内容页,以 VIEW 权限进入(与 "已过查看密码"同档,不代输任何密码)。编译期门控 DTU_BENCH || UI_REMO_ALLOW_GOTO:产品构建恒拒(status=4),模拟器 构建默认开启便于无板验证;执行类页(clear/reset)固件侧同样拒绝 (status=2,与主机 EXEC_PAGE_IDS 同一事实源);待机中拒绝(status=5), 由主机按键唤醒后再来。成功应答带回目标叶节点下标便于对账。 ui_sink 主机单测补导航侧链接假件 + 最小 lvgl 桩(仅本测试目录)。 产品构建 Keil 0 Error 0 Warning;ui_sink 单测 17/17。
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
#ifndef TEST_UI_SINK_STUB_LVGL_H
|
||||
#define TEST_UI_SINK_STUB_LVGL_H
|
||||
|
||||
/*
|
||||
* 测试存根 lvgl.h(#69,2026-11-02 新增)
|
||||
*
|
||||
* 为什么存在:ui_net_sink.c 新增 STATUS/GOTO 处理(#69 板端导航身份查询)后,
|
||||
* 间接引用 ui_menu_view.h / ui_content_page.h,两者 include 真实 "lvgl.h"。
|
||||
* 本单测只覆盖成帧 / 心跳 / 状态机纯逻辑(见 run_unit_test.py 文件头),
|
||||
* 运行期不触任何 LVGL,故此处仅提供上述头文件声明处用到的最小类型;
|
||||
* 不模拟任何 LVGL 行为,也不参与 MCU 构建(stub 目录仅本测试使用)。
|
||||
*
|
||||
* 维护约定:ui_content_page.h / ui_menu_view.h 的声明若新增 lv_* 类型依赖,
|
||||
* 在此按需补最小 typedef;禁止在此写真实 LVGL 语义来"凑过"编译。
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _lv_obj_t lv_obj_t;
|
||||
typedef struct _lv_area_t lv_area_t;
|
||||
typedef struct _lv_layer_t lv_layer_t;
|
||||
typedef uint32_t lv_key_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t a;
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
} lv_color_t;
|
||||
|
||||
/* ui_tokens.h 的 UI_COL_* 宏用到;本测试不断言其值,仅需可编译 */
|
||||
static inline lv_color_t lv_color_white(void)
|
||||
{
|
||||
lv_color_t c;
|
||||
c.a = 0xFFu;
|
||||
c.r = 0xFFu;
|
||||
c.g = 0xFFu;
|
||||
c.b = 0xFFu;
|
||||
return c;
|
||||
}
|
||||
|
||||
static inline lv_color_t lv_color_black(void)
|
||||
{
|
||||
lv_color_t c;
|
||||
c.a = 0xFFu;
|
||||
c.r = 0x00u;
|
||||
c.g = 0x00u;
|
||||
c.b = 0x00u;
|
||||
return c;
|
||||
}
|
||||
|
||||
/* ui_content_page.h 注释提及;为防后续声明引用,按真实 LVGL 键码给出 */
|
||||
#define LV_KEY_LEFT 0x14u
|
||||
#define LV_KEY_ESC 0x1Bu
|
||||
|
||||
#endif /* TEST_UI_SINK_STUB_LVGL_H */
|
||||
@@ -93,6 +93,38 @@ void ui_net_sink_inject_key(uint8_t k) {
|
||||
if (s_key_n < 16) { s_keys[s_key_n++] = k; }
|
||||
}
|
||||
|
||||
/* ============ 假件:导航侧(#69 STATUS/GOTO,2026-11-02 新增) ============
|
||||
* 本单测不发 STATUS/GOTO 帧,以下仅为链接占位:STATUS 恒为根菜单
|
||||
* depth=0、无页、非待机。若后续要断言 STATUS/GOTO 语义,把这些假件
|
||||
* 改成可控状态并新增用例,不要动生产分支。 */
|
||||
#include "ui_menu.h"
|
||||
#include "ui_content_page.h"
|
||||
#include "ui_page_registry.h"
|
||||
#include "ui_standby.h"
|
||||
|
||||
static const uint8_t s_nav_zero[4] = { 0u, 0u, 0u, 0u }; /* 根菜单 path/sel */
|
||||
|
||||
void ui_menu_get_nav_state(uint8_t *p_depth, const uint8_t **p_path,
|
||||
const uint8_t **p_sel)
|
||||
{
|
||||
if (p_depth != NULL) { *p_depth = 0u; }
|
||||
if (p_path != NULL) { *p_path = s_nav_zero; }
|
||||
if (p_sel != NULL) { *p_sel = s_nav_zero; }
|
||||
}
|
||||
const content_page_def_t *ui_content_page_current_desc(void) { return NULL; }
|
||||
bool ui_content_page_open(const content_page_def_t *desc, uint8_t perm)
|
||||
{
|
||||
(void)desc; (void)perm; return false;
|
||||
}
|
||||
void ui_content_page_close(void) { }
|
||||
bool ui_standby_is_active(void) { return false; }
|
||||
|
||||
/* 生成表占位:尺寸必须按 ui_page_registry.h 的固定条数(本头文件 extern
|
||||
* 了 g_ui_page_map[UI_PAGE_MAP_COUNT])。静态零初始化 = 全表 {node=0,
|
||||
* desc=NULL}:本单测从不发 GOTO 帧,生产的 desc 扫描不会被触达 */
|
||||
const ui_page_entry_t g_ui_page_map[UI_PAGE_MAP_COUNT] = { { 0u,
|
||||
(const content_page_def_t *)0 } };
|
||||
|
||||
/* ===================== 被测代码 ===================== */
|
||||
#include "ui_net_sink.c"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user