e_bak wrote on Sunday, April 12, 2015:
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_ZERO_COPY flag is passed to FreeRTOS_sendto() as ulFlags and pucUDPPayloadBuffer as pvBuffer.
FreeRTOS_sendto() 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_ZERO_COPY 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 )