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.

TMS320F28388D: TCP Client running on F2838xD CM cannot connect to a server

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE

Hi,

I am creating a TCP driver based on lwIP 2.1.2 shipped in C2000Ware 2.00.00.02. I am able to succesfully create a TCP Server on the target and connect it to a TCP Client running on my PC using Hercules utility.

However, I am unable to create a connection when the target is configured as a TCP Client and I run a TCP Server on Hercules.

I logged the messages over Ethernet connetion in Wireshark and saw that the target initially sends a SYN command correctly.

In response the server running on my PC, sends a SYN+ACK command but that is not acknowledged by the client and hence the three-way handshake is not completed.

Following is my setup when the target is in Client mode:

pcb = tcp_new();
err = tcp_bind(pcb, IP_ADDR_ANY, LocalIPPort);

GetIPAddressOctets(RemoteIPAddress,IPOctets);//Get the Remote IP Address Octets
IP4_ADDR(&ipaddr_send, IPOctets[0], IPOctets[1], IPOctets[2], IPOctets[3]);//Create IP Address from Octets 
// listen for connections
ret_val = tcp_connect(pcb, &ipaddr_send, ServerPort, client_connected); //server port for incoming connection
if(ret_val !=ERR_OK)
{
// Assign a NULL pointer as error in building connection 
pcb = NULL; 
}

As I said before, the target sends the initial SYN command correctly through "tcp_connect" and so the "ret_val" in the above code is ERR_OK.

I am attaching the screenshots from Hercules and WireShark.

Any help as to why this is happening would be really helpful.

Thanks,

Manan

  • Hi Manan, 

    The LWIP has been tested only with the the Webserver application, hence running the TCP client has not been tested. It's good to know that you are bringing up a TCP Client based application. Thanks for the details of the setup.

    When I hit such issues, I first look at lwip_stats variable on the target(Expressions window) and look at the link,ip,tcp level stats to see at which layer the packet is not passed up/responded to. At the Ethernet driver level it is  good to check the following watch variables:

    Ethernet_rxInterruptCount

    Ethernet_txInterruptCount 

    Before you call the tcp_connect and after the tcp_connect (after the retries in wireshark), it is good to see the statistics. You can also check the Ethernet statistics registers using the register view or CCS memory window. 

    This will throw some light on where the issue lies. 

    Just curious to know what are you trying to achieve by running both TCP client/server on the target. what is your end product/use case with Ethernet. 

    Regards,

    Sudharsanan

  • Hi Sudharsanan,

    Thanks for your quick reply.

    Based on your inputs, I captured the stats at three points:

    1) Just before tcp_connect: No Tx/Rx at this point, just an ARP message in queue probably.

    2) After "stepping over" tcp_connect in debugger: TCP SYN command is enqueued but not yet sent.

    3) After giving free run: SYN command is sent on TCP layer and the ARP messages are exchanged. Other than these, no messages are received on TCP or even at IP layer, even though Wireshark shows that the server tried to send SYN+ACK command multiple times.

    I am using the "f2838xif.c" file in "ports/C2000/netif" as my interface.

    Also, Ethernet module initialization is borrowed from the webserver example, configuring the following callbacks:

    pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallbackCustom;
    pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
    pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBufferCustom;

    Could there be a problem with the way receive callback is configured and the reason why lwip stack is unable to receive TCP messages from my PC?

    As to your question about my use case, I am trying to create a TCP driver for this board to be used by our customers, to configure the Ethernet module as TCP client/server as per their requirements.

  • Hi Manan,

    Thanks for the additional information. It looks like the SYN packets are not received at even at the driver level.

    1.can you confirm if the MAC Destination address of the ARP and the SYN packet are the same?

    2. Is the destination address matching the address programmed in register MAC_Address0_low and high(0x400c0300, 0x400c0304)?

    3. What is the register value of MAC_Packet_Filter Register(0x400c0008)?

    4. Is the Rx Statistics (0x400c0780 - 0x400c0800) showing any change after you see the SYN packets on Wireshark?

    Regards,

    Sudharsanan

  • Hi Sudharsanan,

    Thanks a lot for your insights.

    With the help of "Rx Statistics" registers, I was able to narrow down the source of the issue. The received packets were all being discarded and the "Rx_FIFO_Overflow_Packets Register" was being incremented with every try.

    I also found the reason as to why the Rx FIFO was overflowing. Here is a little background to the problem in my original question:

    During initialization of GPIO pins for Ethernet, powering down GPIO 108 is required to enable the external PHY chip.

    As soon as I do this, it triggers lot of traffic on the network (which I have captured in the WireShark window below). This traffic goes on for quite some time (6-8 seconds) and if I execute the "tcp_connect" command before this stream of traffic ends, I do not get a response from my PC.

    To clarify, if I give a free run to my code, this traffic starts on the network, somewhere in between "tcp_connect" is executed and I see a SYN command from the target to my PC. But my server does not respond with a SYN+ACK in this case.

    So to work around this issue, I was manually putting a breakpoint before "tcp_connect", waiting for this traffic to end and then giving a free run to my code. In this case, my PC was responding with a SYN+ACK and the target was not acknowledging it as mentioned in my original question.

    The problem as I found out today was that I was waiting too long at the breakpoint before "tcp_connect", which results in my server sending a lot of ARP messages and since the target is halted in debugger, it cannot respond and clear the Rx FIFO. Hence the overflowing of the buffer.

    As of now I have found a very inefficient way to make it work, by waiting just the right amount of time between setting GPIO 108 and execution of "tcp_connect". So now I execute "tcp_connect" after the stream of traffic ends but before Rx FIFO is bombarded by other incoming messages.

    I used "SysCtl_delay(350000000)" just after setting GPIO configuration for Ethernet. With this, I am able to connect my target client to the server in my PC.

    However, I am not sure as to why enabling the PHY chip triggers this traffic on the network, where is this originating from and how to deal with this. Because waiting for 8-10 seconds for this stream of traffic to finish is super ineffective. Just to clarify, there is nothing else connected in this network, just the target to my PC.

    Would you have any idea as to why this is happening or how to avoid it? Here is the capture from WireShark for the messages on the network after setting GPIO 108:

  • Hi Manan,

    Thanks for the additional details. Good to see that you nailed down further.

    What is application run sequence between cores? Are you doing this using JTAG? 

    We suggest this way 

    1. Load CPU1

    2. Run CPU1

    3. Connect CM

    4. Load CM

    5. Run CM 

    Do you run your sequence using JTAG? or have an automated way of running this standalone without JTAG.

    In your end configuration is it not okay to have this 6 second delay at startup at CPU1? It happens only once at Power ON right?

    I have not observed that stream of traffic since I typically would have taken that 5-6 seconds between my CPU1 Run and JTAG load/run. 

    Regards,

    Sudharsanan

     

  • Hi Sudharsanan,

    Yes, I am following the boot sequence you mentioned. I have an automated way of doing this through a JavaScript file.

    As you said, the delay happens only once during the initialization code and I will see if I can optimize the delay and make it a little bit better in case it is a necessity.

    I was just not sure whether this traffic and the resulting delay was a design flaw in my application or a bug from TI or expected behavior.

    So, I just wanted to check if there was any better solution to this as providing this delay seems quite ineffective and unreliable, especially for real-time applications (considering "SysCtl_delay" does not guarantee a fixed delay).

    My above question still remains if this behavior is expected, an application design flaw or a bug?

    But in case, there is nothing else you can add at this point of time, I can close this thread. You can update later if you get a definitive answer to this.

    Thanks a lot for your help.

    - Manan