FreeRTOS Network driver zero-copy

Hi All
I am planning to add in my network driver the code, in the receive function, to fallback to memcpy where by default the zero-copy is used. At runtime, the ISR calls the RX function and the driver can decide to do not allocate a new buffer but switching back to memcpy in some circumstances. Do you see any potential issues on such implementation?


Hi peppe,

aside from the obvious (eg don’t even thin about mallocing in an ISR), you’d have to have some infrastructure to decide whether and where the memory must be freed.

Some (Pseudo)code would help to be more precise.

thx for your reply.
The ISR schedules a task and, by default, the RX routine (prvNetworkInterfaceInput) decides to use the zero-copy approach.
In the loop, where the incoming frame are handled inside the ring, the prvNetworkInterfaceInput function should check the uxGetNumberOfFreeNetworkBuffers and if it is lesser than a budget, it fallbacks to memory copy so re-using the current buffer in the in the ring.


It should be okay as you are doing it in a task. Are you seeing any problem? Also, your description probably implies that you will over-write the data in the current buffer if the system is running tight on memory?


I confirm that, it is working fine.


Calling uxGetNumberOfFreeNetworkBuffers() does not guarantee that the next call to pxGetNetworkBufferWithDescriptor() will succeed. Another high-priority task may come in between and allocate all buffers.

What normally happens when reception is “zero-copy” :

  • A packet has been received, an interrupt follows, a task is woken up
  • Call pxGetNetworkBufferWithDescriptor() to replace the buffer in the DMA descriptor
  • If when that fails, leave the buffer in the DMA descriptor, and thus drop the packet
  • If it succeeds, pass the filled buffer to the IP-task

Interrupts are only used to wake-up the task prvEMACHandlerTask() by calling e.g. vTaskNotifyGiveFromISR().

I do not see how you can combine zero-copy behaviour with a plan-B that uses copying. In both cases you will need a new network buffer for each packet that has been received.

Is there any code that you can show?