@aggarg@tony-josi-aws
This is the MAC Address I’m using in both LWIP and in FreeRTOS + TCP static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x0a, 0x35, 0x00, 0x01, 0x02 };
In LWIP I’m able to ping w/ no issues
I have three devices on my network:
IP 10.100.100.151 (i.e. 0xa646497) - Raspberry Pi
IP 10.100.100.140 (i.e. 0xa6464a0) - Windows 10 machine
IP 10.100.100.160 (i.e. 0xa64648c) - Zynq
Here’s my console output when starting the Zynq application:
FreeRTOS_AddEndPoint: MAC: 01-02 IPv4: a6464a0ip prvIPTask started XEmacPs detect_phy: PHY detected at address 0. Start PHY autonegotiation Waiting for PHY to complete autonegotiation. autonegotiation complete link speed: 1000 prvEMACHandlerTask[ 0 ] started running Network buffers: 28 lowest 28 END POINT created vApplicationIPNetworkEventHook_Multi Network buffers: 28 lowest 27
Here’s the console output when I ping from Rpi:
pxEasyFit: ARP a646497ip → a6464a0ip ipARP_REQUEST from a646497ip to a6464a0ip end-point a6464a0ip
Note, that on the Rpi I do not see the ping replies.
Here’s the console output when I ping from Windows:
Network buffers: 27 lowest 26 pxEasyFit: ARP a6464a0ip → a64648cip ipARP_REPLY from a64648cip to a6464a0ip end-point a6464a0ip pxEasyFit: ARP a64648cip → a6464a0ip ipARP_REQUEST from a64648cip to a6464a0ip end-point a6464a0ip
On Windows I do see ping replies
Here’s the console output when I ping from Windows a second time: pxEasyFit: ARP a64648cip → a6464a0ip ipARP_REQUEST from a64648cip to a6464a0ip end-point a6464a0ip
Here’s the console output when I ping from Rpi a second time: pxEasyFit: ARP a646497ip → a6464a0ip ipARP_REQUEST from a646497ip to a6464a0ip end-point a6464a0ip
Does the ping work from Windows after you tried pinging from RPi, and have you verified that the PRi has a different MAC address compared to Zynq?
Can you share your ARP configurations, for example:
/* The ARP cache is a table that maps IP addresses to MAC addresses. The IP
* stack can only send a UDP message to a remove IP address if it knowns the MAC
* address associated with the IP address, or the MAC address of the router used to
* contact the remote IP address. When a UDP message is received from a remote IP
* address the MAC address and IP address are added to the ARP cache. When a UDP
* message is sent to a remote IP address that does not already appear in the ARP
* cache then the UDP message is replaced by a ARP message that solicits the
* required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum
* number of entries that can exist in the ARP table at any one time. */
#define ipconfigARP_CACHE_ENTRIES 6
/* ARP requests that do not result in an ARP response will be re-transmitted a
* maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is
* aborted. */
#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
/* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP
* table being created or refreshed and the entry being removed because it is stale.
* New ARP requests are sent for ARP cache entries that are nearing their maximum
* age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is
* equal to 1500 seconds (or 25 minutes). */
#define ipconfigMAX_ARP_AGE 150
@tony-josi-aws
After attempting a ping from the Rpi (which doesn’t work)
I can then attempt a ping from Windows which does work.
I’ve confirmed that the MAC address is different on the Zynq.
I’ve also hooked up a Linux Mint laptop to the network and it has the same issue trying to ping the Zynq.
Here are my ARP settings from my FreeRTOSIPConfig.h file:
Also, I’m not using DNS. I’m only using static IP addresses.
In my example I set static const uint8_t ucDNSServerAddress[ 4 ] = { 208, 67, 222, 222 };
Not sure if that’s an issue?
I am attaching two packet captures from the Linux laptop to the Zynq (10.100.100.153 to 10.100.100.160) as well as one packet capture from the Windows machine to the Zynq (10.100.100.140 to 10.100.100.160).
I also included a packet capture from the linux laptop to the Raspberry pi (10.100.100.153 to 10.100.100.151).
At the end of the day I’m trying to create a TCP server and client.
Next thing I may try is going for TCP server and client between windows and zynq to see if that works. But if the ping doesn’t work, it makes me thing other things may be wrong. pcaps.zip (89.0 KB)
Thank you for sharing these packet captures. I looked at these and I do not see anything obviously wrong. Can you put a breakpoint in Network interface input path on Zynq and see if the Ping request from the laptop ever reaches the device?
I looks like all the pings from Windows result in xResult = 1 (see breakPoint1 link above).
However, when pings from Linux are sent xResult is sometimes 1, sometimes 0.
For the times that xResult = 1 from Linux
I would pause at breaPoint2 and after two or three seconds resume the operation of the application and a ping reply would sometimes get registered on the Linux machine.
However, a majority would not come back. Below I show a portion of the console output from the Linux machine (Raspberry Pi)
user@rpi151:~ $ ping 10.100.100.160
PING 10.100.100.160 (10.100.100.160) 56(84) bytes of data.
From 10.100.100.151 icmp_seq=13 Destination Host Unreachable
From 10.100.100.151 icmp_seq=14 Destination Host Unreachable
64 bytes from 10.100.100.160: icmp_seq=39 ttl=64 time=3399 ms
From 10.100.100.151 icmp_seq=60 Destination Host Unreachable
From 10.100.100.151 icmp_seq=70 Destination Host Unreachable
64 bytes from 10.100.100.160: icmp_seq=90 ttl=64 time=5614 ms
From 10.100.100.151 icmp_seq=106 Destination Host Unreachable
ping: sendmsg: No route to host
From 10.100.100.151 icmp_seq=107 Destination Host Unreachable
From 10.100.100.151 icmp_seq=108 Destination Host Unreachable
@aggarg . I got caught up with other tasks, and and am now coming back to this task.
I think we may be getting too much into the weeds so to speak.
Before going down this path, can we take a look at my FreeRTOSIPConfig.h file?
I originally got a FreeRTOSIPConfig.h file from here.
I am have attached my modified file to this reply at the bottom.
You can find the few modifications I made by searching the term “SDOG”.
In order to get the project to compile for Zynq I had to add a few extra things that were missing.
For ipconfigNIC_N_TX_DESC and ipconfigNIC_N_RX_DESC I was not able to find any documentation about appropriate values to put in here so I just put 32.
Do you know what values I should be using?
Could you take a look through the attached FreeRTOSIPConfig.h file to see if anything sticks out and may be a potential culprit?
Thanks for reporting back. It seems like incoming ping request packets are dropped somewhere in this code. It will be great if you could verify if that’s what’s happening there by putting breakpoints in those return pdFALSE; statements.
The ipconfigNIC_N_RX_DESC and ipconfigNIC_N_TX_DESC define the number of DMA descriptors for reception and transmission. As @aggarg suggested, those values look good. You can even lower them if you wish to save memory if your core is running faster to keep up with the rate of packet transmissions. Note that ideally the total number of network buffers, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS should be greater than the total number of TX and RX DMA descriptors.
Thanks for sharing the finding. Saw that the endian correction is performed twice for fragment offset bit mask in the Zynq network interface packet filtering function [ipFRAGMENT_OFFSET_BIT_MASK is already defined to be matching as per the endian requirement based on the ipconfigBYTE_ORDER, it doesn’t need FreeRTOS_ntohs again]. Can you please apply the following patch and test?:
--- a/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+++ b/source/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
@@ -439,7 +439,7 @@ BaseType_t xMayAcceptPacket( uint8_t * pucEthernetBuffer )
/* Ensure that the incoming packet is not fragmented (only outgoing packets
* can be fragmented) as these are the only handled IP frames currently. */
- if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
+ if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
{
return pdFALSE;
}