Getting FreeRTOS plus TCP to work

fest wrote on Friday, February 09, 2018:

Hi,

I’m trying to get latest version of FreeRTOS plus TCP to run on my Zynq 7 SoC. Basically I took the provided demo projects and stripped off the parts I don’t need so now I’m left off with a simple application which initializes FreeRTOS TCP stack and creates one task which periodically prints to console just to make sure application is alive.
The problem is that I cannot even ping the board. I’ve enabled ping option in config and I’m using static IP.
Board is 100% working with very old FreeRTOS + lwip stack so hardware is not a problem.
I took a look at some parts of the Zynq port and noticed, for example, that there are slight differences in xemacpsif_physpeed.c between FreeRTOS plus TCP and lwip.
If I use the lwip version of that file, I can print received buffer from emacps_check_rx function which means I do recieve Ethernet frames but then I get Network buffers: XX lowest XX messages also and the XX drops down to zero in about a minute.
If I use original xemacpsif_physpeed.c from FreeRTOS plus TCP, and leave the debug print in emacps_check_rx it never gets printed so it means I don’t recieve any frames.

Can somebody confirm me that latest FreeRTOS plus TCP is actually working on Zynq 7?

Thanks

heinbali01 wrote on Friday, February 09, 2018:

Hi Fest, the Zynq +TCP project has been tested on both a MicroZed and a Zybo board. I even ran +TCP and lwIP simultaneously, using the +TCP Network interface driver.
Actually, the Zynq +TCP port works really well. When tested with iperf3, it showed a high performance.

Note that the latest release of +TCP can be found for instance here

Can you attach the version of ‘xemacpsif_physpeed.c’ that does receive Ethernet packets? I’m curious about the differences.

XX lowest XX messages also and the XX drops down to
zero in about a minute

Every packet received will be passed to the IP-task. It sounds like your IP-task is not running, could that be?
Can you also confirm that where weren’t any complaints or calls to configASSERT() while the system is starting up? Can you check if the IP-task has really started?
Maybe you want to attach your version of FreeRTOSConfig.h and FreeRTOSIPConfig.h ?

fest wrote on Friday, February 09, 2018:

I enabled debug prints and I can’t see anything wrong. Here’s the output with original physpeed file:

Hello world!
vTaskStartScheduler
prvIPTask started
XEmacPs detect_phy: PHY detected at address 7.
XEmacPs detect_phy: PHY detected.
link speed: 1000
Test task created
cnt 0
cnt 1
Network buffers: 64 lowest 64
Network is up!
cnt 2
cnt 3
cnt 4
cnt 5
cnt 6
cnt 7

“cnt” is just my counter that gets printed each second.

I attached the original physpeed file and the one I adapted to match lwip version and also my configuration files.

heinbali01 wrote on Friday, February 09, 2018:

What kind of hardware are you testing with? Is it also a MicroZed?
What PHY is mounted on your board, a Marvell Alaska 88E1512?

fest wrote on Friday, February 09, 2018:

No it’s not a prototype board. It’s custom PCB with Marvell 88E1111.

heinbali01 wrote on Saturday, February 10, 2018:

Maybe you are a lot more experienced with FPGA’s than I am, but still I want to make sure that your Zynq gets the correct set-up.

I’m using the following debug configuration:

  • Initialisation file: ps7_init.tcl
  • Reset entire System
  • Run ps7_init

Without the above procedure, things will only work partly.

Another question: FreeRTOS+TCP will send a gratuitos ARP message every 20 seconds:

#ifndef arpGRATUITOUS_ARP_PERIOD
    #define arpGRATUITOUS_ARP_PERIOD    ( pdMS_TO_TICKS( 20000 ) )
#endif

Have you checked with a program like Wireshark if the packet really gets sent?

It’s custom PCB with Marvell 88E1111.

Do you happen to have a MicroZed or a Zybo board, just to make sure that your application works on that platform?

About your Config files: I didn’t see any significant difference, except that I use:

#define ipconfigNIC_LINKSPEED_AUTODETECT	1

in stead of:

#define ipconfigNIC_LINKSPEED1000			1

fest wrote on Saturday, February 10, 2018:

I solved the problem finally - it was incorrect PHY configuration (obviously, since I’m using different chip) + I had a short code for opening a TCP socket and binding it inside vApplicationIPNetworkEventHook function when event is eNetworkUp. For some reason, creating TCP socket worked but bind call caused IP task to freeze so recieved frames weren’t processed. That’s why I was getting messages about network buffers getting used up.
When I moved socket related code to a separate task and just signaled it from vApplicationIPNetworkEventHook (in addition to using modified physpeed.c file), it started working.
I’m not sure why would this happen - it would be ok if bind function returned some error but it just froze. In any case, I hope my experiences here will be helpful for someone in future.

heinbali01 wrote on Saturday, February 10, 2018:

Thank you for reporting this.

Application hooks like vApplicationIPNetworkEventHook() often have a risk: they are called from a different task. The same for vApplicationIdleHook() (called form the idle task), and vApplicationTickHook() (called from an ISR, the FreeRTOS clock-tick interrupt).

In this case you were calling a +TCP API from the IP-task. I also made this mistake some day. What I did is just set a variable from within vApplicationIPNetworkEventHook().

it would be ok if bind function returned some error but it just froze

I will see if the API can just fail and return some appropriate error.

I hope my experiences here will be helpful for someone in futur

You helped me remind about this trap, thanks.