refactor(NET): netMsgQueueHandle 收进 net_socket 私有,改为创建后绑定

结构债 S-2 的最后一步——**该族的 24 处手写跨模块裸 extern 就此全部清零**。

队列对象仍由 CubeMX 在 `MX_FREERTOS_Init()` 创建(**创建点不可外移**:
`osKernelInitialize()` 之前的任何创建类 API 会杀死启动,见
`docs/架构设计/项目启动顺序管理.md`);改为创建后立刻在 `Src/freertos.c` 的
`USER CODE BEGIN RTOS_QUEUES` 区调用 `net_msg_queue_adopt(netMsgQueueHandle)`,
把句柄交给唯一使用者。`net_socket.c` 内改用 `static osMessageQueueId_t
s_net_msg_queue`(21 处引用改名),BSP 对该全局变量的裸 `extern` 消失——现在
`netMsgQueueHandle` 只出现在生成文件自己的两处(定义 + 创建)。

两个刻意的设计决定:
① **不新建第二个队列**。自建队列 + 删 `.ioc` 里的 netMsgQueue 也能收口,但要
   CubeMX 重生成(Ask-first),过渡期还会同时存在两个队列,白占 CCM 堆里
   8 × `net_msg_t` 的空间——CCM 正是当下 87.9% 的红线。故选"创建后绑定"。
② `adopt()` **拒绝重复绑定、保留首次句柄**。真出现两处绑定时,静默换句柄会让
   已入队的请求留在旧队列里永不处理;拒掉第二个反而更容易暴露。绑定前的判空
   是真实防线:丢了那一行,后果是"所有 net_* 请求被丢弃、网络全线静默不通",
   不是崩溃。

**防回退**:`check_cubemx_survival.py` 新增存活项 `net-msgq-adopt`(region
`RTOS_QUEUES`、`must_contain=["net_msg_queue_adopt"]`),易失清单 29 → 30 项全部
到位;基线已重建(有意的 USER CODE 区改动,按脚本文档流程 `--write`)。

**体量**:`Code` 213,204 → **213,236 B(+32)**、`ER_IROM1` **231,816 B(22.1%)**;
`RW +4 / ZI −4` → `RW_IRAM1` 恒 **75,264 B(57.4%)**、`RW_CCM` 恒 **57,376 B
(87.9%)**、`RW+ZI` 总量 132,688 B 不变(没有多占一个字节 RAM)。

**验证**:`@build` 0 错 0 警告;`@test` PASS——624 ms 到 `net init: OK`、`i104:
listening on 2404`、无 `[ERR]`/Fault、`heap free=15800 min_ever=8464` 逐项不变。
另在真机跑了一次 FTP 控制通道往返:220 → `USER admin` 331 → `PASS admin` 230
→ `PWD` 257 → `TYPE I` 200 → `QUIT` 221。每条命令都是一次过队列的
net_recv/net_send,证明绑定路径真在跑;`.map` 里 `freertos.o(MX_FREERTOS_Init)
refers to net_socket.o(i.net_msg_queue_adopt)` 证明镜像含该行。

⚠ **顺带揪出一条测试工具漂移(本次未修,等定夺)**:
`test/host/ftp_up_dl_test.py:123/126` 仍写死 `USER anonymous` /
`PASS test@test.com`,而设备自 N-19(2026-10-11)起按 `/config.ini [ftp]` 校验
admin/admin(SHA-256 `pwd_hash`)→ 该脚本必然登录失败。它是手工工具、不在任何
pre-commit 钩子里,所以 11 天没人发现,而 `docs/测试说明/FTP_Test_Guide.md` 把它
列为"推荐入口"。建议加 `--user/--password`(默认 admin/admin),并连
`ftp_speed_test.py` 一起核。

数字联动:两份 `data/` 快照重跑、`ram_baseline --update/--write`、
`check_mem_numbers --write`、FLASH 与任务栈两张配图常量重算并重新生成(逐文本按
字号与锚点复查越界 = 0)、报告 §1.3/§5.1/§5.4 与部署文档 §3.3 同步。报告 §0.4 的
S-2 行按「完成即销项」改写为已闭环,§9 拆出独立 S-2 行标 ✅。

门禁:`@build` 0/0、`@test` PASS、`layer-deps` / `cubemx-survival` / `mem-numbers`
(本次改到台账受管区,scan 已过)/ `mem-budget`(57.4% / 87.9%)/ `task-table` /
`doc-links --all`(146 文档 0 问题)/ `id-check --strict`(增量拦截通过、可判定
82.84%、存量债 640)全绿;14 个文件字节卫生 BOM 无 / CR 0 / U+FFFD 0 / 无尾空格。
未推送。
This commit is contained in:
2026-10-22 20:01:40 +08:00
parent 6ede1443e9
commit e7f28502bc
14 changed files with 211 additions and 123 deletions
+8 -8
View File
@@ -47,11 +47,11 @@ RAM2_CATEGORIES = [
# ── Flash breakdown (1MB = 1,048,576 B; 2026-10-22 @build) ──────────────────
FLASH_TOTAL = 1048576
FLASH_CODE = 213204
FLASH_CODE = 213236
FLASH_RO = 18580
FLASH_RW = 1184
FLASH_RW = 1188
FLASH_USED = FLASH_CODE + FLASH_RO + FLASH_RW # ROM 合计(含 RW 初始化表)
FLASH_IROM = FLASH_CODE + FLASH_RO # ER_IROM1 区用量 = 231,784 B(22.1%)
FLASH_IROM = FLASH_CODE + FLASH_RO # ER_IROM1 区用量 = 231,816 B(22.1%)
FLASH_FREE = FLASH_TOTAL - FLASH_USED
FLASH_CATEGORIES = [
@@ -61,7 +61,7 @@ FLASH_CATEGORIES = [
("Flash 空闲", FLASH_FREE, "#E0E0E0"),
]
# Flash Code+RO 分布(= ER_IROM1 231,784 B;2026-10-22 按 .map 对象表逐对象归类,
# Flash Code+RO 分布(= ER_IROM1 231,816 B;2026-10-22 按 .map 对象表逐对象归类,
# 口径同 data/ram_report_20261022.md;"其他"含链接器填充)
FLASH_CODE_SUB = [
("LVGL 库", 87706, "#4CAF50"),
@@ -73,7 +73,7 @@ FLASH_CODE_SUB = [
("FatFS", 8468, "#9C27B0"),
("C 库 (microlib)", 5486, "#795548"),
("startup", 468, "#B0BEC5"),
("其他 (长尾)", 7432, "#E0E0E0"), # remainder
("其他 (长尾)", 7464, "#E0E0E0"), # remainder
]
# ── Task stack budgets (2026-10-22 @build + 同日真机 [STACK] 实测; data/stack_report_20261022.md) ──
@@ -83,13 +83,13 @@ FLASH_CODE_SUB = [
TASK_STACKS = [
("defaultTask", 5120, "Normal", 3024, 2152, 2096, 40, "PASS", "FatFS 挂载/探针 + 配置引擎 + syslog + LED"),
("netTask", 3840, "Normal", 1912, 1116, 1928, 50, "PASS", "CH395F 轮询、消息处理"),
("ftpTask", 4096, "Normal", 1456, 764, 2640, 64, "PASS", "lftpd FTP 服务(大缓冲已静态化)"),
("ftpTask", 4096, "Normal", 1456, 1404, 2640, 64, "PASS", "lftpd FTP 服务(大缓冲已静态化)"),
("uiTask", 16384, "BelowNormal", 4052, 4052, 12332, 75, "PASS", "LVGL UI 主循环 + 远程显示推流"),
("testTask", 8192, "BelowNormal", 736, 736, 7456, 91, "PASS", "测试套件(产品构建不创建,取静态最坏链)"),
("timeSyncTask", 2560, "Normal", 1264, 616, 1296, 50, "PASS", "TCP 时间同步(8888)"),
("timeSyncTask", 2560, "Normal", 1264, 648, 1296, 50, "PASS", "TCP 时间同步(8888)"),
("adcTask", 2560, "AboveNormal", 1320, 952, 1240, 48, "PASS", "1 kHz 节拍消费者(L1 采集,纯取数)"),
("iec104Task", 2560, "Normal", 1456, 540, 1104, 43, "PASS", "IEC 60870-5-104 上行(2404)"),
("protectTask", 2048, "Normal", 872, 624, 1176, 57, "PASS", "20 ms 保护判据 + 闭锁 + 定值校验和巡检"),
("protectTask", 2048, "Normal", 872, 828, 1176, 57, "PASS", "20 ms 保护判据 + 闭锁 + 定值校验和巡检"),
]
KERNEL_STACKS = [("idle", 512), ("timer", 1024)] # 128/256 words(未实测)