refactor(time_sync)!: 退役 TCP :8888 对时任务,timeSyncTask 转纯 SNTP 校时节拍宿主(#78)
CI / 静态门禁 (pre-commit) (push) Failing after 43s
CI / 主机侧单测 (MSVC) (push) Failing after 45s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 45s
CI / 主机侧单测 (MSVC) (pull_request) Failing after 45s

SNTP 客户端已随 #73/PR #77 上线合入(merge 2b848c4a),用户裁定
8888 对时任务退出历史舞台(gitea:77 线程原话,跟踪 Issue #78)。

生产侧(App/sync/time_sync.c v2.0,任务入口名不变,freertos.c 零改动):
- 删除 :8888 监听、TIME 包重组、sys_clock 写入、OPER 落痕、
  net_drop_conn 队头自救整条链(TIME_SYNC_PORT 宏随退役删除)
- 任务体收敛为:就绪屏障(100ms 分片、osFlagsNoClear)→
  200ms 校时节拍 task_wd_beat → time_sntp_run(net_get_generation())
  → 分片延时;喂狗节奏(TASK_WD_TIMESYNC=5,required_mask)不变
- 时钟写入口自此 = SNTP / UI 手工 / 104 C_CS,双写竞态(后写者赢)
  随之消失(墙钟说明 §15 退役公告、§16 现势口径)

工具与测试:
- 删除 test/host/time_sync_server.py(对时源)与 e02_probe.py
  (队头阻塞探针,载体随监听退役;判据脚本 v5_log_gap_report.py
  保留供旧日志解读)
- time_sync 主机单测重写 v2.0:33 断言覆盖分片延时 / 屏障 /
  SNTP 节拍与网络代次当轮交接 / 未出网守门;stub 的
  net_socket.h 裁剪至 net_get_generation 作编译期绊线
- 覆盖率基线 --update-baseline 收口(time_sync.c 101→20 行为刻意
  缩减,全仓 48/48 套绿)

文档与图:墙钟说明 §15 改退役公告(教训保留:CH395F FIN 丢未读
缓冲)、§16 单一网络来源;产品需求 FR-TIME-2 退役注记、§6.3 重写;
架构总览 / 软件架构规格 / 网络配置 / 网络自愈 §9.3 / BSD 指南 /
看门狗说明心跳与白名单行 / 实机测试指南 / 部署环境 / 继保规划 /
UI补齐时基口径 / 页面补齐规划 SNTP 页行 / 任务规划 README 叶数与
暂缓项行(SNTP 叶已绑、UI_PAGE_MAP_COUNT=31 口径)等约 30 处现势
口径同步;arch / net_stack 两图生成器与 SVG 同笔重跑。

台账:ram_baseline --update + check_mem_numbers --write + 体积凭证
(Code 254,648→253,428,−1,220 B)。静态链复测发现 timeSyncTask
1,904 B / iec104Task 1,600 B 低于 ISR 硬线:master 2b848c4a 同判据
timeSyncTask 即 2,056 B(本 PR 只减不增,−152 B 旧任务自身帧),
双 FAIL 为 #74/#77 后既有债;抬栈属 Ask-first 未擅自执行,登记簿
新增「静态链硬线双 FAIL」待台架复采,复测快照入 docs/内存管理/data。

验证:keil-build 0 错 0 警;time_sync/sntp 主机单测绿;
ci_local 全绿;doc-links --all 0。
This commit is contained in:
2026-11-04 18:07:03 +08:00
parent 2b848c4a0b
commit 3a2f9b21fb
50 changed files with 621 additions and 1567 deletions
+2 -2
View File
@@ -9,8 +9,8 @@
<text x="251" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_send() / net_recv() / net_close()(线程安全封装)</text>
<rect x="468" y="116" width="431" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="684" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_select() / net_poll_events() / net_set_event_cb()</text>
<rect x="44" y="164" width="601" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="344" y="187" font-size="13" fill="#1e293b" text-anchor="middle">消费方:lftpd(FTP :21)· time_sync(对时 :8888)· ui_net_sink(远程显示 :7003)</text>
<rect x="44" y="164" width="620" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="354" y="187" font-size="13" fill="#1e293b" text-anchor="middle">消费方:lftpd(FTP :21)· time_sntp(SNTP 出向对时)· ui_net_sink(远程显示 :7003)</text>
<rect x="26" y="262" width="1148" height="140" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<text x="44" y="288" font-size="17" font-weight="700" fill="#7c3aed">消息队列</text>
<text x="124" y="288" font-size="12" fill="#64748b">osMessageQueue · CubeMX 生成,在 MX_FREERTOS_Init() 中创建</text>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

+75 -75
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1560" height="1192" viewBox="0 0 1560 1192" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1560" height="1192" fill="#ffffff"/>
<svg xmlns="http://www.w3.org/2000/svg" width="1560" height="1240" viewBox="0 0 1560 1240" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1560" height="1240" fill="#ffffff"/>
<text x="26" y="40" font-size="20" font-weight="700" fill="#0f172a">STM32F4-Base 项目分层架构</text>
<text x="26" y="62" font-size="13" fill="#64748b">STM32F407ZGTx @168MHz · FreeRTOS V10.3.1 (CMSIS-RTOS2) · 上层只依赖相邻下层</text>
<rect x="26" y="78" width="1508" height="92" rx="12" fill="#eff6ff" stroke="#2563eb" stroke-opacity="0.45"/>
@@ -7,7 +7,7 @@
<text x="134" y="104" font-size="12" fill="#64748b">顶层共享配置 · 被 UI 与基础服务共用</text>
<rect x="44" y="116" width="489" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="288" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_cfg(网口配置:IP/掩码/网关/MAC · /config.ini [network] 段)</text>
<rect x="26" y="214" width="741" height="284" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<rect x="26" y="214" width="741" height="332" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<text x="44" y="240" font-size="17" font-weight="700" fill="#7c3aed">② UI 层</text>
<text x="129" y="240" font-size="12" fill="#64748b">Drivers/BSP/UI · 一份显存三出(模拟器/屏板/远程)</text>
<rect x="44" y="252" width="162" height="38" rx="8" fill="#ffffff" stroke="#7c3aed" stroke-opacity="0.55"/>
@@ -32,7 +32,7 @@
<text x="330" y="419" font-size="13" fill="#1e293b" text-anchor="middle">ui_font_cn_12(中文字体)</text>
<rect x="444" y="396" width="172" height="38" rx="8" fill="#ffffff" stroke="#7c3aed" stroke-opacity="0.55"/>
<text x="530" y="419" font-size="13" fill="#1e293b" text-anchor="middle">ui_deco(浅 V 装饰)</text>
<rect x="793" y="214" width="741" height="284" rx="12" fill="#f0fdfa" stroke="#0d9488" stroke-opacity="0.45"/>
<rect x="793" y="214" width="741" height="332" rx="12" fill="#f0fdfa" stroke="#0d9488" stroke-opacity="0.45"/>
<text x="811" y="240" font-size="17" font-weight="700" fill="#0d9488">③ 基础服务层</text>
<text x="935" y="240" font-size="12" fill="#64748b">应用侧服务 / 编排</text>
<rect x="811" y="252" width="170" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
@@ -55,77 +55,77 @@
<text x="960" y="467" font-size="13" fill="#1e293b" text-anchor="middle">cfg_file · prot_set_store(配置引擎)</text>
<rect x="1119" y="444" width="148" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="1193" y="467" font-size="13" fill="#1e293b" text-anchor="middle">lftpd(FTP :21)</text>
<rect x="1277" y="444" width="227" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="1391" y="467" font-size="13" fill="#1e293b" text-anchor="middle">time_sync(TCP 对时 :8888)</text>
<rect x="26" y="542" width="1508" height="140" rx="12" fill="#f0fdf4" stroke="#16a34a" stroke-opacity="0.45"/>
<text x="44" y="568" font-size="17" font-weight="700" fill="#16a34a">④ 中间件层</text>
<text x="151" y="568" font-size="12" fill="#64748b">通用库 / 协议栈</text>
<rect x="44" y="580" width="675" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="381" y="603" font-size="13" fill="#1e293b" text-anchor="middle">net_socket / net_select / net_events / net_listener / net_pending(BSD API + 阻塞模型)</text>
<rect x="729" y="580" width="147" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="803" y="603" font-size="13" fill="#1e293b" text-anchor="middle">FatFs(文件系统)</text>
<rect x="887" y="580" width="186" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="980" y="603" font-size="13" fill="#1e293b" text-anchor="middle">nand_ftl(dhara FTL)</text>
<rect x="1083" y="580" width="164" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1165" y="603" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.3(图形库)</text>
<rect x="1258" y="580" width="177" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1347" y="603" font-size="13" fill="#1e293b" text-anchor="middle">sys_clock(墙钟基准)</text>
<rect x="44" y="628" width="219" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="153" y="651" font-size="13" fill="#1e293b" text-anchor="middle">task_watchdog(IWDG 判定)</text>
<rect x="26" y="726" width="1508" height="92" rx="12" fill="#fffbeb" stroke="#d97706" stroke-opacity="0.45"/>
<text x="44" y="752" font-size="17" font-weight="700" fill="#d97706">⑤ 驱动层</text>
<text x="134" y="752" font-size="12" fill="#64748b">Drivers/BSP · 芯片时序/中断</text>
<rect x="44" y="764" width="178" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="133" y="787" font-size="13" fill="#1e293b" text-anchor="middle">ch395f(SPI2 + DMA)</text>
<rect x="232" y="764" width="163" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="314" y="787" font-size="13" fill="#1e293b" text-anchor="middle">gd5f2gq5ue(SPI1)</text>
<rect x="406" y="764" width="195" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="503" y="787" font-size="13" fill="#1e293b" text-anchor="middle">tpafe5160(并行 16 位)</text>
<rect x="611" y="764" width="133" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="677" y="787" font-size="13" fill="#1e293b" text-anchor="middle">sd2506(I2C1)</text>
<rect x="754" y="764" width="171" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="840" y="787" font-size="13" fill="#1e293b" text-anchor="middle">rs485(UART4 + DE)</text>
<rect x="935" y="764" width="388" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="1130" y="787" font-size="13" fill="#1e293b" text-anchor="middle">sb_link · sb_proto(屏板链路 · USART1 700 kbaud)</text>
<rect x="26" y="862" width="1508" height="92" rx="12" fill="#f1f5f9" stroke="#475569" stroke-opacity="0.45"/>
<text x="44" y="888" font-size="17" font-weight="700" fill="#475569">⑥ 内核 / HAL</text>
<text x="176" y="888" font-size="12" fill="#64748b">调度 · 外设抽象</text>
<rect x="44" y="900" width="329" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="208" y="923" font-size="13" fill="#1e293b" text-anchor="middle">FreeRTOS V10.3.1(CMSIS-RTOS2 · heap_4)</text>
<rect x="383" y="900" width="189" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="478" y="923" font-size="13" fill="#1e293b" text-anchor="middle">STM32 HAL(时基 TIM7)</text>
<rect x="582" y="900" width="144" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="655" y="923" font-size="13" fill="#1e293b" text-anchor="middle">CMSIS / 启动文件</text>
<rect x="26" y="998" width="1508" height="140" rx="12" fill="#fff1f2" stroke="#e11d48" stroke-opacity="0.45"/>
<text x="44" y="1024" font-size="17" font-weight="700" fill="#e11d48">⑦ 硬件</text>
<text x="117" y="1024" font-size="12" fill="#64748b">STM32F407ZGTx @168MHz</text>
<rect x="44" y="1036" width="179" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="133" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">CH395F 以太网(SPI2)</text>
<rect x="233" y="1036" width="201" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="334" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">GD5F2GQ5UE NAND(SPI1)</text>
<rect x="445" y="1036" width="182" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="536" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">TPAFE5160 ADC(并行)</text>
<rect x="637" y="1036" width="163" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="718" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">SD2506 RTC(I2C1)</text>
<rect x="810" y="1036" width="202" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="912" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">RS-485(UART4 · 未接线)</text>
<rect x="1023" y="1036" width="219" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1133" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">屏板(USART1 · 700 kbaud)</text>
<rect x="1253" y="1036" width="249" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1377" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">RS232#1 日志(UART5 · 115200)</text>
<rect x="44" y="1084" width="77" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="82" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">6x LED</text>
<rect x="811" y="492" width="355" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="988" y="515" font-size="13" fill="#1e293b" text-anchor="middle">time_sntp(SNTP 对时,UDP 出向;:8888 已退役)</text>
<rect x="26" y="590" width="1508" height="140" rx="12" fill="#f0fdf4" stroke="#16a34a" stroke-opacity="0.45"/>
<text x="44" y="616" font-size="17" font-weight="700" fill="#16a34a">④ 中间件层</text>
<text x="151" y="616" font-size="12" fill="#64748b">通用库 / 协议栈</text>
<rect x="44" y="628" width="675" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="381" y="651" font-size="13" fill="#1e293b" text-anchor="middle">net_socket / net_select / net_events / net_listener / net_pending(BSD API + 阻塞模型)</text>
<rect x="729" y="628" width="147" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="803" y="651" font-size="13" fill="#1e293b" text-anchor="middle">FatFs(文件系统)</text>
<rect x="887" y="628" width="186" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="980" y="651" font-size="13" fill="#1e293b" text-anchor="middle">nand_ftl(dhara FTL)</text>
<rect x="1083" y="628" width="164" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1165" y="651" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.3(图形库)</text>
<rect x="1258" y="628" width="177" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1347" y="651" font-size="13" fill="#1e293b" text-anchor="middle">sys_clock(墙钟基准)</text>
<rect x="44" y="676" width="219" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="153" y="699" font-size="13" fill="#1e293b" text-anchor="middle">task_watchdog(IWDG 判定)</text>
<rect x="26" y="774" width="1508" height="92" rx="12" fill="#fffbeb" stroke="#d97706" stroke-opacity="0.45"/>
<text x="44" y="800" font-size="17" font-weight="700" fill="#d97706">⑤ 驱动层</text>
<text x="134" y="800" font-size="12" fill="#64748b">Drivers/BSP · 芯片时序/中断</text>
<rect x="44" y="812" width="178" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="133" y="835" font-size="13" fill="#1e293b" text-anchor="middle">ch395f(SPI2 + DMA)</text>
<rect x="232" y="812" width="163" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="314" y="835" font-size="13" fill="#1e293b" text-anchor="middle">gd5f2gq5ue(SPI1)</text>
<rect x="406" y="812" width="195" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="503" y="835" font-size="13" fill="#1e293b" text-anchor="middle">tpafe5160(并行 16 位)</text>
<rect x="611" y="812" width="133" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="677" y="835" font-size="13" fill="#1e293b" text-anchor="middle">sd2506(I2C1)</text>
<rect x="754" y="812" width="171" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="840" y="835" font-size="13" fill="#1e293b" text-anchor="middle">rs485(UART4 + DE)</text>
<rect x="935" y="812" width="388" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="1130" y="835" font-size="13" fill="#1e293b" text-anchor="middle">sb_link · sb_proto(屏板链路 · USART1 700 kbaud)</text>
<rect x="26" y="910" width="1508" height="92" rx="12" fill="#f1f5f9" stroke="#475569" stroke-opacity="0.45"/>
<text x="44" y="936" font-size="17" font-weight="700" fill="#475569">⑥ 内核 / HAL</text>
<text x="176" y="936" font-size="12" fill="#64748b">调度 · 外设抽象</text>
<rect x="44" y="948" width="329" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="208" y="971" font-size="13" fill="#1e293b" text-anchor="middle">FreeRTOS V10.3.1(CMSIS-RTOS2 · heap_4)</text>
<rect x="383" y="948" width="189" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="478" y="971" font-size="13" fill="#1e293b" text-anchor="middle">STM32 HAL(时基 TIM7)</text>
<rect x="582" y="948" width="144" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="655" y="971" font-size="13" fill="#1e293b" text-anchor="middle">CMSIS / 启动文件</text>
<rect x="26" y="1046" width="1508" height="140" rx="12" fill="#fff1f2" stroke="#e11d48" stroke-opacity="0.45"/>
<text x="44" y="1072" font-size="17" font-weight="700" fill="#e11d48">⑦ 硬件</text>
<text x="117" y="1072" font-size="12" fill="#64748b">STM32F407ZGTx @168MHz</text>
<rect x="44" y="1084" width="179" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="133" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">CH395F 以太网(SPI2)</text>
<rect x="233" y="1084" width="201" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="334" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">GD5F2GQ5UE NAND(SPI1)</text>
<rect x="445" y="1084" width="182" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="536" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">TPAFE5160 ADC(并行)</text>
<rect x="637" y="1084" width="163" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="718" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">SD2506 RTC(I2C1)</text>
<rect x="810" y="1084" width="202" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="912" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">RS-485(UART4 · 未接线)</text>
<rect x="1023" y="1084" width="219" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1133" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">屏板(USART1 · 700 kbaud)</text>
<rect x="1253" y="1084" width="249" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1377" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">RS232#1 日志(UART5 · 115200)</text>
<rect x="44" y="1132" width="77" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="82" y="1155" font-size="13" fill="#1e293b" text-anchor="middle">6x LED</text>
<line x1="780.0" y1="176.0" x2="780.0" y2="199.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 206.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="396.5" y1="504.0" x2="396.5" y2="527.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 396.5 534.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="1163.5" y1="504.0" x2="1163.5" y2="527.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 1163.5 534.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="688.0" x2="780.0" y2="711.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 718.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="824.0" x2="780.0" y2="847.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 854.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="960.0" x2="780.0" y2="983.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 990.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<text x="26" y="1174" font-size="12" fill="#94a3b8">上层只依赖相邻下层(单向);UI 层与基础服务层同级并列,均使用顶层 net_cfg。跨层调用细节见 docs/架构设计/项目架构总览.md §1.2</text>
<line x1="396.5" y1="552.0" x2="396.5" y2="575.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 396.5 582.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="1163.5" y1="552.0" x2="1163.5" y2="575.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 1163.5 582.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="736.0" x2="780.0" y2="759.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 766.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="872.0" x2="780.0" y2="895.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 902.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="1008.0" x2="780.0" y2="1031.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 1038.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<text x="26" y="1222" font-size="12" fill="#94a3b8">上层只依赖相邻下层(单向);UI 层与基础服务层同级并列,均使用顶层 net_cfg。跨层调用细节见 docs/架构设计/项目架构总览.md §1.2</text>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB