Hello,
I am using FreeRTOS v8.2.1 and I ran into a strange issue in FreeRTOS-Plus-UDP in FreeRTOS_DHCP.c.
Take a look at the “static void prvSendDHCPDiscover( xMACAddress_t *pxMACAddress )” function:
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, pxMACAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, sizeof( ucDHCPDiscoverOptions ) );
iptraceSENDING_DHCP_DISCOVER();
if( FreeRTOS_sendto( xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( xDHCPMessage_t ) + sizeof( ucDHCPDiscoverOptions ) ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
Notice that the FREERTOS
ZEROCOPY flag is passed to FreeRTOS
sendto() as ulFlags and pucUDPPayloadBuffer as pvBuffer.
FreeRTOSsendto() run into the following code:
if( ( ulFlags & FREERTOS_ZERO_COPY ) == 0 )
{
...
else
{
/* When zero copy is used, pvBuffer is a pointer to the
payload of a buffer that has already been obtained from the
stack. Obtain the network buffer pointer from the buffer. */
pucBuffer = ( uint8_t * ) pvBuffer;
pucBuffer -= ( ipBUFFER_PADDING + sizeof( xUDPPacket_t ) );
pxNetworkBuffer = * ( ( xNetworkBufferDescriptor_t ** ) pucBuffer );
}
When FREERTOS
ZEROCOPY is set it sets up the pxNetworkBuffer pointer by reading out a pointer from pvBuffer. But pvBuffer doesn’t contain any pointer to any valid data space, that’s a DHCP message made by prvCreatePartDHCPMessage().
The next lines in FreeRTOS_sendto() causes crash because it writes to “illegal” memory locations (pxNetworkBuffer is initialized with garbage):
if( pxNetworkBuffer != NULL )
{
pxNetworkBuffer->xDataLength = xTotalDataLength;
pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_ADDRESS( pxSocket );
pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;
...
In my case this error is fixed by calling FreeRTOS_sendto() with ulFlags = 0 in prvSendDHCPDiscover().
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, pxMACAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, sizeof( ucDHCPDiscoverOptions ) );
iptraceSENDING_DHCP_DISCOVER();
if( FreeRTOS_sendto( xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( xDHCPMessage_t ) + sizeof( ucDHCPDiscoverOptions ) ), 0, &xAddress, sizeof( xAddress ) ) == 0 )