Files
STM32F4-Base/Drivers/BSP/UI/ui_net_sink.h
T
super_agent_bot 493fa6ba0e 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。
2026-11-02 22:19:58 +08:00

113 lines
5.9 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 Network Sink (RemoDispBus 服务端)
* 模块功能:实现 RemoDispBus 协议服务端,接收远端连接与导航按键,回送 1bpp 帧缓冲
* 适用平台:STM32F407ZGTx + CH395F 以太网
* 作者:王建锋
* 创建日期:2026-08-29
* 修改记录:
* 2026-08-29 王建锋 创建初始版本
* 2026-08-29 王建锋 修正监听端口为 7003,与 DTU-RemoteLCD 客户端默认端口对齐
* 2026-10-25 DTU 项目组 F3:新增 ui_net_sink_set_beat_cb()(看门狗心跳
* 回调注入,往返返回点喂位;未注册 = 零行为变化)
* 2026-11-02 DTU 项目组 #69:新增 STATUS(4) 身份查询与 GOTO(5) 直开页命令
* (协议契约 UI_REMO_STATUS_VER / UI_REMO_ST_* /
* UI_REMO_GOTO_*,v1;主机侧解析器 = scripts/board_ui_nav.py)
*/
#ifndef UI_NET_SINK_H
#define UI_NET_SINK_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* RemoDispBus 标签与命令 */
#define UI_REMO_TAG_CLIENT 0xAA
#define UI_REMO_TAG_DEVICE 0xBB
#define UI_REMO_CMD_KEEP 0
#define UI_REMO_CMD_INIT 1
#define UI_REMO_CMD_KEY 2
#define UI_REMO_CMD_LCDMEM 3
#define UI_REMO_CMD_STATUS 4 /* 身份查询:应答"现在在哪个画面"(v1,2026-11-02) */
#define UI_REMO_CMD_GOTO 5 /* 直开页:按页 id 一步开内容页(台架/模拟器构建,2026-11-02) */
/* STATUS/GOTO 协议契约 v1(#69,2026-11-02;主机侧解析器 = scripts/board_ui_nav.py,
* 两端共用本组常量,禁止各自复制字面量)
* STATUS 应答布局:[ver][kind][depth][n][id_len][path n B][sel n B][页 id ASCII id_len B]
* kind 取值:MENU(菜单屏,path/sel 有效)/ PAGE(内容页开,页 id 尾附)/ STANDBY(待机屏)
* GOTO payload:页 id ASCII(≤ UI_REMO_MAX_ID 字节);应答 [ver][status][node]
* status 取值:OK(node=目标叶节点)/ NO_ID / EXEC(clear、reset 拒)/ FAIL /
* NOSUPP(产品构建,编译期剔除)/ STANDBY(先唤醒再查) */
#define UI_REMO_STATUS_VER 1u
#define UI_REMO_MAX_ID 15u /* 页 id 字符串上限(现最长 wave_manual 10 字符,留余量) */
#define UI_REMO_ST_MENU 0u
#define UI_REMO_ST_PAGE 1u
#define UI_REMO_ST_STANDBY 2u
#define UI_REMO_GOTO_OK 0u
#define UI_REMO_GOTO_NO_ID 1u
#define UI_REMO_GOTO_EXEC 2u
#define UI_REMO_GOTO_FAIL 3u
#define UI_REMO_GOTO_NOSUPP 4u
#define UI_REMO_GOTO_STANDBY 5u
/* UI 推流监听端口(须与 DTU-RemoteLCD 客户端默认端口 7003 一致) */
#define UI_NET_SINK_PORT 7003
/*
* 函数功能:启动 UI 专用 TCP 监听 Socket
* 入口参数:port - 监听端口号 uint16_t 1 - 65535
* 返回值:0 - 成功,其他 - 失败(socket 创建/绑定/监听失败)
* 限定条件:net_init() 已完成,网络子系统就绪
* 函数说明:1. 创建流式 Socket 并绑定到指定端口与任意本地地址
* 2. 进入监听状态,等待远端客户端连接
* 3. 调用前需确保 CH395F 网络已初始化
*/
int ui_net_sink_start(uint16_t port);
/*
* 函数功能:轮询 RemoDispBus 协议(接受连接、收帧、逐字节解析)
* 入口参数:无
* 返回值:无
* 限定条件:ui_net_sink_start() 已成功调用
* 函数说明:1. 无客户端时先门控(net_listener_armed,纯 RAM 读)再尝试接受连接
* 2. 有客户端时先门控(net_can_read)再用 net_recv_nb 非阻塞收帧并解析
* (KEEPLIVE/INIT/KEY/LCDMEM/STATUS/GOTO);门控判为无数据时仍每 32 轮兜底收一次
* (DONTWAIT 已转正为具名 API;uiTask 受 IWDG 监控,
* 非阻塞是契约义务——见 net_socket.h net_recv 文档契约)
* 3. 对端关闭或异常时复位客户端,等待下次重监听
* ⚠ **不是"零成本非阻塞"**:门控只消除无谓往返;真有活时仍是
* "入队 + 等 netTask 回执"(osMessageQueuePut(osWaitForever) +
* xTaskNotifyWait(portMAX_DELAY),均无上界;LCDMEM 应答 3204 B 最坏 ≈4 s)
* → 会拖住宿主(uiTask)的刷新;"搬出 uiTask"已完整评估并**决定不做**
* (实测刷新最坏周期 = LVGL 帧周期地板,与网络无关),见
* docs/UI设计/RemoDispBus协议与接收设计说明.md §3
*/
void ui_net_sink_poll(void);
/*
* 函数功能:注册看门狗心跳回调钩子(F3,2026-10-25 大窗判读)
* 入口参数:cb - 回调钩子(宿主轮询上下文调用);NULL = 注销
* 返回值:无
* 限定条件:宿主任务在首次 ui_net_sink_poll() 之前调用一次;注册者 = 推流
* 属主(MCU = uiTask,须保证钩子内只做置位类动作、不阻塞)
* 函数说明:本模块在每次**可等待 net 往返**(accept / recv_nb / send / close /
* 重建三件套)返回处调用钩子。动因:netTask 重建风暴期,单轮内多个
* 往返串行排队,把宿主(uiTask,IWDG 必需位)的心跳间隔拖过 800ms
* (2026-10-25 台架实测 bit4 单任务 8 连击窗、uisn=154ms 仍在段内);
* 往返时长本身不改(上界收口为登记簿批 3 事项),但心跳在每个
* 往返边界续命——单任务停摆判据(按位连击,docs/子系统设计/看门狗设计说明.md
* §5.3)只应
* 抓真挂死,不该抓「多个都回来了但各自偏慢的往返之和」。
* 未注册(模拟器/黄金回归形态)= 行为与本特性引入前逐字一致。
* 为何回调注入而非直调 task_wd_beat():Drivers/BSP 不得 include
* App 侧头(layer-deps 门禁,方向性铁律)
*/
void ui_net_sink_set_beat_cb(void (*cb)(void));
#ifdef __cplusplus
}
#endif
#endif /* UI_NET_SINK_H */