尊敬的团队:
我们做以下事情:
基于 AM24的 AM243x_MCU_SDK8.4.0.17中的1.use icssg lwip 演示。
2.delete task sys_threade_new ("UDP Iperf"、start_application、NULL、DEFAULT_THREAD_STACKSIZE、 DEFAULT_THREAD_PRIO);
3.创建 UDP 发送任务,代码如下,发送 buf 为1024字节。
static void udp_task ( void* arg ) { int ret, sockfd = -1; int udp_port = 10250; const int reuse = 1; struct sockaddr_in rmt_addr, bod_addr; uint32_t id = *( uint32_t* )arg; DebugP_log ( "id=%u\r\n",id ); u32_t len = sizeof ( rmt_addr ); int i; ip_addr_t ipaddr,ipaddr1; ssize_t recvnum=0; ssize_t sendnum=0; int32_t status; uint32_t cnt = 0; uint16_t count = 1024; uint32_t sendcnt = 0; uint32_t recvcnt = 0; uint64_t timestart = 0; uint64_t timeelapse = 0; uint64_t time = 0,time1 = 0; uint32_t val; struct timeval tv; IP4_ADDR ( &ipaddr, 192, 168, 2, 100 ); IP4_ADDR ( &ipaddr1, 192, 168, 2, 220 ); /* set up address to connect to */ rmt_addr.sin_family = AF_INET; rmt_addr.sin_port = htons ( udp_port ); rmt_addr.sin_addr.s_addr = ipaddr.addr; bod_addr.sin_family = AF_INET; bod_addr.sin_port = htons ( udp_port ); bod_addr.sin_addr.s_addr = ipaddr1.addr;//htons ( INADDR_ANY ); //while ( 1 ) { do { net_is_linked=get_enet_link(id); ClockP_usleep ( 100000 ); } while ( !net_is_linked ); DebugP_log ( "is linked\r\n" ); /* create the socket */ sockfd = socket ( AF_INET, SOCK_DGRAM, 0 ); if ( sockfd < 0 ) { DebugP_log ( "fail to create sockopt\r\n" ); } tv.tv_sec = 0; tv.tv_usec = 30000; ret = setsockopt ( sockfd, SOL_SOCKET, SO_RCVTIMEO, ( void* ) &tv, sizeof ( tv ) ); if ( ret < 0 ) { DebugP_log ( "fail to setsockopt\r\n" ); lwip_close ( sockfd ); sockfd = -1; //continue; //return ERROR; } ret = bind ( sockfd, ( struct sockaddr* ) &bod_addr, sizeof ( bod_addr ) ); if ( ret < 0 ) { lwip_close ( sockfd ); sockfd = -1; DebugP_log ( "fail to bind sockopt\r\n" ); } send_buf[0] = id; send_buf[1] = cnt%256; for ( i=2; i<count-1; i++ ) { send_buf[i]=i&0xff; } send_buf[count-1]=0x5A; timestart = ClockP_getTimeUsec(); /* reveive packets from rmt_addr, and limit a reception to MAX_BUF_SIZE bytes */ //recvnum = recvfrom ( sockfd, buf, MAX_BUF_SIZE, 0, ( struct sockaddr* ) &rmt_addr, &len ); while (( -1 != sockfd && net_is_linked ) && ( timeelapse < (60*1000000) )) { /* send packets to rmt_addr */ sendnum=sendto ( sockfd, send_buf, sizeof (send_buf), 0, ( struct sockaddr* ) &rmt_addr, len ); if(sendnum == sizeof (send_buf)) { // DebugP_log ( " sendbuf[0]-sendbuf[4] %d %d %d %d %d \r\n",send_buf[0],send_buf[1],send_buf[2],send_buf[3],send_buf[4]); sendcnt++; send_buf[1] = sendcnt%256; } else DebugP_log ( "ERROR: send count %d sendnum != sizeof ( buf ),no need to recv\r\n",sendcnt); timeelapse = ClockP_getTimeUsec()-timestart; } DebugP_log ( "total cycle %d,sendcount %d,recvcount %d\r\n",cnt,sendcnt,recvcnt); DebugP_log ( "1min UDP pingpong test end \r\n"); lwip_close ( sockfd ); } }
4.然后我们在发送特定 计数后发现(发送37次将发送失败的 MEMP_NUM_PBUF=16、LWIP_malloc_MEMPOOL(20、1568 ))、UDP sendto 将失败。就像发送池已满一样。
5.因此我们更改了 lwip 栈池大小(发送 187 次将发送失败的 MEMP_NUM_PBUF=100、LWIP_malloc_MEMPOOL (100、 1568))。
6、我知道一个内核运行一个 UDP 发送任务、不可能有上述现象、所以我们用 JTAG 调试、每次 UDP 发送处理之后我们都发现:
堆栈将 malloc 1个 pbuf by pbuf_alloc (类型为 PBUF_RAM (大小由 LWIP_malloc_MEMPOOL 定义、数字由 MEMP_NUM_PBUF 定义))
UDP 发送后,堆栈将释放 上面步骤中分配的 pbuf 地址。我们发现这两个地址不是同一个,并且 在输入 pbuf_free() 函数()断点后,这个地址就变成了一个异常的 pbuf 池(类型是 PBUF_POOL )地址。
因此、在发送特定的时间后无法再发送、导致发送 pbuf 已满。
link.cmd :pbuf 保存在 BSS (MSRAM)中、我们更改为 ddr.现象是相同的、在一定的时间成功后、发送失败、并且 pbuf 地址在 输入 pbuf_free 后更改。
谢谢。
jimin.li