Files
STM32F4-Base/simulator/sim
wandering1 1d1a9d4656 net/ui: UI 推流加就绪门控,刷新脱离 netTask 往返(销项 N-10)
新增 net_can_accept() / net_can_read():纯 RAM 读 Socket 控制块,不入队、
不等 netTask 回执,供实时性敏感任务在发 RPC 前判断"有没有活"。
ui_net_sink_poll() 改为先门控再 RPC;无客户端时 RPC 从 100 msg/s 降到 0。

两条兜底(门控引入的新卡死路径,设计阶段未预见):
- I-2 每 32 轮无条件 recv:readable 仅由 RECV_OK 中断置位,Trap 22 三类
  对账不含"RX 非空但 readable=0",纯门控会把已到达的数据永久藏住;
- I-3 门控返 0 时查监听控制块,消失即 g_listen=-1 重建(改前靠每轮
  accept 撞 BADF 暴露,门控会连这条暴露路径一起消掉)。
net_can_read() 对非 ESTABLISHED / 非法 fd 故意返 1,让上层必得 EOF/BADF
走既有错误分支——返 0 会把死连接永久藏住。
模拟器后端恒返 1(Winsock 无 RPC 成本,行为逐位不变)。

实测:uis 50ms→1µs、uiw 50ms→11.4ms(只剩 LVGL);@build 0 错 0 警、
@test 10/10 PASS(uis≤1µs、uisn≡0、0 task stall、0 [ERR])、
check_remo_sink.py e2e 0/25600 位差异、内容页文本断言 50/50。
uip 最坏 61ms 是 LVGL 帧周期地板、与网络无关,判据已按实测修订。

方案 B(把推流搬出 uiTask + 帧 seqlock)已评估并决定不做:搬任务不会
让刷新变快,收益只剩极端并发下的观感隔离,成本含必改 .ioc 的 CubeMX
重生成。残留暴露与观测手段(uis/uisn)如实记录在 §9.4。
N-19 / C7 不入登记簿(当日结案),结论沉淀进问题记录 §9。
2026-10-10 20:47:59 +08:00
..

simulator/sim/ — 模拟器平台层

PC 端 LVGL 模拟器的平台适配层:把 MCU 侧的硬件/RTOS 接口替换成 PC 实现, 使 UI 源码(Drivers/BSP/UI/)与固件共用同一套代码。

文件一览

文件 替换的 MCU 侧实现 作用
sim_port.c/h ui_port.c 显示/输入移植层:SDL 窗口 → LVGL 显示驱动 + 键鼠/触摸输入
net_socket_sim.c net_socket.c 网络 Socket 的 PC 实现(宿主 BSD socket)
cfg_file_store_sim.c cfg_file_store_mcu.c 配置存储的 PC 后端(宿主堆)
sim_syslog.c sys_log_mcu.c 日志的 PC 实现(写文件而非 NAND)
ui_net_sink_backend_sim.c ui_net_sink_backend_mcu.c 推流后端的 PC 实现
sim_latency_stub.c — 时延打桩(模拟链路延迟,供测试)

设计模式

MCU 与模拟器共用核心逻辑,仅后端不同:

      共享核心(无分配符号)
      ├── cfg_file.c(配置引擎)
      └── ui_*(LVGL UI)
             ↓ 后端抽象接口
   ┌─────────┴─────────┐
MCU 后端(本工程 *_mcu.c)  PC 后端(本目录 *_sim.c)

配置引擎后端:MCU = FreeRTOS 堆、模拟器 = 宿主堆,共享核心零分配符号。

相关文档

  • 模拟器总说明:../README.md
  • UI 架构与移植要点:docs/UI设计/UI_设计架构.md
  • 模拟器部署:docs/UI设计/LVGL模拟器部署与使用说明.md