FreeRTOS+TCP in AMD/Xilinx Vitis 2024

What is the correct way to use FreeRTOS and FreeRTOS+TCP in a AMD/Xilinx Vivado/Vitis 2024 (Unified IDE) project?
As far as I can tell the FreeRTOS+TCP ports don’t work with Vitis’ new SDT approach of communicating HW meta data.
What am I supposed to do about this?

@LinkwitzRiley

We recently had a community contribution as part of PR1227 updating the Xilinx network interface with the new SDT changes, and it is merged to the FreeRTOS+TCP latest main branch on Github.

The author has tested the changes in the PR for FreeRTOS+TCP Xilinx port with new drivers on Vitis 2024.2

1 Like

@tony-josi-aws

Thanks, that’s great news!
However, now I struggle getting Vitis to find the includes:
I’m getting FreeRTOSConfig.h has not been included yet in FreeRTOSIPConfigDefaults.h, probably because of include order. But no matter what I do, I can’t get rid of it.

@LinkwitzRiley

I’m getting FreeRTOSConfig.h has not been included yet in FreeRTOSIPConfigDefaults.h

Compilation of which source file (.c) is leading to that error in FreeRTOSIPConfigDefaults.h?

FreeRTOS.h should always be the first FreeRTOS related header file included in the source files and then FreeRTOS_IP.h. Check if that’s the case in any application source/include files that include FreeRTOSIPConfigDefaults.h.

You can also take a look at this page for folder structure information.

I think the error happens before actual compilation.
I think the #error directive in FreeRTOSIPConfigDefaults.h gets triggered.

I believe this error is reported when you are building the app_component. Did you try a clean build after changing the include order?

If that doesn’t work, try commenting out the #error line that’s causing the error and then build it to see if you are getting any other errors. This error might be a side effect of some other errors.

I am endeed facing multiple errors.
Resolving one by one now.

One of them is that XPAR_PS7_ETHERNET_0_DEVICE_ID is not defined - pxZynq_FillInterfaceDescriptor needs this. What can I do about this?

Do you have a xparameters.h file?

I believe XPAR_PS7_ETHERNET_0_DEVICE_ID should be defined in xparameters.h.

This used to be in xparameters.h but the new SDT-based flow in Vivado/Vitis 2024 doesn’t define device IDs anymore.

In that case I would suggest reaching out to AMD/Xilinx forums/mailing lists since it’s outside the scope of FreeRTOS.

Is it really?
This is not a build error, this is how Vitis with SDT works
This leaves FreeRTOS+TCP unusable in Vivado/Vitis 2024.
Is this really outside of the scope of FreeRTOS?

The latest main branch of FreeRTOS+TCP with PR1227 merged has been confirmed by the author to be tested on Vitis 2024.2.

Whether XPAR_PS7_ETHERNET_0_DEVICE_ID has to be set or XPAR_PS7_ETHERNET_1_DEVICE_ID has to be set depends on your peripheral availability in your hardware reference design, and it cannot be set universally from the FreeRTOS+TCP. Hence, if your xparameters.h is lacking those definitions, it needs to be checked with Xilinx/AMD or their documentations on why is that happening provided that those are user configurations.

According to AMD/Xilinx DEVICE_ID macros are never defined in Vitis2024.
This is not happening on error!

This is not happening on error!

Have you verified that the SDT macro is visible/defined to the FreeRTOS+TCP network interface files in your IDE?

I just verfied it by adding

#ifdef SDT
#error "SDT is defined"
#else
#error "SDT Is NOT defined"
#endif

to FreeRTOS-Plus-TCP/source/portable/NetworkInterface/Zynq/NetworkInterface.cand getting the error “SDT is defined”

The only location in FreeRTOS+TCP where XPAR_PS7_ETHERNET_0_DEVICE_ID is used is here: FreeRTOS-Plus-TCP/source/portable/NetworkInterface/Zynq/NetworkInterface.c at main · FreeRTOS/FreeRTOS-Plus-TCP · GitHub when SDT is not defined.

One of them is that XPAR_PS7_ETHERNET_0_DEVICE_ID is not defined - pxZynq_FillInterfaceDescriptor needs this. What can I do about this?

Are you using XPAR_PS7_ETHERNET_0_DEVICE_ID in the function call to pxZynq_FillInterfaceDescriptor?

Yes, exactly - I use it as

pxZynq_FillInterfaceDescriptor(XPAR_PS7_ETHERNET_0_DEVICE_ID, &networkInterface);

Unless you are using multiple ethernet interfaces on Zynq I believe setting the xEMACIndex argument of pxZynq_FillInterfaceDescriptor to zero or previously defined value of XPAR_PS7_ETHERNET_0_DEVICE_ID should work.

I only need multiple IP endpoints on one ethernet interface.

Of course I can just set it to whatever worked in Vivado SDK 2019, I guess, but it’s not pretty.

Actually I’ve just seen that there is a comment in NetworkInterface.c to not use the pxZynq_FillInterfaceDescriptor directly but that it’s called in FreeRTOS_IPInit() (but it is called in the legacy code I am working on).

Do you know anything about that?

xEMACIndex of <interface>_FillInterfaceDescriptor API is used to uniquely index the MAC interface and its configs; its API signature is similar for the network interfaces, not just Zynq, since with SDT as the device ID, macros are not there anymore; you will need to set the xEMACIndex as the MAC interface of Zynq that you have configured (with Vivado if used)/planned to use. It needs to be checked with Xilinx/AMD on if it’s possible to get a similar zero-indexed interface ID that the user has configured using Vivado if you think manually specifying the device ID is not pretty.

Actually I’ve just seen that there is a comment in NetworkInterface.c to not use the pxZynq_FillInterfaceDescriptor directly but that it’s called in FreeRTOS_IPInit() (but it is called in the legacy code I am working on)

The comment is specifying to not use pxFillInterfaceDescriptor directly, not the pxZynq_FillInterfaceDescriptor. With V4.0.0 and above of FreeRTOS+TCP, it’s needed to explicitly call the interface-specific <interface>_FillInterfaceDescriptor APIs before the FreeRTOS_IPInit_Multi is called, as multiple interfaces are supported with newer versions starting from V4.0.0. pxFillInterfaceDescriptor is there for backward compatibility where only one interface is allowed, and in that case the FreeRTOS_IPInit will internally call it with xEMACIndex fixed to 0.