This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2434: icssg lwip demo in one UDP send cycle, the pbuf address malloced when entering UDP send has been changed after SYS_ARCH_PROTECT in the end of UDP send

Part Number: AM2434

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(1001568)).

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

  • Hi Jimin,

    we have started looking into the issue, let me check and get back.

  • Hi Jimin Li,

    A few questions, if you answer, would help me understand the problem a bit better.

    Q1. Are you using netconn_send() and netconn_free() functions from sockets.c?. The 'buf' passed in netconn_send() and netconn_free() is of type PBUF_POOL or PBUF_RAM?


    Q2. Are you using the udp_sendto_if_src_chksum() function from udp.c? The 'p' (pbuf) used here is of type PBUF_RAM, which is freed again in the same function.

    Regards,

    Shaunak

  • Dear Shaunak Deshpande,

    Q1: Yes,we use netconn_send() and netconn_free() functions from sockets.c.

    Buf  passed in netconn_send() is PBUF_RAM as netbuf_alloc() point, but in netconn_free() is changed(we check this buf in pbuf_free() function) to PBUF_POOL.

    Q2:Yes,we use the udp_sendto_if_src_chksum() function from udp.c.

     

    Thanks,

    jimin.li

  • Hi Jimin,

    I would like to understand the exact functionality that you are trying to achieve or implement with using both Netconn APIs as well as the udp.c 's APIs

    TI does not recommend the use of Netconn APIs. 

    I would also recommend using the enet_cpsw_udpclient example for a UDP ping pong example.

    BR,

    Shaunak

  • Dear Shaunak Deshpande,

    We have found the reason is the other one (PC)connected with  AM243(customer board base AM2434-evm )is always sending UDP pack(type is PBUF_POOL) to AM24,so my previous discription is incorrectable.

    Buf  passed in netconn_send() is PBUF_RAM as netbuf_alloc() point, but in netconn_free() is changed(we check this buf in pbuf_free() function) to PBUF_POOL.

    But, stop UDP send on  PC side,AM24 still send a certain time then send failed. 

    Then,we do two things:

    1.use AM24-LP run this demo:

    Can send success without "send a certain time then send failed" phenomenon.

    In one send process, the pbuf malloced by netbuf_alloc() before send is the same one as netconn_free() after send.

    2.use customer board(base AM2434-evm) run this demo:

    Still has "send a certain time then send failed" phenomenon.

    In one send process,the pbuf malloced by netbuf_alloc() before send is the same one as netconn_free() after send.

    Do you have any ideas?

    Thanks,

    jimin.li 

  • Hi Jimin Li,

    The behavior should be the same in case of AM243x-LP and AM243x-EVM for the out-of-box example. To help me further analyze and reproduce this issue on my end, can you please share the zip file of your example (MCU_SDK/examples/networking/lwip/enet_lwip_icssg)?

    Also, when you tested the above with UDP Send disabled on the PC side, the PBUFS are getting saved in MSRAM or DDR (for AM243x-EVM)? (Since in your original question, you mentioned you changed it to DDR).

    Thanks,

    Shaunak

  • Dear Shaunak Deshpande,

    sorry for late update cause we OOO for a week.

    enet_lwip_icssg.rar

    we config lwip icssg dual mac mode by ourself as customer req,so SDK has been changed a lot.Below code may be helpful.

    networking.rar

    We save PBUFS in MSRAM now.For debug we also try saved them in DDR and found no matter saved in MSRAM or DDR the phenomenon is the same one.

    Also, when you tested the above with UDP Send disabled on the PC side, the PBUFS are getting saved in MSRAM or DDR (for AM243x-EVM)? (Since in your original question, you mentioned you changed it to DDR).

    Besides, if config total num is 10 in this pool (LWIP_MALLOC_MEMPOOL(10, 1568)).Our customer board show all PBUFs be used then send failed cause stack cannot  alloc a new PBUF. But on AM243-LP board ,after send 5 times,the PBUFs will be free and reuesd in next send cycle.

    Thanks,

    jimin.li

  • Hi Jimin,

    Could you re-check the example.rar file that you have shared, seems like some files are missing which is blocking me from building your example locally (example.syscfg for am243x-evm).

    Regards,

    Shaunak

  • Dear Shaunak Deshpande,

    rar file is all for example.The syscfg file has been removed in our customer board.

    Now we can run UDP send test (packet length is 1024Byte)successfully on our customer board.But the project is in debug mode. If use release mode, after send a specific count(send 37 times will send failed MEMP_NUM_PBUF=16 ,LWIP_MALLOC_MEMPOOL(20, 1568)),UDP sendto will failed.

    Besides,if packet length is 20Byte,no matter project mode is debug or release,there is no send failed phenomenon.show details as below picture:

    It confued me by above conclusion on debug and release conditions.

    thanks,

    jimin.li 

  • Dear Jimin.Li,

    I see you have changed the enet-lld in sdk a lot for dual mac on ICSSG. This feature is not supported on our 8.4SDK. Dual mac on ICSSG is supported on 8.6 SDK which will be available within next 2 weeks on ti.com. It would be better if you can move to 8.6 SDK and use the dual mac feature.

    I have verified the out of box enet_lwip_icssg example on 8.4SDK. I have added a similar udp server task as yours (shown below) and tested if the am243x is sending out udp packets continuously or not on SDK 8.4.0.17. (this is written inside the enet_lwip_icssg example in place of udp_iperf). The task waits for the first packet to receive and sends the packet back continuously until timeout. 

    I do not see any issues here, I tried with both 20 byte and 1024 byte, packets are getting sent by the am243x DUT continuously. Attached are the screenshots on wireshark where 10.24.69.20 is the ip address of am243x and I am receiving the packets continuously (more than 10k packets)on both release and debug modes. 

    #define UTILS_ALIGN(x,align)  ((((x) + ((align) - 1))/(align)) * (align))
    void udp_task_0 ( void* arg )
    {
        err_t err;
        int sock;
        struct sockaddr_in socketAddr;
        struct timeval tv;
        char recv_buf[UTILS_ALIGN(UDP_RECV_BUFSIZE, 32)] __attribute__ ((aligned(32)));
        struct sockaddr_in from = { 0 };
        socklen_t fromlen = sizeof(from);
        int32_t count;
        int32_t sendnum;
        uint64_t timestart = 0;
        uint64_t timeelapse = 0;
    
        memset(&socketAddr, 0, sizeof(socketAddr));
        socketAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        socketAddr.sin_family = AF_INET;
        socketAddr.sin_port = htons(10255);
        if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        {
            DebugP_log("UDP server: Error creating Socket\r\r\n");
            return;
        }
    
        tv.tv_sec = 0;
        tv.tv_usec = 30000;
        err = setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, ( void* ) &tv, sizeof ( tv ) );
        if (err != ERR_OK)
        {
            DebugP_log ( "socket fail to setsockopt\r\n");
            lwip_close ( sock );
            sock = -1;
        }
        err = bind (sock, (struct sockaddr*) &socketAddr, sizeof (socketAddr));;
        if (err != ERR_OK)
        {
            DebugP_log("UDP server: Error on bind: %d\r\r\n", err);
            close(sock);
            return;
        }
        while (1)
        {
            count = lwip_recvfrom(sock, recv_buf, UDP_RECV_BUFSIZE, 0, (struct sockaddr*) &from, &fromlen);
            if (count <= 0)
                continue;
    
            DebugP_log("Packet recieved \r\n\r");
            count = (count >= UDP_RECV_BUFSIZE) ? UDP_RECV_BUFSIZE - 1 : count;
            recv_buf[count] = '\0';
            /*CacheP_wbInv(recv_buf, sizeof(recv_buf), CacheP_TYPE_ALLD);*/
            DebugP_log("Client: %s\r\n", recv_buf);
            timeelapse = 0U;
            timestart = ClockP_getTimeUsec();
            while( timeelapse < (60*1000000) )
            {
                sendnum = sendto(sock, recv_buf, count, 0, (struct sockaddr*) &from, fromlen);
                if (sendnum != count)
                {
                    DebugP_log("Error in write\r\n\r");
                }
                else
                {
                    DebugP_log("Echo pkt completed\r\n\r");
                }
                timeelapse = ClockP_getTimeUsec()-timestart;
                DebugP_log("timeelapsed to send %d \r\n\r", timeelapse);
            }
            ClockP_sleep(2);
        }
    }
    




    Thanks,

    Susheel.