GD32F450IKH6以太网发数据死机的调试问题,求救
时间:2022-11-07 19:00:00
先说现象:板作为以太网客户端,一直在向服务器上传数据。现在发了一段时间就死了,找不到问题,就要崩溃了。~~~
硬件和逻辑说明:板以太网PHY芯片使用DP基本收发数据,连接服务器,DHCP,借用的官方例程已经调试完毕,现在数据源串口已经获得,两个频率,1Hz和10Hz,我目前的处理步骤是判断串口数据接收一帧后,调用以太网发出函数,
发出步骤如下:
if( rx7_anal_i == 1 ) //UART7接收完成,更新数据包
{
enet_len = rx7_i; //实际数据长度
rx7_anal_i = 0; ///标志位置0启用下次UART7接收
tcp_write(HPST_pcb, data_to_sever1,1458, 1);
err_ENETsend = tcp_output(HPST_pcb);
printf("tcp_output_err_ENETsend=%d\r\n\r\n",err_ENETsend);
RXBuffer7_clear(1460); ///数据源数组清空
}
HPST_pcb:以太网句柄pcb
data_to_sever1:准备发布的数据组初始化长度为1460,实际串口数据收到长度约为1200字节 长。
1458:根据接收数据的总长度,考虑将1460阈值减少两个长度,但实际长度和所有长度相同。
err_ENETsend :tcpoutput判断函数反馈是否成功。
从启动,以太网连接服务器,收集串口数据,开始发送,有时运行一个多小时,最长运行到19小时,我添加了以太网定义的队列缓存,原始默认值标记在注释中 如下:
#define MEM_SIZE (20*1024) /* 堆内存的大小,如果应用程序需要大量的发送
复制数据,应将其设置为高
the size of the heap memory, if the application
will send a lot of data that needs to be copied,
&bsp; this should be set high */
#define MEMP_NUM_PBUF 30 /* 原默认10 memp struct pbufs的数目。如
果应用 程序从ROM(或其他静态内存)发
送大量数据,则应将其设置为高
the number of memp struct pbufs. If the
application sends a lot of data out of ROM (or
other static memory),this should be set high */
#define MEMP_NUM_UDP_PCB 6 /* the number of UDP protocol control blocks, one per active UDP "connection" */
#define MEMP_NUM_TCP_PCB 10 /*模拟活动TCP连接数 the number of simulatenously active TCP connections */
#define MEMP_NUM_TCP_PCB_LISTEN 6 /* 侦听TCP连接数the number of listening TCP connections */
#define MEMP_NUM_TCP_SEG 400 /*默认 12 TCP_SND_QUEUELEN 同时排
队的TCP段数the number of simultaneously queued TCP segments */
#define MEMP_NUM_SYS_TIMEOUT 10 /* 模拟活动超时的数量the number of simulateously active timeouts */
#define MEMP_NUM_NETBUF 8 /*结构netbufs的数量 the number of struct netbufs */
/* Pbuf options */
#define PBUF_POOL_SIZE 30 /*默认 10 pbuf池中的缓冲区数 the number of buffers in the pbuf pool */
#define PBUF_POOL_BUFSIZE 1460 /*默认1500 pbuf池中每个pbuf的大小 the size of each pbuf in the pbuf pool */
/* TCP options */
#define LWIP_TCP 1
#define TCP_TTL 255
#define TCP_QUEUE_OOSEQ 0 /* 控制TCP是否应对无序到达的段进行排
队,如果设备内存不足,则定义为0。
controls if TCP should queue segments that arrive out of order, Define to 0 if your device is low on memory. */
#define TCP_MSS (1500 - 40) /* TCP最大段大小,TCP\U MSS=(以太网
MTU-IP标头大小-TCP标头大小)
TCP Maximum segment size, TCP_MSS = (Ethernet MTU - IP header size - TCP header
size) */
#define TCP_SND_BUF (4*TCP_MSS) /*默认2 TCP发送方缓冲区空间(字节)
TCPsender buffer space (bytes) */
#define TCP_SND_QUEUELEN ((100* TCP_SND_BUF)/TCP_MSS)
/* 默认6 TCP发送方缓冲区空 间(pbufs),
必须至少达到 (2*TCP\u SND\u BUF/TCP\u MSS)才能正常工作
TCP sender buffer space (pbufs), this must be at least
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work */
#define TCP_WND (8*TCP_MSS) /* 默认 2 TCP接收窗口 TCP receive window */
在改了这些后,没效果。然后贴上以太网部分的接收回调函数:红线部分是以太网接收到指令和服务器下发的心跳,
红线处代码:
if(date_sever_mode ==1) //=1进入数据模式
{
if(recev_packet->length > 1)ENETrx_over=1; //接收1包数据完成
/*1.收到心跳后上传反馈信息数组client_to_consever长度1字节*/
if(enet_configsever_buf[0]=='y') //收到心跳‘y’
{
ENET_conXT=0; //心跳计次清0
}
tcp_write(con_up_pcb,client_to_consever,1, 1); //向句柄写入1字节数据
tcp_output(con_up_pcb); //立即发出//ywd+0602
//2.收到指令处理
if( strstr((const char*)enet_configsever_buf,"systemreset") )
{
//重启前向服务器发出挂载点身份信息
tcp_write(con_up_pcb, ntripid,strlen((char *)ntripid), 1); //身份信息
tcp_output(con_up_pcb);
tcp_write(con_up_pcb, "client_reset#",13, 1); //描述语句
tcp_output(con_up_pcb);
NVIC_SystemReset(); // 系统重启
}
}
怀疑接收跟发出有冲突,但接收有释放pbuf_free,想不明白哪里可能会有冲突,在tcp_output函数里看到了这个:
/*First, check if we are invoked by the TCP input processing code. If so, we do not output anything. Instead, we rely on the input processing code to call us when input processing is done with. */
//0621ywd+当输入处理完成时,我们依靠输入处理代码来调用我们。
if (tcp_input_pcb == pcb)
{
return ERR_OK;
}
这里应该能说明接收不会跟发送有冲突才对。然后我打开了调试宏定义 贴上调试log
先是正常运行时后的log:
TCP header:
+-------------------------------+
| 21001 | 8777 | (src port, dest port)
+-------------------------------+
| 0000885513 | (seq no)
+-------------------------------+
| 0000400163 | (ack no)
+-------------------------------+
| 5 | |010000| 64400 | (hdrlen, flags (ACK
), win)
+-------------------------------+
| 0x05a3 | 0 | (chksum, urgp)
+-------------------------------+
+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ACK
-+-+-+-+-+-+-+-+-+-+-+-+-+-+
State: ESTABLISHED
tcp_receive: window update 64400
tcp_receive: congestion avoidance cwnd 35726
tcp_receive: ACK for 400163, unacked->seqno 397363:398763
tcp_receive: removing 397363:398763 from pcb->unacked
tcp_receive: queuelen 4 ... 3 (after freeing unacked)
tcp_receive: removing 398763:400163 from pcb->unacked
tcp_receive: queuelen 3 ... 2 (after freeing unacked)
tcp_output: snd_wnd 64400, cwnd 35726, wnd 35726, effwnd 116, seq 400163, ack 400163
tcp_output: snd_wnd 64400, cwnd 35726, wnd 35726, effwnd 116, seq 400163, ack 400163, i 0
tcp_output_segment: 400163:400279
State: ESTABLISHED
运行异常时的log:
TCP header:
+-------------------------------+
| 10001 | 8778 | (src port, dest port)
+-------------------------------+
| 0905286533 | (seq no)
+-------------------------------+
| 0000006650 | (ack no)
+-------------------------------+
| 5 | |011000| 64216 | (hdrlen, flags (PSH ACK
), win)
+-------------------------------+
| 0xd467 | 0 | (chksum, urgp)
+-------------------------------+
+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags PSH ACK
-+-+-+-+-+-+-+-+-+-+-+-+-+-+
State: ESTABLISHED
tcp_receive: window update 64216
tcp_recved: recveived 1 bytes, wnd 11680 (0).
tcp_write(pcb=2000da2c, data=2001ae84, len=1, apiflags=1)
tcp_write: queuelen: 0
tcp_create_segment: no memory.
tcp_write: 0 (with mem err)
###tcp_write()->ERR_MEM=-1 #####
tcp_output: nothing to send (00000000)
tcp_output: snd_wnd 64216, cwnd 10092, wnd 10092, seg == NULL, ack 6650
State: ESTABLISHED
_state=2
tcp_write(pcb=2000d998, data=200024bc, len=1458, apiflags=1)
tcp_write: queuelen: 6
Assertion "unsent_oversize mismatch (pcb vs. last_unsent)" failed at line 459 in ..\Soft_Drive\lwip-1.4.1\src\core\tcp_out.c
tcp_create_segment: no memory.
tcp_write: 6 (with mem err)
###tcp_write()->ERR_MEM=-1 #####
tcp_output: snd_wnd 64400, cwnd 1400, wnd 1400, effwnd 2858, seq 2133841, ack 2132383
tcp_output_err_ENETsend=0
tcp_fasttmr: delayed ACK
tcp_output: sending ACK for 905286534
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_output: nothing to send (00000000)
tcp_output: snd_wnd 64216, cwnd 10092, wnd 10092, seg == NULL, ack 6650
tcp_slowtmr: processing active pcb
tcp_slowtmr: polling application
tcp_output: snd_wnd 64400, cwnd 1400, wnd 1400, effwnd 2858, seq 2133841, ack 2132383
tcp_write(pcb=2000d998, data=200024bc, len=1458, apiflags=1)
tcp_write: queuelen: 6
Assertion "unsent_oversize mismatch (pcb vs. last_unsent)" failed at line 459 in ..\Soft_Drive\lwip-1.4.1\src\core\tcp_out.c
红色####语句是我自己加的打印:tcp_write函数中有一个调用的另一个检查数据的函数:
err = tcp_write_checks(pcb, len);
这里报的应该是内存的错误,我第一次调以太网,想不明白哪里有问题,希望各位前辈们看到了帮忙看看,我的问题出在哪里?万分感谢,求救~~~