Zynq-7000 FreeRTOS FPU context / IRQ handling with LWIP

I observed sporadic TCP payload corruption on a Zynq-7000 XC7Z020 running FreeRTOS and lwIP 2.2.0 with a hard-float build. The application source buffer was always correct, but in reproduced failures the data was already corrupted immediately after the normal lwIP memcpy into the TCP pbuf.

I use Vivado/Vitis 2025.2.

The linked memcpy uses VFP registers. I found that configUSE_TASK_FPU_SUPPORT was set to 0x1 and that the BSP provided a strong vApplicationIRQHandler(), which bypassed the FreeRTOS FPU-safe IRQ wrapper. To fix this, I changed the FreeRTOS BSP setting to FPU_SUPPORT = 0x2 and modified portZynq7000.c by renaming the BSP dispatcher from vApplicationIRQHandler() to vApplicationFPUSafeIRQHandler().

The final ELF then uses the FreeRTOS IRQ wrapper and saves/restores FPSCR and d0-d31 around interrupt dispatch. With the original optimized memcpy and D-cache enabled, 100,000 Ethernet datasets completed without corruption.

Could you confirm whether both changes are actually required for a hard-float Zynq-7000 FreeRTOS application? In particular, is modifying portZynq7000.c the intended solution, or is there an AMD-supported BSP setting or newer implementation that avoids changing the generated FreeRTOS port source

Your description sounds like this issue: Interrupt unsafety in XEmacPs_GetQxOffset() · Issue #374 · Xilinx/embeddedsw · GitHub

Xilinx accidentally introduced code which uses FPU (memcpy) in their interrupts, so thats why you needed to use vApplicationFPUSafeIRQHandler. The workaround is to modify their code so that memcpy is not used in the interrupt.