Simple TCP Echo server – does not respond to ping

Hello, This is my first post on forum so first of all I want to say “Thank You” for the great job that you are doing with the FreeRTOS operating system. I started to use it due to the available features and excellent documentation provided. I have a problem with server implementation from SimpleTCPEchoServer.c – in few words, does not respond to ping (and also arp) requests but even so at each 30 seconds it sends a “Gratuitos ARP” over the network. Here are the details: FreeRTOS v9.0 FreeRTOS Plus TCP version 160919 Custom hardware based on ARM Cortex M7 (Atmel ATSAME70Q21) LogiLink USB to Ethernet adapter connected to PC – IP address 192.168.0.3 No DHCP (static IP – 192.168.0.2) No DNS The initial software application contained FreeRTOS (without TCP/ IP Stack) and Atmel’s Ethernet driver. This version responded to arp and ping requests thus I can exclude any hardware or network configuration issues. Then I added +TCP and the SimpleTCPEchoServer.c but no answers from board. What can be wrong? Regards, Andrei

Simple TCP Echo server – does not respond to ping

The first thing to do will be to make sure the MAC is receiving interrupts for incoming packets, then if it is, follow the packet’s path into the the stack to see how far it gets. First though, I’m curious about the following from your post:
The initial software application contained FreeRTOS (without TCP/ IP Stack) and Atmel’s Ethernet driver. This version responded to arp and ping requests thus I can exclude any hardware or network configuration issues.
If it didn’t contain the TCP/IP stack, but did respond to ARP and Ping, what was responding to ARP and Ping. Was there a different stack in use that you removed? Or is there something in the hardware itself responding?

Simple TCP Echo server – does not respond to ping

And in addition to Richards questions: Sometimes the simplest things are the most complex. As far as I know we never provided a +TCP driver for ATSAME70Q21. Where did you get your driver? There may be many causes. Like Richard asks, do you ever get a DMA reception (RX) interrupt? Did you allow for broadcast messages in your EMAC?

Simple TCP Echo server – does not respond to ping

Yes, MAC is receiving interrupts for incoming packets so I will have to check the path. Atmel provided a mini TCP/ IP Stack capable to respond to ARP and Ping requests in order to test their MAC driver implementation. This mini TCP/ IP Stack and Ethernet drivers were implemented by Atmel for ATSAM4E and KSZ8051. I updated the code to properly function with custom hardware build around ATSAM7EQ21 uC and KSZ8041TL Ethernet driver -> board responded to ARP and Ping requests (continuously tested for few hours without failures). Broadcast messages are allowed by EMAC. FreeRTOSIPInit() called before starting the scheduler; prvIPTask priority = 3 IPHook function -> network up -> create server task with priority = 1

Simple TCP Echo server – does not respond to ping

Hi Andrei, I’m afraid I can’t help you much more on this. Do you see that it attempts to send packets back? If not, you’ll really have to follow the entire path from reception to answering. I’m not familiar with the mini IP-stack developed by Atmel. FreeRTOS has FreeRTOS+TCP, which has a driver and demo project for SAM4E. Unfortunately I don’t have a ATSAM7EQ21 for testing.

Simple TCP Echo server – does not respond to ping

Hello Hein, I think I was not so clear in explanations. Currently I am using the FreeRTOS+TCP with driver and demo project based on SAM4E but with some small updates necessary for ATSAME70Q21. The mini TCP/ IP Stack provided by Atmel I initially use it just to test the EMAC driver, network configuration and possible hardware issues. After being confident that all things were well functioning I replaced the mini TCP/ IP Stack with FreeRTOS+TCP. Now comes my problem because the board does not respond to ARP and Ping requests. It seems that TCP/ IP packets are not sent to IP Task due to pxNextNetworkBufferDescriptor which is NULL (prvEMACRxPoll function). Please have a look below.
    if( pxNextNetworkBufferDescriptor != NULL )
    {
        /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
        pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
    }
** else { /* As long as pxNextNetworkBufferDescriptor is NULL, the incoming messages will be flushed and ignored. */ pucUseBuffer = NULL; }** I am trying to figure out why this is happening.

Simple TCP Echo server – does not respond to ping

Which buffer allocation file are you using? BufferAllocation1.c or BufferAllocation2.c?

Simple TCP Echo server – does not respond to ping

the board does not respond to ARP and Ping requests
Before being able to PING, an ARP request must be sent and answered. So let’s focus at the ARP requests. Do you see ARP requests arrive at your device? If not, did you allow for broadcast addresses? If ARP requests do arrive, do you see that xNetworkInterfaceOutput() gets called? Do you see an answer to the ARP request on the LAN, when looking with Wireshark? If you do not see an answer, has the DMA been initialised well? Did you start the peripheral clock for DMA? Did you enable RX and TX? Were all descriptors well initialised? If pxNextNetworkBufferDescriptor equals to NULL, that would mean that some Network Buffers do not get released. You’re running out of Network Buffers. Would you mind showing the adapted NetworkInterface.c ? You might also attach a PCAP if you want, when trying out an ARP / PING. Regards.

Simple TCP Echo server – does not respond to ping

I am using BufferAllocation_2.c For an ARP request I don’t see any network transfer with Wireshark but in debug mode if I store data received into a buffer (gsuceth_buffer) I can see the received packet, please see .png image and Wireshark capture. For Ping request please see Wireshark capture named “Ping request.pcapng”. xNetworkInterfaceOutput () gets called For all the other questions the answers are affirmative.

Simple TCP Echo server – does not respond to ping

… and in attachment it is the updated NetworkInterface.c source code

Simple TCP Echo server – does not respond to ping

Hi Ion Andrei, Your PCAP called “ARP request.pcapng” looks strange: It shows 32 so-called gratuitous ARP requests, which are sent within less than a ms. The IP-stack will send these ‘gratuitous ARP requests’ regularly but not that often. The requests help other devices to keep ARP tables up-to-date, and also to help the detection of double IP-addresses. Within “PING request.pcapng”, I see three gratuitous ARP requests, sent at an acceptable frequency of two per minute. The ping command (e.g. ping 192.168.0.2) will always start with an ARP command. In you PCAP, the ARP commando isn’t answered by the device. As the device is sending gratuitous ARP requests, I would conclude that its RX path isn’t working properly.

Simple TCP Echo server – does not respond to ping

Hello Hein, Related to ARP requests – after some time (dozens of seconds) the “gratuitos ARP requests” are sent at much lower frequency as you pointed out. I’m fully agree that issue is on Rx path. Please have a look at first image with an ethernet frame received stored in gsuceth_buffer. All data bytes seems to be correctly received (e.g. ethernet header, …) but aren’t sent further to IP Task because all time pxNextNetworkBufferDescriptor == NULL and ~~~ As long as pxNextNetworkBufferDescriptor is NULL, the incoming messages will be flushed and ignored. pucUseBuffer = NULL; ~~~ ~~~
It seems that TCP/ IP packets are not sent to IP Task due to pxNextNetworkBufferDescriptor which is NULL (prvEMACRxPoll function). Please have a look below.
if( pxNextNetworkBufferDescriptor != NULL )
{
    /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
    pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
}
> > else { / As long as pxNextNetworkBufferDescriptor is NULL, the incoming messages will be flushed and ignored. / pucUseBuffer = NULL; } ~~~
Please give me some hints about why pxNextNetworkBufferDescriptor equals NULL. What could be the reason for this? Thanks you. Regards, Andrei

Simple TCP Echo server – does not respond to ping

Hello, It’s been a while since I have worked at this project and now it’s comming back with high priority therefore I will have to fix somehow the ethernet communication bug. I think I know the reason for board not responding to ARP request but I do not know how to fix it. It seems that Ethernet packet is wrong interpreted due to pxEthernetHeader which is pointing to a wrong address – instead of 0x20406938 is pointing to 0x2040693A. Having this 2 bytes offset error leads to not correctly identify the ethernet type (instead of 0x0608 is seen 0x0100) so the switch will always execute the default case (release buffer) and not the ARP case. Please see the attachment. Please let me know from where this offset is comming. What to check? Thank you. (All TCP structures are packed in code so there is not any padded byte) MAC destination address – 00:04:25:1C:A0:02 MAC source address – 00:60:6E:43:61:FB Regards, Andrei ~~~ static void prvProcessEthernetPacket( NetworkBufferDescriptort * const pxNetworkBuffer ) { EthernetHeadert pxEthernetHeader; volatile eFrameProcessingResult_t eReturned; / Volatile to prevent complier warnings when ipCONSIDERFRAMEFOR_PROCESSING just sets it to eProcessBuffer. */
configASSERT( pxNetworkBuffer );

/* Interpret the Ethernet frame. */
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );

if( eReturned == eProcessBuffer )
{
    /* Interpret the received Ethernet packet. */
    **switch( pxEthernetHeader->usFrameType )**
    {
        case ipARP_FRAME_TYPE :
            /* The Ethernet frame contains an ARP packet. */
            eReturned = eARPProcessPacket( ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
            break;

        case ipIPv4_FRAME_TYPE :
            /* The Ethernet frame contains an IP packet. */
            eReturned = prvProcessIPPacket( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
            break;

        **default :
            /* No other packet types are handled.  Nothing to do. */
            eReturned = eReleaseBuffer;
            break;**
    }
}
~~~

Simple TCP Echo server – does not respond to ping

Hi Andrei, it looks like you have correctly defined ipconfigPACKET_FILLER_SIZE in your FreeRTOSIPConfig.h as follows:
#define ipconfigPACKET_FILLER_SIZE   2
See a discussion about this padding here: FreeRTOSTCP – zero copy – ipBUFFERPADDING This means that any Ethernet packet (pxDescriptor->pucEthernetBuffer) will start at a (32-bit) aligned offset plus 2. The reason for this is that almost all 32-bit values in the IP and TCP/UDP packets will become 32-bit aligned. But your CPU peripheral must know that you want packets to be written at a +2 byte offset. This is done by setting: ~~~ GMAC Network Configuration Register: GMAC_NCFGR
● RXBUFO: Receive Buffer Offset
Indicates the number of bytes by which the received data is
offset from the start of the receive buffer.
~~~ You could set the offset like this: ~~~ gmacsetconfig(pgmac, ( gmacgetconfig(pgmac) & ~GMACNCFGRRXBUFOMsk ) | GMACNCFGRRFCS | /* Remove FCS, frame check sequence (last 4 bytes) */ GMACNCFGRPEN | /* Pause Enable */ GMACNCFGRRXBUFO( ipconfigPACKETFILLERSIZE ) | /* Set Ethernet Offset */ GMACRXD_RXCOEN ); /* RXCOEN related function */ ~~~ For transmitting packets there should not be a problem: the contents of pucEthernetBuffer will be sent, which is already aligned with an offset of 2 bytes. Please let me know if this helps. Hein

Simple TCP Echo server – does not respond to ping

PS. I just ordered an evaluation board ATSAME70-XPLD so I can help testing the driver. Until now I could only test the SAM4E. I am working on a “unified” driver that works both on SAM4E, as well as on SAME70.

Simple TCP Echo server – does not respond to ping

Hello Hein, Thank you very much for the support. UnfortunatelIy I can update the code and test it only Monday when for sure that I will post the test result. I just wait to do it. Best regards, Andrei

Simple TCP Echo server – does not respond to ping

Hello Hein, I just tested and it seems the issue is now fixed so the ethernet frame is right processed. Now I have another issue on transmit path in Atmel’s GMAC driver, gmac_dev_write() function, so the answer is not sent back (test using ARP command) because there are no free trasmit descriptors and function will always return GMAC_TX_BUSY. ~~~ /* Pointers to the current transmit descriptor */ p_tx_td = &p_gmac_queue->p_tx_dscr[p_gmac_queue->us_tx_head];
/* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
if (CIRC_SPACE(p_gmac_queue->us_tx_head, p_gmac_queue->us_tx_tail,
                p_gmac_queue->us_tx_list_size) == 0) {
    if (p_tx_td[p_gmac_queue->us_tx_head].status.val & GMAC_TXD_USED)
    **  return GMAC_TX_BUSY;**
}
~~~ Please give me some hints about what I can do. Best regards, Andrei

Simple TCP Echo server – does not respond to ping

I fixed the “no free tx descriptor” issue. The number of Tx buffers was defined in FreeRTOSIPConfig.h by constant GMAC_TX_BUFFERS with default value of 2. It seems that it was not enough so I increased it to 4 (empirical value and not computed) now having 4 Tx buffers each of 1518 bytes length. ~~~ /* Number of DMA buffer used by the driver for TX. */

define GMACTXBUFFERS 4 /* 4 * 1518 = 6072 bytes -> ~6kB */

~~~ I still do not understand why 2 buffers were not enough but for the moment it is a good thing that I have an ATSAME70Q21 custom board running FreeRTOS + TCPIP. Best regards, Andrei

Simple TCP Echo server – does not respond to ping

I still do not understand why 2 buffers were not enough but for the moment
I suppose that your driver uses zero-copy for sending? If you need 4 TX buffers, it means that your CPU ( ATSAME70 ) is pretty fast. What happens if xNetworkInterfaceOutput() finds that all DMA buffers are occupied? Doesn’t it wait a few uS? It would be worth blocking on a ( counting ) semaphore. Like I mentioned here above, I am waiting for a ATSAME70 evaluation board.

Simple TCP Echo server – does not respond to ping

Driver copies the buffer to one of the GMAC Tx buffers so it does not use zero-copy for sending. The function is that one provided by Atmel and I have not modified it. Below is the function prototype. ~~~ /** * brief Send ulLength bytes from pcFrom. This copies the buffer to one of the * GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready. * If lEndOfFrame is true then the data being copied is the end of the frame * and the frame can be transmitted. * * param pgmacdev Pointer to the GMAC device instance. * param pbuffer Pointer to the data buffer. * param ulsize Length of the frame. * param functxcb Transmit callback function. * * return Length sent. / uint32_t gmac_dev_write(gmac_device_t pgmacdev, gmacquelistt queueidx, void *pbuffer, uint32t ulsize, gmacdevtxcbt functxcb) ~~~

Simple TCP Echo server – does not respond to ping

CPU’s operating frequency is 300 MHz.

Simple TCP Echo server – does not respond to ping

In that case it is indeed possible that 4 TX buffers are occupied at the same time. I did write a zero-copy driver ( at the transmission site ), but I’m waiting for a SAME70 board to test it.

Simple TCP Echo server – does not respond to ping

Hi Andrei, do you have the driver already working? I finally have a SAME70 Xplained board here for testing. What I found is that the driver must set dummy descriptors in the priority queues, even if you do not use them: ~~~ +COMPILERALIGNED(8) + static gmactxdescriptort gstxdesc_null;
 /* Set transmit buffer queue */
 gmac_set_tx_queue(p_hw, (uint32_t) p_td);
+ gmacsettxpriorityqueue(phw, (uint32t)&gstxdescnull, GMACQUE1); + gmacsettxpriorityqueue(phw, (uint32t)&gstxdescnull, GMACQUE2); ~~~ Otherwise the DMA transmission unit finds an invalid TX descriptor at address 0x00.

Simple TCP Echo server – does not respond to ping

Hello Hein, Yes, the driver is working since you gave me the solution – set Rx Buffer Offset to 2. Thanks again! Dummy descriptors in the priority queues were set (the difference is that first I am setting GMACQUE2 and then GMACQUE1 but this should not be an issue) .

Simple TCP Echo server – does not respond to ping

Andrei, I will try to bring out a unified version of the +TCP driver, which will work for bot SAM4E, and SAME70. The transmission will be zero-copy. The reception can not be made zero-copy for +FAT, as it uses small fixed-size RX buffers. Right now I’m fighting with the SAME70 TC (Timer Counter), which is only 16-bits. I want to cascade two of them in order to get a 32-bit performance timer.

Simple TCP Echo server – does not respond to ping

Hello Hein, Did you implemented the unified version? I am just curious. Please be aware that are some differences between ATSAME70Q21 (Rev. A mounted on Xplained board) and new ATSAME70Q21B (Rev. B). That last revision (B) does fix some silicon bugs which affects GMAC queues therefore the code is not a drop-in replacement and must be updated. Differences between the 2 revisions can be found here: http://ww1.microchip.com/downloads/en/DeviceDoc/80000767A.PDF Hope it helps. Best Regards, Andrei