perf(vd960DBN): OTA RAM 优化 — union 复用块缓冲 + 命令分支数组改 static

MRS 编译 RAM 90.02% (44248/48KB) 逼近历史 .bss 挤栈红线, 减负:
- ota_srv.c: _chunk_buf[256] + _fs_frame[254] 合并为 union (下载/校验与刷写帧
  互斥复用, 省 ~260B static); ota_send_9f 组帧直接用 union 缓冲 (省 254B 栈)
- iot_mqtt_srv.c: 6 个 ota_* 分支 resp[256~400] + ota_data hexbuf[513] 局部栈
  数组改 static (栈峰值 → BSS, 防运行时栈溢出; RAM 总量不变但运行时安全)

验证: gcc 隔离单测 9/9 全过; 语法 0 新增错误
This commit is contained in:
wangfq
2026-08-20 13:41:33 +08:00
parent 49736c341c
commit 0b51d84a9b
2 changed files with 28 additions and 27 deletions
@@ -46,9 +46,11 @@ static uint32_t _fs_block_crc; /* 当前块 CRC (调试/审计) */
uint8_t g_ota_flash_active = 0; /* 本地刷写进行中 → uart_srv 把 ACK 交给 ota_srv */
/* 块缓冲 (static: 栈紧张教训) */
static uint8_t _chunk_buf[OTA_CHUNK_SIZE]; /* 下载片缓冲 */
static uint8_t _fs_frame[5 + OTA_FLASH_BLOCK + 1]; /* A7 帧: 9F+SubL+SubH+LEN+CMD+DATA+CHECK */
/* 块缓冲 (static: 栈紧张教训; union: 下载片 256B 与 A7 帧 254B 互斥复用, 省 ~260B RAM) */
static union {
uint8_t chunk[OTA_CHUNK_SIZE]; /* 下载片缓冲 / 校验读缓冲 */
uint8_t frame[5 + OTA_FLASH_BLOCK + 1]; /* A7 帧: 9F+SubL+SubH+LEN+CMD+DATA+CHECK */
} _ota_buf;
/*===========================================================================
* CRC-32/ISO-HDLC (协议 §4.19.1; 逐位实现, 零查表 RAM)
@@ -275,15 +277,15 @@ int ota_cmd_data(uint32_t offset, uint32_t crc32, const char *hex)
clen = _meta.size - offset;
if (clen > OTA_CHUNK_SIZE) clen = OTA_CHUNK_SIZE;
if (ota_hex_decode(hex, _chunk_buf, clen) != 0) {
if (ota_hex_decode(hex, _ota_buf.chunk, clen) != 0) {
return 1; /* hex 格式错误 */
}
if (ota_crc32(_chunk_buf, clen) != crc32) {
if (ota_crc32(_ota_buf.chunk, clen) != crc32) {
return 1; /* 单片 CRC 失败 */
}
/* 落盘: SPI_Flash_Write 自带"目标区非 0xFF 则读-改-写擦扇区" (256B 页对齐) */
SPI_Flash_Write(_chunk_buf, _slot_base + offset, (uint16_t)clen);
SPI_Flash_Write(_ota_buf.chunk, _slot_base + offset, (uint16_t)clen);
_meta.received = offset + clen;
ota_meta_flush();
PRINT("OTA: data@%lu crc_ok received=%lu\n",
@@ -313,8 +315,8 @@ int ota_cmd_end(uint32_t crc32)
while (i < _meta.size) {
uint32_t n = _meta.size - i;
if (n > OTA_CHUNK_SIZE) n = OTA_CHUNK_SIZE;
SPI_Flash_Read(_chunk_buf, _slot_base + i, (uint16_t)n);
total = ota_crc32_update(total, _chunk_buf, n);
SPI_Flash_Read(_ota_buf.chunk, _slot_base + i, (uint16_t)n);
total = ota_crc32_update(total, _ota_buf.chunk, n);
i += n;
}
total ^= 0xFFFFFFFFu;
@@ -407,18 +409,17 @@ int ota_cmd_flash(uint8_t slot, uint8_t force)
static void ota_send_9f(uint8_t sub_l, uint8_t sub_h, uint8_t cmd,
const uint8_t *data, uint16_t datalen)
{
uint8_t frame[5 + OTA_FLASH_BLOCK + 1];
uint16_t i;
uint8_t sum = 0;
frame[0] = 0x9F;
frame[1] = sub_l;
frame[2] = sub_h;
frame[3] = (uint8_t)(1 + datalen); /* LEN 含 CMD */
frame[4] = cmd;
if (data && datalen) memcpy(&frame[5], data, datalen);
for (i = 1; i < 5 + datalen; i++) sum += frame[i]; /* SubL..DATA */
frame[5 + datalen] = sum;
UART2_SendString(frame, (uint16_t)(5 + datalen + 1));
_ota_buf.frame[0] = 0x9F;
_ota_buf.frame[1] = sub_l;
_ota_buf.frame[2] = sub_h;
_ota_buf.frame[3] = (uint8_t)(1 + datalen); /* LEN 含 CMD */
_ota_buf.frame[4] = cmd;
if (data && datalen) memcpy(&_ota_buf.frame[5], data, datalen);
for (i = 1; i < 5 + datalen; i++) sum += _ota_buf.frame[i]; /* SubL..DATA */
_ota_buf.frame[5 + datalen] = sum;
UART2_SendString(_ota_buf.frame, (uint16_t)(5 + datalen + 1));
}
/* 刷写失败收尾: 状态落盘 + event_report 告警 + 恢复 0x7F 模式 */
@@ -566,9 +567,9 @@ void ota_poll(void)
uint32_t read_off = _fs_sent;
uint32_t remain = _meta.size - read_off;
uint16_t datalen = (remain > OTA_FLASH_BLOCK) ? OTA_FLASH_BLOCK : (uint16_t)remain;
SPI_Flash_Read(_fs_frame + 5, _slot_base + read_off, datalen);
SPI_Flash_Read(_ota_buf.frame + 5, _slot_base + read_off, datalen);
ota_send_9f((uint8_t)(_fs_sub & 0xFF), (uint8_t)(_fs_sub >> 8), 0xA7,
_fs_frame + 5, datalen);
_ota_buf.frame + 5, datalen);
_fs = OTA_FLASH_WAIT_ACK;
_fs_start_ms = now;
PRINT("OTA: sent A7 sub=%u off=%lu datalen=%u\n",