perf(vd960DBN): RAM 瘦身 — .bss 省 4.8KB, 栈 1.9KB→~6.7KB (2026-08-17)

栈溢出根因确认后 .bss 瘦身四刀:
- net_config.h: ETH_MAX_PACKET_SIZE 1520→768 (MSS=700最大帧758B, 省3.76KB)
- iot_mqtt_srv.c: payload[1400]→800 (loop_data最大~604B, 省600B)
- iot_mqtt_srv.h: IOT_MQTT_SEND_BUF_LEN 1024→800 (_iot_send_buf/resp/buf 同步, 省224B)
- net_srv.c: MAX_MQTTBUF_LEN 1024→800 (512仍不够勿回改, 省224B)

⚠ ETH 768 为 MSS=700 最小安全值; 若现场有大UDP包截断改回1024。
待办: .map 确认 BLE 栈占用; RECE_BUF_LEN/ARP 表可再省; 局部大数组转static。
This commit is contained in:
wangfq
2026-08-17 14:10:52 +08:00
parent 26f2326c96
commit 421334ec48
5 changed files with 28 additions and 6 deletions
@@ -22,7 +22,7 @@
#define IOT_MQTT_RECONNECT_MAX_MS 60000 // 最大重连间隔 (指数退避上限) #define IOT_MQTT_RECONNECT_MAX_MS 60000 // 最大重连间隔 (指数退避上限)
#define IOT_MQTT_HEARTBEAT_MS 60000 // 心跳上报周期 (60s) #define IOT_MQTT_HEARTBEAT_MS 60000 // 心跳上报周期 (60s)
#define IOT_MQTT_RECV_BUF_LEN 1024 // 接收缓冲区 (单次交互 ≤1024) #define IOT_MQTT_RECV_BUF_LEN 1024 // 接收缓冲区 (单次交互 ≤1024)
#define IOT_MQTT_SEND_BUF_LEN 1024 // 发送缓冲区 (单次交互 ≤1024) #define IOT_MQTT_SEND_BUF_LEN 800 // 发送缓冲区 (2026-08-17: 1024→800, loop_data~604B+头~30B<800, 省 224B .bss)
#define IOT_MQTT_TOPIC_MAX_LEN 128 // Topic 最大长度 #define IOT_MQTT_TOPIC_MAX_LEN 128 // Topic 最大长度
/*=========================================================================== /*===========================================================================
@@ -47,6 +47,12 @@ extern "C" {
#define ETH_RXBUFNB 4 /* Number of MAC received descriptors */ #define ETH_RXBUFNB 4 /* Number of MAC received descriptors */
/* 2026-08-17 RAM 瘦身: ETH_MAX_PACKET_SIZE 1520 → 768.
最大 TCP 帧 (MSS=700) = 700+20+20+14+4 = 758B ≤ 768 ✓;
停车场景 (TCP JSON/MQTT/SSC UDP 小包) 无 >728B UDP 数据。
省 .bss: (1520-768)×(RX 4 + TX 1) = 3.76KB (栈空间 +3.76KB)。
若现场出现大 UDP 包截断, 改回 1024 (省 2.48KB)。 */
#define ETH_MAX_PACKET_SIZE 768
#ifndef ETH_MAX_PACKET_SIZE #ifndef ETH_MAX_PACKET_SIZE
#define ETH_RX_BUF_SZE 1520 /* MAC receive buffer length, an integer multiple of 4 */ #define ETH_RX_BUF_SZE 1520 /* MAC receive buffer length, an integer multiple of 4 */
#define ETH_TX_BUF_SZE 1520 /* MAC send buffer length, an integer multiple of 4 */ #define ETH_TX_BUF_SZE 1520 /* MAC send buffer length, an integer multiple of 4 */
@@ -855,7 +855,7 @@ void iot_mqtt_publish_sensor(void) {
- 用 iot_mqtt_publish() 代替 mqtt_publish(), 发送缓冲隔离 - 用 iot_mqtt_publish() 代替 mqtt_publish(), 发送缓冲隔离
(event_report→mqttBuf vs loop_data→iot_mqtt_publish::buf[1024]) (event_report→mqttBuf vs loop_data→iot_mqtt_publish::buf[1024])
- coil_count 边界硬限, 防 0xC0 坏帧致溢出 */ - coil_count 边界硬限, 防 0xC0 坏帧致溢出 */
static char payload[1400]; static char payload[800]; /* 2026-08-17: 1400→800, loop_data 最大~604B, 省 600B .bss */
char *p = payload; char *p = payload;
int remaining = sizeof(payload); int remaining = sizeof(payload);
int written; int written;
@@ -65,7 +65,7 @@ uint8_t MyBuf[RECE_BUF_LEN];
#define MAX_TMP_BUF_LEN 64 #define MAX_TMP_BUF_LEN 64
#define MAX_MQTTBUF_LEN 1024 //512: loop_data(4通道)≈604B > 512 → 序列化失败发全零垃圾包被broker RST (2026-07-15) #define MAX_MQTTBUF_LEN 800 // 2026-08-17: 1024→800 (loop_data~604B+头<800; 512仍不够勿改回) 省224B .bss
char mqtt_username[64] = {0}; char mqtt_username[64] = {0};
char mqtt_password[32] = {0}; char mqtt_password[32] = {0};
char mqtt_clientid[64] = {0}; char mqtt_clientid[64] = {0};
+19 -3
View File
@@ -52,11 +52,27 @@ BOOT_CNT:1 @0x2000f84c END:0x2000f834 SP:0x2000ffd0
| `cfig_flash.c` | load_cfg 内 3 处调试 PRINT 注释(magic mismatch ×2 + Sub_Code ×1)——printf 栈峰值是压垮 1.9KB 栈的最后一根稻草 | | `cfig_flash.c` | load_cfg 内 3 处调试 PRINT 注释(magic mismatch ×2 + Sub_Code ×1)——printf 栈峰值是压垮 1.9KB 栈的最后一根稻草 |
| `peripheral_main.c` | load_cfg 恢复(保留配置加载);output_cfg 调用 #if 0(纯调试打印,栈峰值高) | | `peripheral_main.c` | load_cfg 恢复(保留配置加载);output_cfg 调用 #if 0(纯调试打印,栈峰值高) |
### RAM 瘦身(2026-08-17 晚,commit 后述)— .bss ≈46KB → 目标栈 4KB+
实验 D 确认栈溢出根因后,.bss 瘦身四刀(省 ~4.8KB,栈 1.9KB → ~6.7KB):
| 文件 | 项目 | 现状 | 改为 | 省 .bss |
|------|------|------|------|---------|
| net_config.h | ETH_MAX_PACKET_SIZE | 1520 (RX×4+TX=7.6KB) | **768** (MSS=700 最大帧 758B) | **3.76KB** |
| iot_mqtt_srv.c | payload[] | 1400 | **800** (loop_data 最大~604B) | 0.6KB |
| iot_mqtt_srv.h | IOT_MQTT_SEND_BUF_LEN | 1024 | **800** (影响 _iot_send_buf/resp/buf) | 0.22KB |
| net_srv.c | MAX_MQTTBUF_LEN | 1024 | **800** (512 仍不够勿回改) | 0.22KB |
⚠ ETH_MAX_PACKET_SIZE 768 是贴着 MSS=700 的最小值:TCP 帧 758B ✓;
若现场出现 >728B 数据的大 UDP 包会截断,保守可改 1024(省 2.48KB)。
### 遗留(根治) ### 遗留(根治)
- [ ] **减 .bss 给栈腾 4KB+**:需用户提供编译后 .map 确认 46KB 组成(BLE 缓冲/ETH_RX_BUF/iot payload - [ ] **确认 BLE 栈(libwchble.a)实际占用**:需用户提供编译后 .mapobj/*.map 或 MRS Release 目录
BLE 栈若是 20+KB 固定成本,应用层已省 4.8KB 足够; 若可裁剪更好
- [ ] map 确认后可选)RECE_BUF_LEN 1400→1024SocketRecvBuf[3][1400]+MyBuf 省 1.5KB
ARP 表 50→16
- [ ] 局部大数组转 statictcp_json data_json[1024]×2、net_srv resp[600]):省 .bss 有余量后做,栈峰值 -2KB+
- [ ] output_cfg 恢复:减栈后重新启用调试打印 - [ ] output_cfg 恢复:减栈后重新启用调试打印
- [ ] 快照区 3s 延后初始化保留(已确认非根因,作为启动早期 SPI 减压措施无害) - [ ] 快照区 3s 延后初始化保留(已确认非根因,作为启动早期 SPI 减压无害)
- [ ] 示波器 VDD:确认 SPI 擦写瞬间电源裕量(次要,软件栈溢出已确认)
### 验证 ### 验证
- [x] 实验D:跳过 load_cfg/output_cfg → 正常启动(WCHNET/TCP/BLE 全通) - [x] 实验D:跳过 load_cfg/output_cfg → 正常启动(WCHNET/TCP/BLE 全通)