尊敬的团队:
我们做以下事情:
基于 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



