Skip to content

[BUG] #1276

@kzorer

Description

@kzorer

Reopen: Zero‑copy RX driver fails to allocate buffers on STM32H7xxx due to padding logic

Description

When building FreeRTOS+TCP with ipconfigZERO_COPY_RX_DRIVER=1 on STM32H7xxx, pucGetRXBuffer() always returns NULL and triggers the configASSERT() in the zero‑copy path. The failure appears to stem from the way buffers are sliced up in uxNetworkInterfaceAllocateRAMToBuffers():

size_t uxNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
{
    uint8_t * ucRAMBuffer = ucNetworkPackets;
    for( uint32_t ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
    {
        pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
        *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
        ucRAMBuffer += ETH_RX_BUF_SIZE;
    }
    return( ETH_RX_BUF_SIZE - ipBUFFER_PADDING );
}

Because ipBUFFER_PADDING = 8 + ipconfigPACKET_FILLER_SIZE, each descriptor’s “usable” buffer pointer gets offset in a way that, combined with STM32H7 DMA/cache requirements, results in no valid buffers being handed out, so pucGetRXBuffer() always returns NULL.

Note: It appears that this issue affects version 4.2.4 in the LTS release—using the LTS version is broken.

Steps to Reproduce

  1. In FreeRTOSIPConfig.h, set:
#define ipconfigZERO_COPY_RX_DRIVER 1
#define ipconfigPACKET_FILLER_SIZE 2
#define ipconfigBUFFER_PADDING 0
#define ETH_RX_BUF_SIZE 1536
#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS  64
  1. Place the ucNetworkPackets[] buffer array in DTCM or mark SRAM as non‑cacheable via the MPU.
  2. Call FreeRTOS_IPInit(), then generate Ethernet traffic into the STM32H7 MAC.
  3. Observe the assertion:
pucBuffer = pucGetRXBuffer( ETH_RX_BUF_SIZE );
configASSERT( pucBuffer != NULL );  // << fails here

Expected behavior

pucGetRXBuffer() should return a valid pointer to the received Ethernet frame buffer, and the zero‑copy path should hand it off to the HAL without triggering an assertion.

Actual Behavior

pucGetRXBuffer() returns NULL immediately, causing the configASSERT() to fire and preventing any packets from being processed.

Environment

MCU: STM32H7xxx (e.g. STM32H743ZI)
FreeRTOS+TCP: v4.2.4 (LTS release)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions