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:
@@ -69,12 +69,34 @@ static uint16_t s_dynamic_port = 49152; /* 动态端口分配起始
|
||||
static volatile uint32_t s_net_generation = 0; /* 网络代次号:网络重建完成时递增(服务据此重建监听) */
|
||||
|
||||
/*
|
||||
* 消息队列(线程安全核心)
|
||||
* 消息队列(线程安全核心,句柄由本模块私有持有)
|
||||
* 外部任务经 net_send/net_recv/net_close 等公开 API 投递请求
|
||||
* netTask 调 net_process_messages() 串行处理所有 CH395F 操作
|
||||
* 由 CubeMX 在 MX_FREERTOS_Init()(osKernelInitialize 之后)中创建
|
||||
* 队列对象由 CubeMX 在 MX_FREERTOS_Init()(osKernelInitialize 之后)创建,创建后
|
||||
* 立刻经 net_msg_queue_adopt() 绑定到这里;绑定之前恒为 NULL,各处投递前的判空
|
||||
* 因此是真实防线而不是形式(绑定失败的后果是"请求被丢弃",不是崩溃)。
|
||||
*/
|
||||
extern osMessageQueueId_t netMsgQueueHandle; /* CubeMX 生成的消息队列句柄 */
|
||||
static osMessageQueueId_t s_net_msg_queue;
|
||||
|
||||
/*
|
||||
* 函数功能:绑定消息队列句柄(本模块是该句柄的唯一使用者)
|
||||
* 入口参数:queue_id - 已创建的消息队列句柄
|
||||
* 返回值:0 = 绑定成功;-1 = 句柄为空或重复绑定(保留首次绑定,不覆盖)
|
||||
* 限定条件:osKernelInitialize() 之后、netTask 启动之前,由 MX_FREERTOS_Init() 调用一次
|
||||
* 函数说明:见 net_socket.h 同名声明处的完整说明。重复绑定**不覆盖**是刻意的——
|
||||
* 真出现两处绑定时,说明有人新加了调用点,此时保留先绑的那个并把后来者
|
||||
* 拒掉,比静默换句柄(已入队的请求会留在旧队列里永不处理)更容易暴露。
|
||||
*/
|
||||
int net_msg_queue_adopt(osMessageQueueId_t queue_id) {
|
||||
if (queue_id == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (s_net_msg_queue != NULL) {
|
||||
return -1;
|
||||
}
|
||||
s_net_msg_queue = queue_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ================= 错误码存储(E-03 修复:按任务隔离,消除跨任务覆写竞态) =================
|
||||
*
|
||||
@@ -582,7 +604,7 @@ void net_process_messages(void) {
|
||||
net_msg_t msg;
|
||||
|
||||
/* 队列句柄未就绪(net_init 未完成):直接返回 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -599,7 +621,7 @@ void net_process_messages(void) {
|
||||
net_reconcile_tick();
|
||||
|
||||
/* 队列排空:超时 0 非阻塞取,每条处理一轮,直到本轮队列为空 */
|
||||
while (osMessageQueueGet(netMsgQueueHandle, &msg, NULL, 0) == osOK) {
|
||||
while (osMessageQueueGet(s_net_msg_queue, &msg, NULL, 0) == osOK) {
|
||||
/* 默认处理完即发即时回执;RECV 挂起登记时置 0(回执推迟到
|
||||
* net_pending_tick 完成检查,避免"登记成功"被误报为处理结果) */
|
||||
int do_notify = 1;
|
||||
@@ -1120,7 +1142,7 @@ int net_listen(int sockfd) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -1136,7 +1158,7 @@ int net_listen(int sockfd) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -1284,7 +1306,7 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -1304,7 +1326,7 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -1445,7 +1467,7 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -1474,7 +1496,7 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -2011,9 +2033,9 @@ static int net_drop_conn_locked(net_sock_t *p_sock) {
|
||||
* 限定条件:1. 必须在【非 netTask】上下文中调用(应用/测试任务);若在 netTask 内调用会自己等自己 → 死锁
|
||||
* (netTask 阻塞在 xTaskNotifyWait 而无人处理消息);netTask 内请直接用 net_send_locked()
|
||||
* 2. Socket 须处于 ESTABLISHED 状态
|
||||
* 3. net_init() + MX_FREERTOS_Init() 已执行,netMsgQueueHandle 已由 net_init 创建
|
||||
* 3. net_init() + MX_FREERTOS_Init() 已执行,消息队列已创建并绑定到本模块
|
||||
* 函数说明:1. 所有 CH395F SPI 访问只允许在 netTask 内串行执行(见 TRAP-NET-14)
|
||||
* 2. 本函数不直接触碰 SPI,而是把发送请求打包成 net_msg_t 投递到 netMsgQueueHandle
|
||||
* 2. 本函数不直接触碰 SPI,而是把发送请求打包成 net_msg_t 投递到本模块的消息队列
|
||||
* 3. netTask 的 net_process_messages() 取出并在 netTask 上下文调用 net_send_locked() 真正写 CH395F
|
||||
* 4. 调用方经 FreeRTOS TaskNotify 阻塞等待处理结果,对外呈现"同步发送"语义
|
||||
* 5. 函数返回 = 本次发送已被 netTask 处理完毕(成功或失败)
|
||||
@@ -2031,7 +2053,7 @@ int net_send(int sockfd, const void *buf, int len, int flags) {
|
||||
}
|
||||
|
||||
/* ---- 2. 运行环境检查:消息队列须已创建(网络层已初始化) ---- */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
/* 网络层未初始化 */
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
@@ -2055,7 +2077,7 @@ int net_send(int sockfd, const void *buf, int len, int flags) {
|
||||
msg.result = -1;
|
||||
|
||||
/* ---- 4. 入队:将消息投递给 netTask,osWaitForever 表示队列满时阻塞调用方 ---- */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败(队列异常等极端情况) */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -2107,7 +2129,7 @@ int net_recv(int sockfd, void *buf, int len, int flags) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -2129,7 +2151,7 @@ int net_recv(int sockfd, void *buf, int len, int flags) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -2193,7 +2215,7 @@ int net_recv_to(int sockfd, void *buf, int len, uint32_t timeout_ms) {
|
||||
}
|
||||
|
||||
/* ---- 2. 运行环境检查:消息队列须已创建(网络层已初始化) ---- */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
/* 网络层未初始化 */
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
@@ -2225,7 +2247,7 @@ int net_recv_to(int sockfd, void *buf, int len, uint32_t timeout_ms) {
|
||||
msg.result = -1;
|
||||
|
||||
/* ---- 5. 入队:将消息投递给 netTask,osWaitForever 表示队列满时阻塞调用方 ---- */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败(队列异常等极端情况) */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -2278,7 +2300,7 @@ int net_close(int sockfd) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -2294,7 +2316,7 @@ int net_close(int sockfd) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
@@ -2336,7 +2358,7 @@ int net_drop_conn(int sockfd) {
|
||||
}
|
||||
|
||||
/* 消息队列未创建(网络层未初始化)→ 通用错误 */
|
||||
if (netMsgQueueHandle == NULL) {
|
||||
if (s_net_msg_queue == NULL) {
|
||||
return NET_ERR_RETURN_1(NET_ERR);
|
||||
}
|
||||
|
||||
@@ -2352,7 +2374,7 @@ int net_drop_conn(int sockfd) {
|
||||
msg.result = -1;
|
||||
|
||||
/* 入队:队列满时阻塞调用方直至有空位 */
|
||||
if (osMessageQueuePut(netMsgQueueHandle, &msg, 0, osWaitForever) != osOK) {
|
||||
if (osMessageQueuePut(s_net_msg_queue, &msg, 0, osWaitForever) != osOK) {
|
||||
/* 入队失败 → BUSY */
|
||||
return NET_ERR_RETURN_1(NET_ERR_BUSY);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ extern "C" {
|
||||
#ifndef NET_NO_OS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "cmsis_os2.h" /* osMessageQueueId_t:net_msg_queue_adopt() 的参数类型 */
|
||||
#endif /* NET_NO_OS */
|
||||
|
||||
#ifndef NET_NO_OS
|
||||
@@ -60,6 +61,23 @@ typedef struct {
|
||||
} net_msg_t;
|
||||
#endif /* NET_NO_OS */
|
||||
|
||||
#ifndef NET_NO_OS
|
||||
/*
|
||||
* 函数功能:把消息队列句柄交给本模块持有(**句柄的唯一使用者是 net_socket.c**)
|
||||
* 入口参数:queue_id - 已创建的消息队列句柄
|
||||
* 返回值:0 = 绑定成功;-1 = 句柄为空、或已绑定过(重复绑定保留首次句柄,不覆盖)
|
||||
* 限定条件:必须在 osKernelInitialize() 之后、netTask 启动之前调用一次
|
||||
* 函数说明:队列对象本身仍由 CubeMX 在 MX_FREERTOS_Init() 里创建——创建点不能外移,
|
||||
* 因为 osKernelInitialize() 之前任何创建类 API 都会杀死启动
|
||||
* (docs/架构设计/项目启动顺序管理.md)。外移创建点还会让重新生成把它抹掉。
|
||||
* 所以这里用"创建后立刻绑定":调用点见 Src/freertos.c 的
|
||||
* USER CODE BEGIN RTOS_QUEUES 区。此前本模块靠对本文件外全局变量的
|
||||
* 裸 extern 取用,谁改名或删掉创建语句都不会有提示。
|
||||
*/
|
||||
int net_msg_queue_adopt(osMessageQueueId_t queue_id);
|
||||
#endif /* NET_NO_OS */
|
||||
|
||||
|
||||
/*
|
||||
* 网络初始化接口
|
||||
*/
|
||||
|
||||
@@ -329,6 +329,11 @@ void MX_FREERTOS_Init(void) {
|
||||
|
||||
/* USER CODE BEGIN RTOS_QUEUES */
|
||||
/* add queues, ... */
|
||||
/* 队列对象由上面生成的语句创建(创建点不可外移:osKernelInitialize() 之前的
|
||||
创建类 API 会杀死启动)。这里立刻把句柄交给唯一使用者 net_socket,之后本模块
|
||||
不再对外暴露这个全局变量;少了这一行,net_socket 的句柄恒为 NULL,所有 net_*
|
||||
请求会被判空丢弃(表现为网络全线静默不通)。 */
|
||||
(void)net_msg_queue_adopt(netMsgQueueHandle);
|
||||
/* USER CODE END RTOS_QUEUES */
|
||||
|
||||
/* Create the thread(s) */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<text x="186" y="152" text-anchor="end" dominant-baseline="central" class="label" fill="#333">ftpTask</text>
|
||||
<rect class="bar-seg" x="190" y="144" width="162.5" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="144" width="57.8" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="171" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 764B | 最坏 1456B | 余量 2640B (64%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="190" y="171" dominant-baseline="central" class="legend-text" fill="#333">配置 4096B | 实测峰值 1404B | 最坏 1456B | 余量 2640B (64%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="192" text-anchor="end" dominant-baseline="central" class="label" fill="#333">uiTask</text>
|
||||
<rect class="bar-seg" x="190" y="184" width="650.0" height="16" fill="#FFE0B2" rx="3"/>
|
||||
<rect x="190" y="184" width="160.8" height="16" fill="#FF9800" rx="3"/>
|
||||
@@ -33,7 +33,7 @@
|
||||
<text x="186" y="272" text-anchor="end" dominant-baseline="central" class="label" fill="#333">timeSyncTask</text>
|
||||
<rect class="bar-seg" x="190" y="264" width="101.6" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="264" width="50.1" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="291" dominant-baseline="central" class="legend-text" fill="#333">配置 2560B | 实测峰值 616B | 最坏 1264B | 余量 1296B (50%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="190" y="291" dominant-baseline="central" class="legend-text" fill="#333">配置 2560B | 实测峰值 648B | 最坏 1264B | 余量 1296B (50%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="312" text-anchor="end" dominant-baseline="central" class="label" fill="#333">adcTask</text>
|
||||
<rect class="bar-seg" x="190" y="304" width="101.6" height="16" fill="#C8E6C9" rx="3"/>
|
||||
<rect x="190" y="304" width="52.4" height="16" fill="#4CAF50" rx="3"/>
|
||||
@@ -45,7 +45,7 @@
|
||||
<text x="186" y="392" text-anchor="end" dominant-baseline="central" class="label" fill="#333">protectTask</text>
|
||||
<rect class="bar-seg" x="190" y="384" width="81.2" height="16" fill="#BBDEFB" rx="3"/>
|
||||
<rect x="190" y="384" width="34.6" height="16" fill="#2196F3" rx="3"/>
|
||||
<text x="190" y="411" dominant-baseline="central" class="legend-text" fill="#333">配置 2048B | 实测峰值 624B | 最坏 872B | 余量 1176B (57%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="190" y="411" dominant-baseline="central" class="legend-text" fill="#333">配置 2048B | 实测峰值 828B | 最坏 872B | 余量 1176B (57%) <tspan fill="#2E7D32" font-weight="bold">PASS</tspan></text>
|
||||
<text x="186" y="434" text-anchor="end" dominant-baseline="central" class="label" fill="#333">idle</text>
|
||||
<rect class="bar-seg" x="190" y="428" width="20.3" height="12" fill="#90A4AE" rx="2"/>
|
||||
<text x="214.3125" y="434" dominant-baseline="central" class="legend-text" fill="#333">512B(未实测)</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
+12
-12
@@ -10,26 +10,26 @@
|
||||
<text x="410.0" y="24" text-anchor="middle" class="title">Flash (1MB) 使用布局 — 2026-10-22 @build</text>
|
||||
<rect class="bar-seg" x="60" y="50" width="150.5" height="40" fill="#2196F3" rx="2"/>
|
||||
<text x="135.2" y="70.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">代码段 (Code) 208.2KB</text>
|
||||
<rect class="bar-seg" x="210.4621124267578" y="50" width="13.1" height="40" fill="#4CAF50" rx="2"/>
|
||||
<rect class="bar-seg" x="210.4846954345703" y="50" width="13.1" height="40" fill="#4CAF50" rx="2"/>
|
||||
<text x="227.6" y="70.0" text-anchor="start" dominant-baseline="central" class="legend-text" fill="#333">只读数据 (RO) 18.1KB</text>
|
||||
<rect class="bar-seg" x="223.57437133789062" y="50" width="575.6" height="40" fill="#E0E0E0" rx="2"/>
|
||||
<rect class="bar-seg" x="223.59695434570312" y="50" width="575.6" height="40" fill="#E0E0E0" rx="2"/>
|
||||
<text x="511.4" y="70.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">Flash 空闲 796.5KB</text>
|
||||
<text x="60" y="108" class="label" fill="#333">已用: 227.5KB (22.2%) 空闲: 796.5KB (77.8%) ER_IROM1(Code+RO): 226.4KB (22.1%) 总量: 1MB (= ROM 合计口径)</text>
|
||||
<text x="60" y="124" class="label" fill="#555">Code + RO 分布(ER_IROM1 226.4KB,按 .map 对象归类)</text>
|
||||
<rect class="bar-seg" x="60" y="130" width="280.0" height="24" fill="#4CAF50" rx="2"/>
|
||||
<text x="200.0" y="142.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">85.7KB</text>
|
||||
<rect class="bar-seg" x="340.0125979360094" y="130" width="182.0" height="24" fill="#2196F3" rx="2"/>
|
||||
<rect class="bar-seg" x="339.9739448528143" y="130" width="182.0" height="24" fill="#2196F3" rx="2"/>
|
||||
<text x="431.0" y="142.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">55.7KB</text>
|
||||
<rect class="bar-seg" x="522.027491112415" y="130" width="81.9" height="24" fill="#F44336" rx="2"/>
|
||||
<text x="563.0" y="142.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">25.0KB</text>
|
||||
<rect class="bar-seg" x="603.8992337693714" y="130" width="57.1" height="24" fill="#607D8B" rx="2"/>
|
||||
<rect class="bar-seg" x="521.963712599648" y="130" width="81.9" height="24" fill="#F44336" rx="2"/>
|
||||
<text x="562.9" y="142.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">25.0KB</text>
|
||||
<rect class="bar-seg" x="603.8241536390931" y="130" width="57.1" height="24" fill="#607D8B" rx="2"/>
|
||||
<text x="632.4" y="142.0" text-anchor="middle" dominant-baseline="central" class="label" fill="#000">17.5KB</text>
|
||||
<rect class="bar-seg" x="660.9706450833535" y="130" width="34.9" height="24" fill="#FF9800" rx="2"/>
|
||||
<rect class="bar-seg" x="695.8692575846478" y="130" width="34.4" height="24" fill="#00BCD4" rx="2"/>
|
||||
<rect class="bar-seg" x="730.228316018362" y="130" width="27.0" height="24" fill="#9C27B0" rx="2"/>
|
||||
<rect class="bar-seg" x="757.2634866945087" y="130" width="17.5" height="24" fill="#795548" rx="2"/>
|
||||
<rect class="bar-seg" x="774.7782418113417" y="130" width="1.5" height="24" fill="#B0BEC5" rx="2"/>
|
||||
<rect class="bar-seg" x="776.2723915369482" y="130" width="23.7" height="24" fill="#E0E0E0" rx="2"/>
|
||||
<rect class="bar-seg" x="660.8876867860718" y="130" width="34.9" height="24" fill="#FF9800" rx="2"/>
|
||||
<rect class="bar-seg" x="695.7814818649274" y="130" width="34.4" height="24" fill="#00BCD4" rx="2"/>
|
||||
<rect class="bar-seg" x="730.1357973565242" y="130" width="27.0" height="24" fill="#9C27B0" rx="2"/>
|
||||
<rect class="bar-seg" x="757.1672360837907" y="130" width="17.5" height="24" fill="#795548" rx="2"/>
|
||||
<rect class="bar-seg" x="774.6795734548091" y="130" width="1.5" height="24" fill="#B0BEC5" rx="2"/>
|
||||
<rect class="bar-seg" x="776.1735169272182" y="130" width="23.8" height="24" fill="#E0E0E0" rx="2"/>
|
||||
<rect x="60" y="167" width="10" height="10" fill="#4CAF50" rx="2"/>
|
||||
<text x="74" y="176" class="legend-text" fill="#333">LVGL 库 85.7KB</text>
|
||||
<rect x="255" y="167" width="10" height="10" fill="#2196F3" rx="2"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -38,10 +38,10 @@
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| ER_IROM1 | 231,784 B (226.35 KB) | 1,048,576 B (1024 KB) | 22.1% |
|
||||
| ER_IROM1 | 231,816 B (226.38 KB) | 1,048,576 B (1024 KB) | 22.1% |
|
||||
| RW_IRAM1 | 75,264 B (73.50 KB) | 131,072 B (128 KB) | 57.4% |
|
||||
| RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% |
|
||||
| **Flash (ROM 合计)** | **232,968 B (227.5 KB)** | 1,048,576 B (1024 KB) | **22.2%** |
|
||||
| **Flash (ROM 合计)** | **233,004 B (227.5 KB)** | 1,048,576 B (1024 KB) | **22.2%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
<!-- MEM_BUDGET:BEGIN generated by scripts/ram_baseline.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) |
|
||||
|---|---|---|---|---|
|
||||
| ER_IROM1 (Flash) | 231,784 B | 1,048,576 B | 22.1% | 参考 |
|
||||
| ER_IROM1 (Flash) | 231,816 B | 1,048,576 B | 22.1% | 参考 |
|
||||
| RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS |
|
||||
| UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 |
|
||||
| RW_IRAM1 | 75,264 B | 131,072 B | 57.4% | PASS |
|
||||
|
||||
| 子系统(静态 RW+ZI;除 RTOS 堆在 CCM 外均在 SRAM1) | 现值 | 配额 | 状态 |
|
||||
|---|---|---|---|
|
||||
| 网络 | 13,690 B | 12 KB | ⚠ 超 1.4 KB |
|
||||
| 网络 | 13,694 B | 12 KB | ⚠ 超 1.4 KB |
|
||||
| 存储 | 7,056 B | 12 KB | OK |
|
||||
| UI | 30,422 B | 16 KB | ⚠ 超 13.7 KB |
|
||||
| RTOS 堆 | 57,376 B | 56 KB | 堆=配额 |
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
# STM32F4-Base RAM/Flash Usage Report
|
||||
|
||||
> Generated: 2026-10-22 19:14 Map: `STM32F407-Demo.map`
|
||||
> Generated: 2026-10-22 19:56 Map: `STM32F407-Demo.map`
|
||||
|
||||
## 1. Grand Totals (全局总量)
|
||||
|
||||
| Metric | Value |
|
||||
|---|---|
|
||||
| Code (inc. data) | 213,204 B (208.2 KB) |
|
||||
| Code (inc. data) | 213,236 B (208.2 KB) |
|
||||
| RO Data | 18,580 B (18.1 KB) |
|
||||
| RW Data (initialized) | 1,184 B (1.16 KB) |
|
||||
| ZI Data (zero-init) | 131,504 B (128.4 KB) |
|
||||
| **Total RO (Code + RO)** | **231,784 B (226.4 KB)** |
|
||||
| RW Data (initialized) | 1,188 B (1.16 KB) |
|
||||
| ZI Data (zero-init) | 131,500 B (128.4 KB) |
|
||||
| **Total RO (Code + RO)** | **231,816 B (226.4 KB)** |
|
||||
| **Total RW (RW + ZI) = SRAM used** | **132,688 B (129.58 KB)** |
|
||||
| **Total ROM (Code + RO + RW init)** | **232,968 B (227.5 KB)** |
|
||||
| **Total ROM (Code + RO + RW init)** | **233,004 B (227.5 KB)** |
|
||||
|
||||
## 2. 执行区水位 (Execution Regions)
|
||||
|
||||
| Region | Base | Size | Max | Util% |
|
||||
|---|---|---|---|---|
|
||||
| ER_IROM1 | 0x08000000 | 231,784 B (226.35 KB) | 1,048,576 B (1024 KB) | 22.1% |
|
||||
| ER_IROM1 | 0x08000000 | 231,816 B (226.38 KB) | 1,048,576 B (1024 KB) | 22.1% |
|
||||
| RW_CCM | 0x10000000 | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% |
|
||||
| UNINIT_CCM | 0x1000FF00 | 48 B (0.05 KB) | 256 B (0 KB) | 18.8% |
|
||||
| RW_IRAM1 | 0x20000000 | 75,264 B (73.50 KB) | 131,072 B (128 KB) | 57.4% |
|
||||
@@ -33,54 +33,54 @@
|
||||
| 4 | 0x2000EDC8 | 6,408 | 6.26 | Zero | .bss | ui_port.o |
|
||||
| 5 | 0x2000667C | 6,200 | 6.05 | Zero | .bss | nand_ftl.o |
|
||||
| 6 | 0x20004E18 | 4,152 | 4.05 | Zero | .bss | ch395f.o |
|
||||
| 7 | 0x20002054 | 4,096 | 4.00 | Zero | .bss | console_log.o |
|
||||
| 8 | 0x20001274 | 3,552 | 3.47 | Zero | .bss | sys_log_mcu.o |
|
||||
| 9 | 0x20003640 | 2,724 | 2.66 | Zero | .bss | default_task.o |
|
||||
| 7 | 0x20002058 | 4,096 | 4.00 | Zero | .bss | console_log.o |
|
||||
| 8 | 0x20001278 | 3,552 | 3.47 | Zero | .bss | sys_log_mcu.o |
|
||||
| 9 | 0x20003644 | 2,724 | 2.66 | Zero | .bss | default_task.o |
|
||||
| 10 | 0x2000A524 | 1,720 | 1.68 | Zero | .bss | cmsis_os2.o |
|
||||
| 11 | 0x2000444C | 1,440 | 1.41 | Zero | .bss | sample_ring.o |
|
||||
| 12 | 0x20009F48 | 1,220 | 1.19 | Zero | .bss | tasks.o |
|
||||
| 13 | 0x20000D74 | 1,104 | 1.08 | Zero | .bss | cfg_file_store_mcu.o |
|
||||
| 14 | 0x20003054 | 1,064 | 1.04 | Zero | .bss | soe_store.o |
|
||||
| 13 | 0x20000D78 | 1,104 | 1.08 | Zero | .bss | cfg_file_store_mcu.o |
|
||||
| 14 | 0x20003058 | 1,064 | 1.04 | Zero | .bss | soe_store.o |
|
||||
| 15 | 0x20012200 | 1,024 | 1.00 | Zero | | startup_stm32f407xx.o |
|
||||
| 16 | 0x20005E50 | 800 | 0.78 | Zero | .bss | gd5f2gq5ue.o |
|
||||
| 17 | 0x200040E8 | 712 | 0.70 | Zero | .bss | iec104_serv.o |
|
||||
| 18 | 0x20000AB4 | 704 | 0.69 | Zero | .bss | cfg_file.o |
|
||||
| 19 | 0x200005CC | 560 | 0.55 | Zero | .bss | spi.o |
|
||||
| 20 | 0x20000844 | 552 | 0.54 | Zero | .bss | usart.o |
|
||||
| 18 | 0x20000AB8 | 704 | 0.69 | Zero | .bss | cfg_file.o |
|
||||
| 19 | 0x200005D0 | 560 | 0.55 | Zero | .bss | spi.o |
|
||||
| 20 | 0x20000848 | 552 | 0.54 | Zero | .bss | usart.o |
|
||||
| 21 | 0x20009CE0 | 552 | 0.54 | Zero | .bss | lftpd_io.o |
|
||||
| 22 | 0x2000ABDC | 492 | 0.48 | Zero | .bss | lv_init.o |
|
||||
| 23 | 0x20004C38 | 480 | 0.47 | Zero | .bss | freq.o |
|
||||
| 24 | 0x2000629C | 416 | 0.41 | Zero | .bss | net_socket.o |
|
||||
| 25 | 0x200064DC | 416 | 0.41 | Zero | .bss | net_pending.o |
|
||||
| 26 | 0x200034C0 | 384 | 0.38 | Zero | .bss | task_prof.o |
|
||||
| 26 | 0x200034C4 | 384 | 0.38 | Zero | .bss | task_prof.o |
|
||||
| 27 | 0x20004A8C | 320 | 0.31 | Zero | .bss | prot_set.o |
|
||||
| 28 | 0x2000A40C | 280 | 0.27 | Zero | .bss | timers.o |
|
||||
| 29 | 0x20006190 | 268 | 0.26 | Zero | .bss | rs485.o |
|
||||
| 30 | 0x200011C4 | 176 | 0.17 | Zero | .bss | prot_set_store.o |
|
||||
| 31 | 0x200004C4 | 168 | 0.16 | Zero | .bss | adc.o |
|
||||
| 32 | 0x200002B0 | 160 | 0.16 | Data | .data | lftpd.o |
|
||||
| 30 | 0x200011C8 | 176 | 0.17 | Zero | .bss | prot_set_store.o |
|
||||
| 31 | 0x200004C8 | 168 | 0.16 | Zero | .bss | adc.o |
|
||||
| 32 | 0x200002B4 | 160 | 0.16 | Data | .data | lftpd.o |
|
||||
| 33 | 0x200049EC | 160 | 0.16 | Zero | .bss | phasor.o |
|
||||
| 34 | 0x200106D0 | 152 | 0.15 | Zero | .bss | ui_menu_view.o |
|
||||
| 35 | 0x2000643C | 128 | 0.12 | Zero | .bss | net_listener.o |
|
||||
| 36 | 0x20004BCC | 108 | 0.11 | Zero | .bss | prot_elm.o |
|
||||
| 37 | 0x2000056C | 84 | 0.08 | Zero | .bss | i2c.o |
|
||||
| 37 | 0x20000570 | 84 | 0.08 | Zero | .bss | i2c.o |
|
||||
| 38 | 0x200043F8 | 84 | 0.08 | Zero | .bss | adc_input.o |
|
||||
| 39 | 0x2000024C | 83 | 0.08 | Data | .data | ftp_cfg.o |
|
||||
| 40 | 0x200007FC | 72 | 0.07 | Zero | .bss | tim.o |
|
||||
| 41 | 0x20000A6C | 72 | 0.07 | Zero | .bss | stm32f4xx_hal_timebase_tim.o |
|
||||
| 42 | 0x2000347C | 68 | 0.07 | Zero | .bss | task_watchdog.o |
|
||||
| 43 | 0x20000480 | 65 | 0.06 | Zero | .bss | freertos.o |
|
||||
| 39 | 0x20000250 | 83 | 0.08 | Data | .data | ftp_cfg.o |
|
||||
| 40 | 0x20000800 | 72 | 0.07 | Zero | .bss | tim.o |
|
||||
| 41 | 0x20000A70 | 72 | 0.07 | Zero | .bss | stm32f4xx_hal_timebase_tim.o |
|
||||
| 42 | 0x20003480 | 68 | 0.07 | Zero | .bss | task_watchdog.o |
|
||||
| 43 | 0x20000484 | 65 | 0.06 | Zero | .bss | freertos.o |
|
||||
| 44 | 0x20009F08 | 64 | 0.06 | Zero | .bss | queue.o |
|
||||
| 45 | 0x20000354 | 60 | 0.06 | Data | .data | tasks.o |
|
||||
| 46 | 0x2000040C | 60 | 0.06 | Data | .data | ui_page_selftest.o |
|
||||
| 45 | 0x20000358 | 60 | 0.06 | Data | .data | tasks.o |
|
||||
| 46 | 0x20000410 | 60 | 0.06 | Data | .data | ui_page_selftest.o |
|
||||
| 47 | 0x20010768 | 60 | 0.06 | Zero | .bss | ui_page_runlog.o |
|
||||
| 48 | 0x20000150 | 48 | 0.05 | Data | .data | adc_health.o |
|
||||
| 49 | 0x200043C8 | 48 | 0.05 | Zero | .bss | iec104_pts.o |
|
||||
| 50 | 0x20000000 | 44 | 0.04 | Data | .data | freertos.o |
|
||||
| 51 | 0x2000009C | 44 | 0.04 | Data | .data | task_watchdog.o |
|
||||
| 52 | 0x20000044 | 36 | 0.04 | Data | .data | sys_log_mcu.o |
|
||||
| 53 | 0x20000228 | 36 | 0.04 | Data | .data | net_cfg.o |
|
||||
| 54 | 0x20000448 | 32 | 0.03 | Data | .data | ui_standby.o |
|
||||
| 53 | 0x2000022C | 36 | 0.04 | Data | .data | net_cfg.o |
|
||||
| 54 | 0x2000044C | 32 | 0.03 | Data | .data | ui_standby.o |
|
||||
| 55 | 0x20006170 | 32 | 0.03 | Zero | .bss | tpafe5160.o |
|
||||
| 56 | 0x200064BC | 32 | 0.03 | Zero | .bss | net_events.o |
|
||||
| 57 | 0x20000128 | 28 | 0.03 | Data | .data | adc_input.o |
|
||||
@@ -88,47 +88,47 @@
|
||||
| 59 | 0x200000E4 | 24 | 0.02 | Data | .data | adc_task.o |
|
||||
| 60 | 0x20000180 | 24 | 0.02 | Data | .data | prot_set.o |
|
||||
| 61 | 0x2000019C | 24 | 0.02 | Data | .data | freq.o |
|
||||
| 62 | 0x200001FC | 24 | 0.02 | Data | .data | net_listener.o |
|
||||
| 62 | 0x20000200 | 24 | 0.02 | Data | .data | net_listener.o |
|
||||
| 63 | 0x200043B0 | 24 | 0.02 | Zero | .bss | protect_task.o |
|
||||
| 64 | 0x20000030 | 20 | 0.02 | Data | .data | cfg_file.o |
|
||||
| 65 | 0x20000080 | 20 | 0.02 | Data | .data | soe_store.o |
|
||||
| 66 | 0x200001D0 | 20 | 0.02 | Data | .data | gd5f2gq5ue.o |
|
||||
| 67 | 0x20000390 | 20 | 0.02 | Data | .data | timers.o |
|
||||
| 68 | 0x20000468 | 20 | 0.02 | Data | .data | ui_net_sink.o |
|
||||
| 69 | 0x200003D0 | 18 | 0.02 | Data | .data | ui_menu.o |
|
||||
| 67 | 0x20000394 | 20 | 0.02 | Data | .data | timers.o |
|
||||
| 68 | 0x2000046C | 20 | 0.02 | Data | .data | ui_net_sink.o |
|
||||
| 69 | 0x200003D4 | 18 | 0.02 | Data | .data | ui_menu.o |
|
||||
| 70 | 0x200000FC | 16 | 0.02 | Data | .data | iec104_serv.o |
|
||||
| 71 | 0x20000118 | 16 | 0.02 | Data | .data | iec104_pts.o |
|
||||
| 72 | 0x20000214 | 16 | 0.02 | Data | .data | net_events.o |
|
||||
| 73 | 0x200002A0 | 16 | 0.02 | Data | .data | nand_ftl.o |
|
||||
| 74 | 0x200003EC | 16 | 0.02 | Data | .data | ui_content_page.o |
|
||||
| 75 | 0x200000D4 | 12 | 0.01 | Data | .data | default_task.o |
|
||||
| 76 | 0x200001B4 | 12 | 0.01 | Data | .data | stm32f4xx_hal.o |
|
||||
| 77 | 0x200001E4 | 12 | 0.01 | Data | .data | tpafe5160.o |
|
||||
| 78 | 0x200001F0 | 12 | 0.01 | Data | .data | net_socket.o |
|
||||
| 79 | 0x200003A8 | 12 | 0.01 | Data | .data | port.o |
|
||||
| 80 | 0x200003C4 | 12 | 0.01 | Data | .data | ui_port.o |
|
||||
| 81 | 0x200003FC | 12 | 0.01 | Data | .data | ui_page_password.o |
|
||||
| 82 | 0x200005C0 | 12 | 0.01 | Zero | .bss | iwdg.o |
|
||||
| 72 | 0x200001F0 | 16 | 0.02 | Data | .data | net_socket.o |
|
||||
| 73 | 0x20000218 | 16 | 0.02 | Data | .data | net_events.o |
|
||||
| 74 | 0x200002A4 | 16 | 0.02 | Data | .data | nand_ftl.o |
|
||||
| 75 | 0x200003F0 | 16 | 0.02 | Data | .data | ui_content_page.o |
|
||||
| 76 | 0x200000D4 | 12 | 0.01 | Data | .data | default_task.o |
|
||||
| 77 | 0x200001B4 | 12 | 0.01 | Data | .data | stm32f4xx_hal.o |
|
||||
| 78 | 0x200001E4 | 12 | 0.01 | Data | .data | tpafe5160.o |
|
||||
| 79 | 0x200003AC | 12 | 0.01 | Data | .data | port.o |
|
||||
| 80 | 0x200003C8 | 12 | 0.01 | Data | .data | ui_port.o |
|
||||
| 81 | 0x20000400 | 12 | 0.01 | Data | .data | ui_page_password.o |
|
||||
| 82 | 0x200005C4 | 12 | 0.01 | Zero | .bss | iwdg.o |
|
||||
| 83 | 0x200001C4 | 10 | 0.01 | Data | .data | ch395f.o |
|
||||
| 84 | 0x20000094 | 8 | 0.01 | Data | .data | sys_clock.o |
|
||||
| 85 | 0x200000C8 | 8 | 0.01 | Data | .data | task_prof.o |
|
||||
| 86 | 0x2000010C | 8 | 0.01 | Data | .data | protect_task.o |
|
||||
| 87 | 0x20000144 | 8 | 0.01 | Data | .data | sample_ring.o |
|
||||
| 88 | 0x200003B4 | 8 | 0.01 | Data | .data | ff.o |
|
||||
| 89 | 0x200003BC | 8 | 0.01 | Data | .data | ffsystem.o |
|
||||
| 90 | 0x200003E4 | 8 | 0.01 | Data | .data | ui_menu_view.o |
|
||||
| 88 | 0x200003B8 | 8 | 0.01 | Data | .data | ff.o |
|
||||
| 89 | 0x200003C0 | 8 | 0.01 | Data | .data | ffsystem.o |
|
||||
| 90 | 0x200003E8 | 8 | 0.01 | Data | .data | ui_menu_view.o |
|
||||
| 91 | 0x2000002C | 4 | 0.00 | Data | .data | app_main.o |
|
||||
| 92 | 0x200000D0 | 4 | 0.00 | Data | .data | vol_lock.o |
|
||||
| 93 | 0x200000E0 | 4 | 0.00 | Data | .data | net_task.o |
|
||||
| 94 | 0x200001C0 | 4 | 0.00 | Data | .data | system_stm32f4xx.o |
|
||||
| 95 | 0x20000224 | 4 | 0.00 | Data | .data | net_pending.o |
|
||||
| 96 | 0x20000350 | 4 | 0.00 | Data | .data | lftpd_io.o |
|
||||
| 97 | 0x200003A4 | 4 | 0.00 | Data | .data | cmsis_os2.o |
|
||||
| 98 | 0x2000047C | 4 | 0.00 | Data | .data | mc_w.l(errno.o) |
|
||||
| 95 | 0x20000228 | 4 | 0.00 | Data | .data | net_pending.o |
|
||||
| 96 | 0x20000354 | 4 | 0.00 | Data | .data | lftpd_io.o |
|
||||
| 97 | 0x200003A8 | 4 | 0.00 | Data | .data | cmsis_os2.o |
|
||||
| 98 | 0x20000480 | 4 | 0.00 | Data | .data | mc_w.l(errno.o) |
|
||||
| 99 | 0x2000014C | 2 | 0.00 | Data | .data | phasor.o |
|
||||
| 100 | 0x20000408 | 2 | 0.00 | Data | .data | ui_page_net_cfg.o |
|
||||
| 100 | 0x2000040C | 2 | 0.00 | Data | .data | ui_page_net_cfg.o |
|
||||
| 101 | 0x20000198 | 1 | 0.00 | Data | .data | prot_elm.o |
|
||||
| | | **75,239** | **73.48** | | | **Total** |
|
||||
| | | **75,243** | **73.48** | | | **Total** |
|
||||
|
||||
## 4. Image Component Sizes(RW + ZI > 0,按大小降序)
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
| 22 | usart.o | 884 | 0 | 0 | 552 | 552 |
|
||||
| 23 | freq.o | 764 | 8 | 24 | 480 | 504 |
|
||||
| 24 | lv_init.o | 156 | 0 | 0 | 492 | 492 |
|
||||
| 25 | net_socket.o | 4,916 | 443 | 12 | 416 | 428 |
|
||||
| 25 | net_socket.o | 4,944 | 443 | 16 | 416 | 432 |
|
||||
| 26 | net_pending.o | 1,400 | 0 | 4 | 416 | 420 |
|
||||
| 27 | task_prof.o | 638 | 185 | 8 | 384 | 392 |
|
||||
| 28 | prot_set.o | 844 | 640 | 24 | 320 | 344 |
|
||||
@@ -171,7 +171,7 @@
|
||||
| 35 | ui_menu_view.o | 2,034 | 16 | 8 | 152 | 160 |
|
||||
| 36 | net_listener.o | 948 | 207 | 24 | 128 | 152 |
|
||||
| 37 | adc_input.o | 592 | 27 | 28 | 84 | 112 |
|
||||
| 38 | freertos.o | 712 | 592 | 44 | 65 | 109 |
|
||||
| 38 | freertos.o | 716 | 592 | 44 | 65 | 109 |
|
||||
| 39 | prot_elm.o | 708 | 227 | 1 | 108 | 109 |
|
||||
| 40 | i2c.o | 168 | 0 | 0 | 84 | 84 |
|
||||
| 41 | ftp_cfg.o | 152 | 225 | 83 | 0 | 83 |
|
||||
@@ -187,8 +187,8 @@
|
||||
| 51 | net_cfg.o | 832 | 103 | 36 | 0 | 36 |
|
||||
| 52 | protect_task.o | 840 | 68 | 8 | 24 | 32 |
|
||||
| 53 | ui_standby.o | 1,208 | 67 | 32 | 0 | 32 |
|
||||
| 54 | (incl. Padding) | 284 | 96 | 16 | 9 | 25 |
|
||||
| 55 | adc_task.o | 1,520 | 234 | 24 | 0 | 24 |
|
||||
| 54 | adc_task.o | 1,520 | 234 | 24 | 0 | 24 |
|
||||
| 55 | (incl. Padding) | 284 | 96 | 16 | 5 | 21 |
|
||||
| 56 | ui_menu.o | 760 | 137 | 18 | 0 | 18 |
|
||||
| 57 | ui_content_page.o | 1,664 | 81 | 16 | 0 | 16 |
|
||||
| 58 | iwdg.o | 28 | 0 | 0 | 12 | 12 |
|
||||
@@ -204,7 +204,7 @@
|
||||
| 68 | vol_lock.o | 92 | 0 | 4 | 0 | 4 |
|
||||
| 69 | errno.o | 20 | 0 | 4 | 0 | 4 |
|
||||
| 70 | ui_page_net_cfg.o | 1,004 | 105 | 2 | 0 | 2 |
|
||||
| | **All .o files** | **213,204** | **18,580** | **1,184** | **131,504** | **132,688** |
|
||||
| | **All .o files** | **213,236** | **18,580** | **1,188** | **131,500** | **132,688** |
|
||||
|
||||
## 5. Flash (Code + RO Data) Top-30(按大小降序)
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
| 1 | ff.o | 7,962 | 282 | 8,244 |
|
||||
| 2 | cfg_file.o | 5,970 | 810 | 6,780 |
|
||||
| 3 | lftpd.o | 6,108 | 509 | 6,617 |
|
||||
| 4 | net_socket.o | 4,916 | 443 | 5,359 |
|
||||
| 4 | net_socket.o | 4,944 | 443 | 5,387 |
|
||||
| 5 | lv_indev.o | 4,928 | 0 | 4,928 |
|
||||
| 6 | ch395f.o | 3,978 | 603 | 4,581 |
|
||||
| 7 | ui_font_cn_12.o | 0 | 4,545 | 4,545 |
|
||||
@@ -240,6 +240,6 @@
|
||||
| 28 | printfa.o | 2,312 | 0 | 2,312 |
|
||||
| 29 | stm32f4xx_hal_i2c.o | 2,294 | 0 | 2,294 |
|
||||
| 30 | lv_display.o | 2,284 | 0 | 2,284 |
|
||||
| | **All .o files** | **213,204** | **18,580** | **231,784** |
|
||||
| | **All .o files** | **213,236** | **18,580** | **231,816** |
|
||||
|
||||
> 自洽校验:per-file 213,204/18,580/1,184/131,504 vs Grand Totals 213,204/18,580/1,184/131,504(CodeΔ=+0 / ROΔ=+0 / RWΔ=+0 / ZIΔ=+0;精确一致(含 '('incl. Generated)'-'(incl. Padding)' 台账行))→ **PASS**
|
||||
> 自洽校验:per-file 213,236/18,580/1,188/131,500 vs Grand Totals 213,236/18,580/1,188/131,500(CodeΔ=+0 / ROΔ=+0 / RWΔ=+0 / ZIΔ=+0;精确一致(含 '('incl. Generated)'-'(incl. Padding)' 台账行))→ **PASS**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Stack budget report
|
||||
|
||||
- Source: `MDK-ARM\STM32F407-Demo\STM32F407-Demo.htm` (Keil static call graph)
|
||||
- Linker run: Thu Oct 22 19:12:02 2026
|
||||
- Linker run: Thu Oct 22 19:53:08 2026
|
||||
- Global maximum stack usage: **3024 B** (any call tree)
|
||||
- Runtime watermark: 8 task(s) from 串口采集日志 `.dsh\skills\serial-assistant\scripts\state\serial.log`
|
||||
|
||||
@@ -11,13 +11,13 @@ Rule: `margin = cfg - max(static_max_depth, runtime_peak)` must be >= max(1024 B
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| defaultTask | `StartDefaultTask` | 5120 | 3024 | 2152 | 3024 | 2096 | 40% | PASS |
|
||||
| netTask | `StartNetTask` | 3840 | 1912 | 1116 | 1912 | 1928 | 50% | PASS |
|
||||
| ftpTask | `StartFtpTask` | 4096 | 1456 | 764 | 1456 | 2640 | 64% | PASS |
|
||||
| ftpTask | `StartFtpTask` | 4096 | 1456 | 1404 | 1456 | 2640 | 64% | PASS |
|
||||
| uiTask | `StartUiTask` | 16384 | 1336 | 4052 | 4052 | 12332 | 75% | PASS |
|
||||
| testTask | `start_test_task` | 8192 | 736 | - | 736 | 7456 | 91% | PASS |
|
||||
| timeSyncTask | `time_sync_task` | 2560 | 1264 | 616 | 1264 | 1296 | 50% | PASS |
|
||||
| timeSyncTask | `time_sync_task` | 2560 | 1264 | 648 | 1264 | 1296 | 50% | PASS |
|
||||
| adcTask | `adc_task_func` | 2560 | 1320 | 952 | 1320 | 1240 | 48% | PASS |
|
||||
| iec104Task | `iec104_serv_task` | 2560 | 1456 | 540 | 1456 | 1104 | 43% | PASS |
|
||||
| protectTask | `protect_task` | 2048 | 872 | 624 | 872 | 1176 | 57% | PASS |
|
||||
| protectTask | `protect_task` | 2048 | 872 | 828 | 872 | 1176 | 57% | PASS |
|
||||
|
||||
`Static max` = armlink worst-case call-tree depth; `Runtime peak` = measured high-water mark (boot + whatever workload ran before the sample); `Worst` = max of the two, which is what the verdict is computed from.
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
|
||||
|
||||
| 资源 | 已用 | 总量 | 利用率 | 余量 | 红线说明 |
|
||||
|---|---|---|---|---|---|
|
||||
| Flash(`ER_IROM1` = Code + RO) | 231,784 B(226.4 KB) | 1 MB | 22.1% | ≈804 KB | **充裕**:产品需求无 OTA / 双镜像预算,Flash 不是卡点;死代码裁剪簇已收口 → `docs/问题记录/项目审查与优化建议报告.md` §5.4 |
|
||||
| Flash(`ER_IROM1` = Code + RO) | 231,816 B(226.4 KB) | 1 MB | 22.1% | ≈804 KB | **充裕**:产品需求无 OTA / 双镜像预算,Flash 不是卡点;死代码裁剪簇已收口 → `docs/问题记录/项目审查与优化建议报告.md` §5.4 |
|
||||
| 主 SRAM1(静态区;FreeRTOS 堆已迁 CCM) | 75,264 B(73.5 KB) | 128 KB | 57.4% | 55,808 B | 已不紧张——2026-10-11 堆迁 CCM 与 2026-10-15 `LV_MEM_SIZE` 40→16 KB 两步的结果 |
|
||||
| CCM(`RW_CCM` 段) | 57,376 B(56.0 KB) | 65,280 B | **87.9%** | **7,904 B** | **当前真正的红线**:加任务 / 抬栈 / 加堆会先在这里撞墙;`mem-budget` 钩子在 92% 拦提交 |
|
||||
|
||||
|
||||
@@ -49,7 +49,12 @@
|
||||
| 内存 RAM | N-14 🟡(N-22) | FTL 单页写回缓存无空闲/掉电强制 flush(整页写与换页已 flush,`f_close` 经 `CTRL_SYNC` 已落盘) | 用户裁定 2026-10-22 暂不做;残余窗口只是"单条记录" |
|
||||
| Flash | **F-5 🟡 观察项**(N-28) | uvprojx 201 个 LVGL `.c` 里 **127 个空 TU**;增量构建 4~5 s、CI 不跑 `@build` | 有实测全量耗时痛点再做,用 `<IncludeInBuild>` |
|
||||
| 结构 | **S-1 已止住恶化**(2026-10-22 上门禁) | 不是"命名错位",是真实的 **BSP→App 反向 include**,精确口径 **8 个文件 9 处**(上一版写"7 文件 15 处"也不准,已按 `check_layer_deps.py` 判定重算):`cfg_file.h`×2(NETCFG)、`vol_lock.h`×1(lftpd_io)、`sys_log.h`×3(UI 两处 + `ui_w_records.h`);`console_log.h` / `sys_clock.h` / `sha256.h` 三个横切叶子头已**显式豁免**。**运行时的属主纪律本来就没破**(UI 只投递 `net_cfg_save_request()`,写盘在 defaultTask),要修的只是静态方向 | **门禁已落地**(`layer-deps` + `scripts/check_layer_deps.py`:存量 6 条基线只减不增、新增当场 FAIL,落地时做过故意违规自证)。剩下的才是反转:把 `cfg_file_*` 直接调用换成注入的 ops(NETCFG 已有 `net_cfg_set_save_req_cb` 先例);**目录搬迁仍暂缓**(远程 CI 不跑 `@build`,兜底未成立) |
|
||||
| 结构 | **S-2 只剩 1 处**(24 处手写已消 23) | 今天已消 23 处:2 处与 `Inc/spi.h`/`Inc/i2c.h` 重复(GD5F/SD2506)+ 19 处任务句柄与属性(新建 `App/task/task_handles.h`)+ 1 处 `main.c` 函数内 `g_rcc_csr_latched`(改由 `App/app/app_main.h` 声明)+ 1 处 `ch395f.c:177`(**改为契约转调**:GD5F 的完成标志收为文件内 `static`,导出 `gd5f_spi1_notify_done()` / `gd5f_spi1_notify_error()`,CH395F 那个"HAL 全局唯一回调"的 SPI1 分支只转调、不再直接写它的变量;`HAL_SPI_AbortCpltCallback` 仍无人实现 → 另列观察)。**只剩 `net_socket.c:77` 的 `netMsgQueueHandle`**。**两类不算债**:`stm32f4xx_it.c:241-256` 是 CubeMX「External variables」生成块(删了会被写回来);`:183/195/207/220` 是 `__asm` Handler 里的汇编标签引用(ARMCC `__asm` 取不到 C 数据符号,**合法例外**) | 剩下一步:`netMsgQueueHandle` 收进 net_socket 内部 + 提供投递 API |
|
||||
| ~~结构 S-2~~ ✅ **已闭环销项 2026-10-22** | 该修的 24 处手写跨模块裸 `extern` **全部消完**:2 处与 `Inc/spi.h`/`Inc/i2c.h` 重复 → 改 include;19 处任务句柄与属性 → `App/task/task_handles.h`;1 处 `main.c` 函数内 `g_rcc_csr_latched` → `App/app/app_main.h`;
|
||||
`ch395f.c:177` 的 `g_spi1_dma_done` → 标志收回 GD5F 内部 `static`,改由 `gd5f_spi1_notify_done()` / `notify_error()` 契约转调;最后一处 `net_socket.c:77` 的
|
||||
`netMsgQueueHandle` → 句柄改为 net_socket 私有 `static s_net_msg_queue`,由 `Src/freertos.c` 的 `USER CODE BEGIN RTOS_QUEUES` 区在队列创建后立刻
|
||||
`net_msg_queue_adopt()` 绑定(创建点不能外移——`osKernelInitialize()` 之前的创建类 API 会杀死启动;**故意不新建第二个队列**:那会白占 CCM 里 8×`net_msg_t`
|
||||
的堆空间,而 CCM 正是当前红线)。**两类从来不算债**:`stm32f4xx_it.c:241-256` 是 CubeMX「External variables」生成块;`:183/195/207/220` 是 `__asm` Handler
|
||||
里的汇编标签引用(ARMCC `__asm` 取不到 C 数据符号)。 | 无(后续由 `layer-deps` 与 `cubemx-survival` 两条门禁守着不回退:新增 `net-msgq-adopt` 存活项) |
|
||||
| 驱动规范 | S-5 ❌ | `bsp_err_t` 至今只出现在本报告里(无统一错误码/超时/重试约定) | 定义后进 `docs/代码规范/` |
|
||||
| 网络 | N-09 / PHY ❌(N-25) | `NET_MAX_SOCKETS` 仍为 8(与单连接复用语义不符);PHY 强制 100M 无自协商回退;PASV 每次新建监听 | 见 §4.2;随 N-25 一并处置 |
|
||||
| 存储 | N-15 🟡(N-25) | `nand_ftl.o` 静态 6,216 B——三块 2 KB 级页缓冲并存未合并 | 与 R-3 同批评估 |
|
||||
@@ -88,7 +93,7 @@ git ls-files -z | xargs -0 stat -c '%s'
|
||||
|
||||
| 名词 | 口径 |
|
||||
|---|---|
|
||||
| Flash 占用 | `Code + RO-data` = `ER_IROM1` = **231,784 B(22.1%)**;`ROM 合计` 再加 `RW` 初始化表 = 232,968 B(22.2%) |
|
||||
| Flash 占用 | `Code + RO-data` = `ER_IROM1` = **231,816 B(22.1%)**;`ROM 合计` 再加 `RW` 初始化表 = 233,004 B(22.2%) |
|
||||
| SRAM 占用 | `RW_IRAM1`(DMA 可达区)与 `RW_CCM`(仅 CPU)分开计,二者不可互换(规则 R2/R3) |
|
||||
| 最坏栈 | `max(armlink 静态调用图深度, 真机 [STACK] 高水位)`;判定线 `余量 ≥ max(1024 B ISR, 配置×30%)` |
|
||||
| 编译单元 | uvprojx 的 `<FilePath>` 计数(今日 **326 个 `.c`**,其中 LVGL 201);"自研 `.c`" 另按目录口径 114 个 |
|
||||
@@ -225,8 +230,8 @@ defaultTask 单属主;原子写经卷锁;旧档迁移已删除。**仍列为
|
||||
|
||||
| 指标 | 2026-10-22 | 2026-10-15 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `Code` | 213,204 B | 213,520 B | F-6 收口 −332 B;同日 SPI 回调归属纠正 +16 B |
|
||||
| `ER_IROM1`(Code+RO) | **231,784 B / 22.1%** | 232,280 B / 22.2% | 余 ≈804 KB |
|
||||
| `Code` | 213,236 B | 213,520 B | 当日累计:F-6 −332 B、SPI 回调归属 +16 B、消息队列收口 +32 B |
|
||||
| `ER_IROM1`(Code+RO) | **231,816 B / 22.1%** | 232,280 B / 22.2% | 余 ≈804 KB |
|
||||
| `RW_IRAM1` | **75,264 B / 57.4%**(余 55,808) | 73,568 B / 56.1% | 增量来自 B5/B8 功能码 |
|
||||
| `RW_CCM` | **57,376 B / 87.9%**(余 7,904) | 57,376 B / 87.9% | **当前唯一红线** |
|
||||
| FreeRTOS 堆 | 56 KB(57,344 B)@CCM;实测 `free=15,800` / `min_ever=8,464` | 同 | 2026-10-22 真机 |
|
||||
@@ -266,7 +271,7 @@ defaultTask 单属主;原子写经卷锁;旧档迁移已删除。**仍列为
|
||||
| **F-6** 双精度软浮点 | ≈1 KB | **归因错**:全库 0 处 `%f`;剩余 `dadd/dmul/ddiv/depilogue/dfixul` 1,018 B 锁在 MicroLIB `printfa.o` 的 `_printf_core → _fp_digits`,只要用 `snprintf` 就删不掉。但**根因侧确有可修点**:`App/algo/prot_set.h` 两个 Q10 宏写成 `double` | ✅ **已落地 2026-10-22**:改单精度 → `@build` −332 B、5 个 helper(300 B)消失;数值逐位等价(穷举 42 个字面量 + int32 全域 ÷1024 往返 4.49×10⁶ 例零差异);真机 `@test` PASS |
|
||||
|
||||
**当前可回收 Flash = 0 B**(F-4/F-6 已定论,图片链同理不打补丁)。LVGL 仍占镜像 **37.8%**
|
||||
(87,706 / 231,784 B)——这是"用 LVGL 画单色菜单"的结构性代价,F-1/F-2/F-3 已省掉 64,576 B。
|
||||
(87,706 / 231,816 B)——这是"用 LVGL 画单色菜单"的结构性代价,F-1/F-2/F-3 已省掉 64,576 B。
|
||||
|
||||
### 5.5 内存治理长效机制(常开,不受暂缓影响)
|
||||
|
||||
@@ -374,7 +379,8 @@ W6 簇按 U4 → U1 → U3 → U2 的顺序执行完毕(U2 停在"够用即止
|
||||
| **D-1** | 外部资料与工程文档同仓同树 | ❌ 暂不处理 | 本文 §3.3、登记簿 N-29 |
|
||||
| D-2 ~ D-7 | 文档治理条目(链接/同源/编号/BOM 等) | ✅ 多数已制度化为钩子 | 本文 §3.2、`../文档规范.md` |
|
||||
| D-9 | 文档面残余观察 | 🟡 观察 | 本节即定义位 |
|
||||
| **S-1 / S-2** | 分层反向依赖 / 跨模块裸 `extern` | 🟡 半办(2026-10-22:24 处手写裸 extern 已消 23 处,只剩 `net_socket.c:77`;反向 include 8 文件 9 处已上门禁、6 条基线待还) | 本文 §0.4、登记簿 C5 |
|
||||
| **S-1** | 分层反向依赖(BSP include App 的头) | 🟡 已止住恶化(存量 6 条基线待还,新增被 `layer-deps` 拦) | 本文 §0.4、登记簿 C5 |
|
||||
| **S-2** | 跨模块裸 `extern` | ✅ **已闭环 2026-10-22**(24 处手写全消;两类本就不算债见 §0.4) | 本文变更记录 2026-10-22 三行;契约见 `App/task/task_handles.h`、`gd5f_spi1_notify_*`、`net_msg_queue_adopt` |
|
||||
| **S-4** | `app_cfg.h` 未接线占位开关 | ✅ **已闭环 2026-10-22**(4 个零消费点宏删除) | `App/app/app_cfg.h` 修改记录 v1.2;口径同步见 `../环境与部署/项目部署环境要求.md` §3.2/§3.5、`../产品需求/产品需求设计文档.md`、`../任务规划/排期详述.md` C5 |
|
||||
| **S-3** | `.ioc` 侧 USART1 配置 | ❌ 在策 | 登记簿 S-3 |
|
||||
| **S-5** | 统一 `bsp_err_t` 错误码约定 | ❌ 未做 | 本文 §0.4、`docs/代码规范/`(待建) |
|
||||
@@ -409,6 +415,33 @@ W6 簇按 U4 → U1 → U3 → U2 的顺序执行完毕(U2 停在"够用即止
|
||||
**改判的三条旧结论**:① §6 的 U1/U3/U4 原写「❌ 未建」,实际已落地(`ui_tokens.h` 69 行、`ui_page_registry.c` 描述符注册表、`ui-golden`+`font-charset` 两枚钩子);U2 只有 `ui_w_records` 一个组件;"27 页未落地"实为 7 页。② "新增一页 ≤30 行"目标**未达**(最省 40 行),如实记为未达项。③ §0.4 与登记簿已漂开 → 本版把待办清单降级为**快照 + 指向登记簿**,权威只留一处。
|
||||
**刻意保留的三层**(删了会出事):§9 **编号族登记处**——本文是 `id_registry.json` 里 `N-RPT`/`D-RPT`/`S-RPT`/`R-RPT`(游标 R-9)/`F-RPT`/`U-RPT`(游标 U5) 六族的属主登记处,且外部存在「报告 N-14」「报告 F-4/F-5/F-6」「报告 D-1」「报告 R-2/R-3」式紧邻引用与 `check_dangling`,删定义位即触发编号门禁;§1.2/§1.3 方法与口径(数字可重跑);文末**变更记录 + 已销项去处表**原样冻结保留(52 行)。被外部点名的锚点(`§0.3`/`§3.1`/`§4.1`/`§4.2`/`§4.3`/`§5.3`×9/`§5.4`/`§5.5`×4/`§6.2`/`§6.3`/`§6.5`)逐个保留,**68 处入站引用零改动**。
|
||||
**门禁**:`check_doc_links.py --all --sections-strict` → 146 文档 0 问题(章节引用 2,499、可判定 1,483);`check_ids.py --strict` 增量拦截通过、**存量债 650 → 641(−9)**、可判定比例 82.98% → **82.79%**(仍高于基线 82.6%,但缓冲从 0.38pp 缩到 0.19pp——删掉的那批引用 99% 是可判定的,属预期副作用);`mem-numbers` / `ram_baseline --gate` / `task-table` / `cubemx-survival` 全 0。字节卫生:BOM 无 / CR 0 / U+FFFD 0 / 无行尾空格 / LF 结尾。 |
|
||||
| **2026-10-22** | **S-2 收尾:`netMsgQueueHandle` 收进 net_socket 内部——该族 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 内改为 `static s_net_msg_queue`
|
||||
(21 处引用改名),BSP 对该全局变量的裸 `extern` 消失,`netMsgQueueHandle` 现在只出现在生成文件自己的两处。 |
|
||||
| | **两个刻意的设计决定**:① **不新建第二个队列**——那会白占 CCM 堆里 8 × `net_msg_t` 的空间,而 CCM 是当下
|
||||
87.9% 的红线;所以选"创建后绑定"而不是"自建队列 + 删 .ioc 里的队列"(后者还要 CubeMX 重生成,属 Ask-first)。
|
||||
② `adopt()` **拒绝重复绑定并保留首次句柄**——真出现两处绑定时,静默换句柄会让已入队的请求留在旧队列里永不处理,
|
||||
拒掉第二个反而更容易暴露。绑定前的判空是真实防线:丢这一行的后果是"所有 net_* 请求被丢弃、网络全线静默不通",
|
||||
不是崩溃。 |
|
||||
| | **防回退**:`check_cubemx_survival.py` 新增存活项 `net-msgq-adopt`(region `RTOS_QUEUES`,must_contain
|
||||
`net_msg_queue_adopt`),易失清单 **29 → 30 项全部到位**;基线已重建。 |
|
||||
| | **体量**:`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 **不变**。 |
|
||||
| | **验证**:`@build` 0 错 0 警告;`@test` PASS(624 ms 到 `net init: OK`、i104 已监听、无 `[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 钩子里,所以
|
||||
一直没人发现,而 `../测试说明/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 行标 ✅。 |
|
||||
| **2026-10-22** | **S-1 只做「防扩大」那一半:新增 `layer-deps` 分层方向门禁**(推荐清单第 5 步拆分执行,钩子 37 → **38**) | 上一轮的结论是「反转暂缓、门禁现在就该上」,这次照做。
|
||||
为什么门禁比搬迁值钱:AGENTS 与分层图早就写着「六层单向依赖」,可从来没有机械检查——于是同一件事的记载从 2026-09 的
|
||||
「NETCFG 一处」漂到今天的「8 文件 9 处」,全靠人读代码才发现。边界的静默腐蚀只能靠门禁止住。 |
|
||||
|
||||
@@ -245,6 +245,16 @@ CHECKS = [
|
||||
no_baseline=True, # 见下方说明:本文件每次 @build 后被 Keil 改写
|
||||
hint="task_watchdog.c 须挂在 MDK 工程 App 组;CubeMX 重生成可能重建 .uvprojx。",
|
||||
),
|
||||
dict(
|
||||
id="net-msgq-adopt",
|
||||
kind="protected",
|
||||
path="Src/freertos.c",
|
||||
region="RTOS_QUEUES",
|
||||
must_contain=["net_msg_queue_adopt"],
|
||||
hint="消息队列句柄的唯一使用者是 net_socket,创建后必须在 USER CODE BEGIN RTOS_QUEUES 区"
|
||||
"绑定给它(替代此前 BSP 对该全局变量的裸 extern)。丢了这一行,net_socket 的句柄"
|
||||
"恒为 NULL → 所有 net_* 请求被判空丢弃,网络全线静默不通(无崩溃、无报错日志)。",
|
||||
),
|
||||
dict(
|
||||
id="reset-cause-latch",
|
||||
kind="protected",
|
||||
|
||||
@@ -4,4 +4,4 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi
|
||||
2026-10-14 212296 18740 1112 154456 231036 22.0 98144 74.9 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=40960;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;default_task.o=2736;sys_log_mcu.o=1924
|
||||
2026-10-15 213540 18740 1136 131520 232280 22.2 75232 57.4 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;sys_log_mcu.o=3588;default_task.o=2736
|
||||
2026-10-20 213356 18580 1184 131480 231936 22.1 75240 57.4 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;sys_log_mcu.o=3588;default_task.o=2736
|
||||
2026-10-22 213204 18580 1184 131504 231784 22.1 75264 57.4 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;sys_log_mcu.o=3588;default_task.o=2736
|
||||
2026-10-22 213236 18580 1188 131500 231816 22.1 75264 57.4 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;sys_log_mcu.o=3588;default_task.o=2736
|
||||
|
||||
|
@@ -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(未实测)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user