Dear team,
we do below things:
1.use icssg lwip demo in AM24 based AM243x_mcu_SDK8.4.0.17.
2.delete task sys_thread_new ( "UDP Iperf", start_application, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO );
3.create a UDP send task,code as below,send buf is 1024 byte.
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.Then we found after send a specific count(send 37 times will send failed MEMP_NUM_PBUF=16 ,LWIP_MALLOC_MEMPOOL(20, 1568)),UDP sendto will failed.Just like the send pool is full.
5.so we change lwip stack pool size(send 187 times will send failed MEMP_NUM_PBUF=100 ,LWIP_MALLOC_MEMPOOL(100, 1568)).
6.As i know,one core run one UDP send task,it 's impossible to have above phenomenon.So we use jtag debug,then we found each time UDP sendto process:
Stack will malloc one pbuf by pbuf_alloc() (type is PBUF_RAM(size defined by LWIP_MALLOC_MEMPOOL,number defined by MEMP_NUM_PBUF))
After UDP send,stack will free the pbuf malloced in above step.We found these two address is not same one,and this address is changed to an abnormal pbuf pool(type is PBUF_POOL)address once entering pbuf_free() function(breakpoint is at below).
So after send a certain time cannot send anymore,cause the send pbuf is full.
link.cmd point the pbuf saved in bss(MSRAM),we changed to DDR.Phenomenon is the same one:after a certain time success,send failed,and pbuf address is changed after entering pbuf_free.
Thanks,
jimin.li