/* Called by FreeRTOS+UDP when a reply is received to an outgoing ping request. */ void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier ) { static const char *pcSuccess = "\r\n\r\nPing reply received - "; static const char *pcInvalidChecksum = "\r\n\r\nPing reply received with invalid checksum - "; static const char *pcInvalidData = "\r\n\r\nPing reply received with invalid data - "; static char cMessage[ 50 ]; void vOutputString( const char * const pcMessage ); switch( eStatus ) { case eSuccess : vOutputString( pcSuccess ); break; case eInvalidChecksum : vOutputString( pcInvalidChecksum ); break; case eInvalidData : vOutputString( pcInvalidData ); break; default : /* It is not possible to get here as all enums have their own case. */ break; } sprintf( cMessage, "identifier %d\r\n\r\n", ( int ) usIdentifier ); vOutputString( cMessage ); }
static void prvSimpleZeroCopyServerTask( void *pvParameters ) { int32_t lBytes; uint8_t *pucUDPPayloadBuffer; struct freertos_sockaddr xClient, xBindAddress; uint32_t xClientLength = sizeof( xClient ), ulIPAddress; xSocket_t xListeningSocket; /* Just to prevent compiler warnings. */ ( void ) pvParameters; /* Attempt to open the socket. */ xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); /* This test receives data sent from a different port on the same IP address. Obtain the nodes IP address. Configure the freertos_sockaddr structure with the address being bound to. The strange casting is to try and remove compiler warnings on 32 bit machines. Note that this task is only created after the network is up, so the IP address is valid here. */ FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL ); xBindAddress.sin_addr = ulIPAddress; xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); /* Bind the socket to the port that the client task will send to. */ FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); for( ;; ) { /* Receive data on the socket. ulFlags has the zero copy bit set (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the received data should be passed out to this task using the second parameter to the FreeRTOS_recvfrom() call. When this is done the IP stack is no longer responsible for releasing the buffer, and the task *must* return the buffer to the stack when it is no longer needed. By default the block time is portMAX_DELAY. */ lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength ); /* It is expected to receive one more byte than the string length as the NULL terminator is also transmitted. */ configASSERT( lBytes == ( ( portBASE_TYPE ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) ); /* Print the received characters. */ if( lBytes > 0 ) { vOutputString( ( char * ) pucUDPPayloadBuffer ); } if( lBytes >= 0 ) { /* The buffer *must* be freed once it is no longer needed. */ FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer ); } } }
static void prvSimpleServerTask( void *pvParameters ) { long lBytes; uint8_t cReceivedString[ 60 ]; struct freertos_sockaddr xClient, xBindAddress; uint32_t xClientLength = sizeof( xClient ); xSocket_t xListeningSocket; /* Just to prevent compiler warnings. */ ( void ) pvParameters; /* Attempt to open the socket. */ xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET ); /* This test receives data sent from a different port on the same IP address. Configure the freertos_sockaddr structure with the address being bound to. The strange casting is to try and remove compiler warnings on 32 bit machines. Note that this task is only created after the network is up, so the IP address is valid here. */ xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL; xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port ); /* Bind the socket to the port that the client task will send to. */ FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) ); for( ;; ) { /* Zero out the receive array so there is NULL at the end of the string when it is printed out. */ memset( cReceivedString, 0x00, sizeof( cReceivedString ) ); /* Receive data on the socket. ulFlags is zero, so the zero copy option is not set and the received data is copied into the buffer pointed to by cReceivedString. By default the block time is portMAX_DELAY. xClientLength is not actually used by FreeRTOS_recvfrom(), but is set appropriately in case future versions do use it. */ lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength ); /* Print the received characters. */ if( lBytes > 0 ) { vOutputString( ( char * ) cReceivedString ); } /* Error check. */ configASSERT( lBytes == ( portBASE_TYPE ) strlen( ( const char * ) cReceivedString ) ); } }
static void prvCreatedTask( void *pvParameters ) { int32_t lParameterValue; static uint8_t pucLocalBuffer[ 60 ]; void vOutputString( const uint8_t * const pucMessage ); /* Cast the parameter to an appropriate type. */ lParameterValue = ( int32_t ) pvParameters; memset( ( void * ) pucLocalBuffer, 0x00, sizeof( pucLocalBuffer ) ); sprintf( ( char * ) pucLocalBuffer, "Created task running. Received parameter %d\r\n\r\n", ( long ) lParameterValue ); vOutputString( pucLocalBuffer ); for( ;; ) { vTaskDelay( portMAX_DELAY ); } }
/* Called by FreeRTOS+UDP when the network connects. */ void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent ) { uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress; int8_t cBuffer[ 16 ]; static portBASE_TYPE xTasksAlreadyCreated = pdFALSE; if( eNetworkEvent == eNetworkUp ) { /* Create the tasks that use the IP stack if they have not already been created. */ if( xTasksAlreadyCreated == pdFALSE ) { #if( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 ) { /* Create tasks that demonstrate sending and receiving in both standard and zero copy mode. */ vStartSimpleUDPClientServerTasks( mainSIMPLE_CLIENT_SERVER_TASK_STACK_SIZE, mainSIMPLE_CLIENT_SERVER_PORT, mainSIMPLE_CLIENT_SERVER_TASK_PRIORITY ); } #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */ #if( mainCREATE_SELECT_UDP_SERVER_TASKS == 1 ) { /* Create tasks that demonstrate sending and receiving in both standard and zero copy mode. */ vStartSelectUDPServerTasks( mainSELECT_SERVER_TASK_STACK_SIZE, mainSELECT_SERVER_PORT, mainSELECT_SERVER_TASK_PRIORITY ); } #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */ #if( mainCREATE_UDP_ECHO_TASKS == 1 ) { /* Create the tasks that transmit to and receive from a standard echo server (see the web documentation for this port) in both standard and zero copy mode. */ vStartEchoClientTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY ); } #endif /* mainCREATE_UDP_ECHO_TASKS */ #if( mainCREATE_UDP_CLI_TASKS == 1 ) { /* Create the task that handles the CLI on a UDP port. The port number is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */ vStartUDPCommandInterpreterTask( mainUDP_CLI_TASK_STACK_SIZE, mainUDP_CLI_PORT_NUMBER, mainUDP_CLI_TASK_PRIORITY ); } #endif /* mainCREATE_UDP_CLI_TASKS */ xTasksAlreadyCreated = pdTRUE; } /* Print out the network configuration, which may have come from a DHCP server. */ FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress ); vOutputString( "IP Address: " ); FreeRTOS_inet_ntoa( ulIPAddress, cBuffer ); vOutputString( ( char * ) cBuffer ); vOutputString( "\r\nSubnet Mask: " ); FreeRTOS_inet_ntoa( ulNetMask, cBuffer ); vOutputString( ( char * ) cBuffer ); vOutputString( "\r\nGateway Address: " ); FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer ); vOutputString( ( char * ) cBuffer ); vOutputString( "\r\nDNS Server Address: " ); FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer ); vOutputString( ( char * ) cBuffer ); vOutputString( "\r\n\r\n" ); } }