fix(vd960DBN): 修复 SocketSend 后重启 — RecvBuf 用错 + 栈溢出
root cause:
1. iot_mqtt_handle_sock_int 的 CONNECT 处理调了
WCHNET_ModifyRecvBuf(_iot_wchnet_buf), 覆盖了 WCHNET 原生的
SocketRecvBuf, 导致后续 SocketSend 时 DMA 访问非法内存 → hard fault
2. uint8_t tmp[RECE_BUF_LEN](1152B) 在中断栈上, 叠加调用链
可能撑爆 2KB 栈
fix:
1. net_srv.c WCHNET_HandleSockInt: 保留 SocketRecvBuf + KeepLive,
其余事件委托给 iot_mqtt_handle_sock_int
2. iot_mqtt_handle_sock_int: 移除 ModifyRecvBuf(已在 wrapper 处理)
3. tmp[1152] 改为 static (移到 BSS, 省 1152B 栈)
This commit is contained in:
@@ -792,13 +792,12 @@ static void iot_connect_broker(void) {
|
|||||||
void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
||||||
if (socketid != g_iot_socket) return;
|
if (socketid != g_iot_socket) return;
|
||||||
|
|
||||||
/* CONNECT 成功 — 仅标记状态,由 poll 延迟发送 CONNECT */
|
/* CONNECT 成功 — 仅标记状态, WCHNET_HandleSockInt 已设好 RecvBuf 和 KeepLive */
|
||||||
if (intstat & SINT_STAT_CONNECT) {
|
if (intstat & SINT_STAT_CONNECT) {
|
||||||
PRINT("IOT: TCP connected (sock=%d)\n", socketid);
|
PRINT("IOT: TCP connected (sock=%d)\n", socketid);
|
||||||
WCHNET_ModifyRecvBuf(socketid, (uint32_t)_iot_wchnet_buf, RECE_BUF_LEN);
|
|
||||||
g_iot_state = IOT_STATE_TCP_CONNECTED;
|
g_iot_state = IOT_STATE_TCP_CONNECTED;
|
||||||
_iot_recv_len = 0;
|
_iot_recv_len = 0;
|
||||||
// 不在此发送 CONNECT,等下一轮 poll 处理
|
// 不在此发送 CONNECT,等下一轮 iot_mqtt_poll 处理
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 收到数据 */
|
/* 收到数据 */
|
||||||
@@ -808,7 +807,7 @@ void iot_mqtt_handle_sock_int(uint8_t socketid, uint8_t intstat) {
|
|||||||
uint16_t space = IOT_MQTT_RECV_BUF_LEN - _iot_recv_len;
|
uint16_t space = IOT_MQTT_RECV_BUF_LEN - _iot_recv_len;
|
||||||
if (recv_len > space) recv_len = space;
|
if (recv_len > space) recv_len = space;
|
||||||
uint32_t rd_len = recv_len;
|
uint32_t rd_len = recv_len;
|
||||||
uint8_t tmp[RECE_BUF_LEN];
|
static uint8_t tmp[RECE_BUF_LEN]; /* static: 1152B 栈分配在中断上下文中会撑爆 2KB 栈 (2026-07-23) */
|
||||||
WCHNET_SocketRecv(socketid, tmp, &rd_len);
|
WCHNET_SocketRecv(socketid, tmp, &rd_len);
|
||||||
memcpy(_iot_recv_buf + _iot_recv_len, tmp, (uint16_t)rd_len);
|
memcpy(_iot_recv_buf + _iot_recv_len, tmp, (uint16_t)rd_len);
|
||||||
_iot_recv_len += (uint16_t)rd_len;
|
_iot_recv_len += (uint16_t)rd_len;
|
||||||
|
|||||||
@@ -581,11 +581,16 @@ uint8_t i;
|
|||||||
// IoT MQTT mode — delegate all socket events to iot_mqtt_srv
|
// IoT MQTT mode — delegate all socket events to iot_mqtt_srv
|
||||||
// (2026-07-23 修复: 旧 mqtt_connect/mqtt_data_manage 与 IoT 栈抢 socket, 致双 CONNECT → broker 踢线 → 频繁 initialize)
|
// (2026-07-23 修复: 旧 mqtt_connect/mqtt_data_manage 与 IoT 栈抢 socket, 致双 CONNECT → broker 踢线 → 频繁 initialize)
|
||||||
if (g_sub_code_enable.iot_enable) {
|
if (g_sub_code_enable.iot_enable) {
|
||||||
#if KEEPLIVE_ENABLE
|
|
||||||
if (intstat & SINT_STAT_CONNECT) {
|
if (intstat & SINT_STAT_CONNECT) {
|
||||||
|
#if KEEPLIVE_ENABLE
|
||||||
WCHNET_SocketSetKeepLive(socketid, ENABLE);
|
WCHNET_SocketSetKeepLive(socketid, ENABLE);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
WCHNET_ModifyRecvBuf(socketid, (uint32_t)SocketRecvBuf[socketid], RECE_BUF_LEN);
|
||||||
|
PRINT("TCP Connect Success (MQTT IoT)\n");
|
||||||
|
}
|
||||||
|
if (intstat & SINT_STAT_DISCONNECT || intstat & SINT_STAT_TIM_OUT) {
|
||||||
|
PRINT("TCP Disconnect/Timeout (MQTT IoT)\n");
|
||||||
|
}
|
||||||
iot_mqtt_handle_sock_int(socketid, intstat);
|
iot_mqtt_handle_sock_int(socketid, intstat);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user