Added simple UDP demo into the mqtt project to enable the network connectivity to be tested in a simple way prior to performing any MQTT operations.

pull/1/head
Richard Barry 6 years ago
parent d362efca8d
commit 2b295f9015

@ -47,6 +47,10 @@
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#if( configASSERT_DEFINED == 0 )
#error This demo uses configASSERT() to trap errors. configASSERT() must be defined in FreeRTOSConfig.h https://www.freertos.org/a00110.html#configASSERT
#endif
#define simpTINY_DELAY ( ( TickType_t ) 2 )
/*
@ -101,6 +105,8 @@ const TickType_t x150ms = 150UL / portTICK_PERIOD_MS;
/* Remove compiler warning about unused parameters. */
( void ) pvParameters;
FreeRTOS_printf( ( "Starting prvSimpleClientTask\r\n" ) );
/* It is assumed that this task is not created until the network is up,
so the IP address can be obtained immediately. store the IP address being
used in ulIPAddress. This is done so the socket can send to a different
@ -161,6 +167,8 @@ Socket_t xListeningSocket;
/* Just to prevent compiler warnings. */
( void ) pvParameters;
FreeRTOS_printf( ( "Starting prvSimpleServerTask\r\n" ) );
/* Attempt to open the socket. */
xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
@ -191,6 +199,7 @@ Socket_t xListeningSocket;
/* Error check. */
configASSERT( lBytes == ( BaseType_t ) strlen( ( const char * ) cReceivedString ) );
FreeRTOS_printf( ( "prvSimpleServerTask() recieved %s\r\n", ( const char * ) cReceivedString ) );
}
}
/*-----------------------------------------------------------*/
@ -211,6 +220,8 @@ const size_t xStringLength = strlen( pcStringToSend ) + 15;
/* Remove compiler warning about unused parameters. */
( void ) pvParameters;
FreeRTOS_printf( ( "Starting prvSimpleZeroCopyUDPClientTask\r\n" ) );
/* It is assumed that this task is not created until the network is up,
so the IP address can be obtained immediately. store the IP address being
used in ulIPAddress. This is done so the socket can send to a different
@ -309,6 +320,8 @@ Socket_t xListeningSocket;
/* Just to prevent compiler warnings. */
( void ) pvParameters;
FreeRTOS_printf( ( "Starting prvSimpleZeroCopyServerTask\r\n" ) );
/* Attempt to open the socket. */
xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
@ -343,6 +356,7 @@ Socket_t xListeningSocket;
/* It is expected to receive one more byte than the string length as
the NULL terminator is also transmitted. */
configASSERT( lBytes == ( ( BaseType_t ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) );
FreeRTOS_printf( ( "prvSimpleZeroCopyServerTask() recieved %s\r\n", ( const char * ) pucUDPPayloadBuffer ) );
}
if( lBytes >= 0 )

@ -136,7 +136,7 @@ example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4
results in the wired network being used, while setting
configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being
used. */
#define configNETWORK_INTERFACE_TO_USE 4L
#define configNETWORK_INTERFACE_TO_USE 3L
/* The address of an echo server that will be used by the two demo echo client
tasks.

@ -53,7 +53,7 @@ out the debugging messages. */
FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1
then FreeRTOS_printf should be set to the function used to print out the
messages. */
#define ipconfigHAS_PRINTF 0
#define ipconfigHAS_PRINTF 1
#if( ipconfigHAS_PRINTF == 1 )
#define FreeRTOS_printf(X) vLoggingPrintf X
#endif

@ -46,18 +46,80 @@ should an assert get hit. */
/* TCP/IP stack includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
/* Demo app includes. */
#include "demo_logging.h"
/* Set the following constants to 1 or 0 to define which tasks to include and
exclude:
mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks
and two UDP server tasks are created. The clients talk to the servers. One set
of tasks use the standard sockets interface, and the other the zero copy sockets
interface. These tasks are self checking and will trigger a configASSERT() if
they detect a difference in the data that is received from that which was sent.
As these tasks use UDP, and can therefore loose packets, they will cause
configASSERT() to be called when they are run in a less than perfect networking
environment.
mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS: TBD
*/
#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1
#define mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS 0
/* Simple UDP client and server task parameters. */
#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL )
/*
* Prototypes for the demos that can be started from this project.
*/
extern void vStartSimpleTaskPoolDemo( void );
extern void vStartSimpleMQTTDemo( void );
extern void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulsPort, UBaseType_t uxPriority );
/*
* Just seeds the simple pseudo random number generator.
*
* !!! NOTE !!!
* This is not a secure method of generating random numbers and production
* devices should use a true random number generator (TRNG).
*/
static void prvSRand( UBaseType_t ulSeed );
/* This example is the first in a sequence that adds IoT functionality into
an existing TCP/IP project. In this first project the TCP/IP stack is not
actually used, but it is still built, which requires this array to be
present. */
/*
* Miscellaneous initialisation including preparing the logging and seeding the
* random number generator.
*/
static void prvMiscInitialisation( void );
/* The default IP and MAC address used by the demo. The address configuration
defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
1 but a DHCP server could not be contacted. See the online documentation for
more information. */
static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };
static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };
static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
/* Set the following constant to pdTRUE to log using the method indicated by the
name of the constant, or pdFALSE to not log using the method indicated by the
name of the constant. Options include to standard out (xLogToStdout), to a disk
file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
then UDP messages are sent to the IP address configured as the echo server
address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and
the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;
/* Default MAC address configuration. The demo creates a virtual network
connection that uses this MAC address by accessing the raw Ethernet data
to and from a real network connection on the host PC. See the
configNETWORK_INTERFACE_TO_USE definition for information on how to configure
the real network connection to use. */
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
/* Use by the pseudo random number generator. */
static UBaseType_t ulNextRand;
/*-----------------------------------------------------------*/
int main( void )
@ -67,14 +129,20 @@ int main( void )
* TBD
*/
/* Create the example that demonstrates task pool functionality. Examples
that demonstrate networking connectivity will be added in future projects
and get started after the network has connected (from within the
vApplicationIPNetworkEventHook() function).*/
vStartSimpleTaskPoolDemo();
/* Miscellaneous initialisation including preparing the logging and seeding
the random number generator. */
prvMiscInitialisation();
/* Start the scheduler - if all is well from this point on only FreeRTOS
tasks will execute. */
/* Initialise the network interface.
***NOTE*** Tasks that use the network are created in the network event hook
when the network is connected and ready for use (see the implementation of
vApplicationIPNetworkEventHook() below). The address values passed in here
are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
but a DHCP server cannot be contacted. */
FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
/* Start the RTOS scheduler. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
@ -118,46 +186,147 @@ volatile uint32_t ulLineNumber = ulLine;
events are only received if implemented in the MAC driver. */
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
{
/* This example is the first in a sequence that adds IoT functionality into
an existing TCP/IP project. In this first project the TCP/IP stack is not
actually used, but it is still built, which requires this function to be
present. For now this function does not need to do anything, so just ensure
the unused parameters don't cause compiler warnings and that calls to this
function are trapped by the debugger. */
__debugbreak();
( void ) eNetworkEvent;
uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
char cBuffer[ 16 ];
static BaseType_t xTasksAlreadyCreated = pdFALSE;
/* If the network has just come up...*/
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 )
{
vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY );
}
#endif
#if( mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS == 1 )
{
vStartSimpleMQTTDemo();
}
#endif
xTasksAlreadyCreated = pdTRUE;
}
/* Print out the network configuration, which may have come from a DHCP
server. */
FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );/*_RB_ Should use IoT libraries logging. */
FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
}
}
/*-----------------------------------------------------------*/
UBaseType_t uxRand( void )
{
const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
/*
* Utility function to generate a pseudo random number.
*
* !!!NOTE!!!
* This is not a secure method of generating a random number. Production
* devices should use a True Random Number Generator (TRNG).
*/
ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
}
/*-----------------------------------------------------------*/
static void prvSRand( UBaseType_t ulSeed )
{
/* Utility function to seed the pseudo random number generator. */
ulNextRand = ulSeed;
}
/*-----------------------------------------------------------*/
static void prvMiscInitialisation( void )
{
time_t xTimeNow;
uint32_t ulLoggingIPAddress;
ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );
vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );
/* Seed the random number generator. */
time( &xTimeNow );
FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );
prvSRand( ( uint32_t ) xTimeNow );
FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );
}
/*-----------------------------------------------------------*/
#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
const char *pcApplicationHostnameHook( void )
{
/* Assign the name "FreeRTOS" to this network node. This function will
be called during the DHCP: the machine will be registered with an IP
address plus this name. */
return mainHOST_NAME;
}
#endif
/*-----------------------------------------------------------*/
#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
BaseType_t xApplicationDNSQueryHook( const char *pcName )
{
BaseType_t xReturn;
/* Determine if a name lookup is for this node. Two names are given
to this node: that returned by pcApplicationHostnameHook() and that set
by mainDEVICE_NICK_NAME. */
if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
{
xReturn = pdPASS;
}
else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
{
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
#endif
/*-----------------------------------------------------------*/
/*
* Callback that provides the inputs necessary to generate a randomized TCP
* Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION
* THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION
* SYSTEMS.
*/
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort )
{
/* This example is the first in a sequence that adds IoT functionality into
an existing TCP/IP project. In this first project the TCP/IP stack is not
actually used, but it is still built, which requires this function to be
present. For now this function does not need to do anything, so just ensure
the unused parameters don't cause compiler warnings and that calls to this
function are trapped by the debugger. */
( void ) ulSourceAddress;
( void ) usSourcePort;
( void ) ulDestinationAddress;
( void ) usDestinationPort;
__debugbreak();
return 0;
}
/*-----------------------------------------------------------*/
UBaseType_t uxRand( void )
{
/* This example is the first in a sequence that adds IoT functionality into
an existing TCP/IP project. In this first project the TCP/IP stack is not
actually used, but it is still built, which requires this function to be
present. For now this function does not need to do anything, so just ensure
the calls to the function are trapped by the debugger. */
__debugbreak();
return 0;
return uxRand();
}
/*-----------------------------------------------------------*/

@ -25,13 +25,6 @@
* 1 tab == 4 spaces!
*/
/*
* This project is a cut down version of the project described on the following
* link. Only the simple UDP client and server and the TCP echo clients are
* included in the build:
* http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
*/
/* Standard includes. */
#include <stdio.h>
#include <time.h>

Loading…
Cancel
Save