]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c
Added +TCP code to main repo.
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_TCP_Minimal_Windows_Simulator / main.c
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c
new file mode 100644 (file)
index 0000000..c008f37
--- /dev/null
@@ -0,0 +1,380 @@
+/*\r
+    FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/*\r
+ * This project is a cut down version of the project described on the following\r
+ * link.  Only the simple UDP client and server and the TCP echo clients are\r
+ * included in the build:\r
+ * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+#include <time.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include <FreeRTOS.h>\r
+#include "task.h"\r
+\r
+/* Demo application includes. */\r
+#include "FreeRTOS_IP.h"\r
+#include "FreeRTOS_Sockets.h"\r
+#include "SimpleUDPClientAndServer.h"\r
+#include "TCPEchoClient_SingleTasks.h"\r
+#include "demo_logging.h"\r
+\r
+/* Simple UDP client and server task parameters. */\r
+#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY             ( tskIDLE_PRIORITY )\r
+#define mainSIMPLE_UDP_CLIENT_SERVER_PORT                              ( 5005UL )\r
+\r
+/* Echo client task parameters - used for both TCP and UDP echo clients. */\r
+#define mainECHO_CLIENT_TASK_STACK_SIZE                                ( configMINIMAL_STACK_SIZE * 2 )        /* Not used in the Windows port. */\r
+#define mainECHO_CLIENT_TASK_PRIORITY                                  ( tskIDLE_PRIORITY + 1 )\r
+\r
+/* Define a name that will be used for LLMNR and NBNS searches. */\r
+#define mainHOST_NAME                          "RTOSDemo"\r
+#define mainDEVICE_NICK_NAME           "windows_demo"\r
+\r
+/* Set the following constants to 1 or 0 to define which tasks to include and\r
+exclude:\r
+\r
+mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS:  When set to 1 two UDP client tasks\r
+and two UDP server tasks are created.  The clients talk to the servers.  One set\r
+of tasks use the standard sockets interface, and the other the zero copy sockets\r
+interface.  These tasks are self checking and will trigger a configASSERT() if\r
+they detect a difference in the data that is received from that which was sent.\r
+As these tasks use UDP, and can therefore loose packets, they will cause\r
+configASSERT() to be called when they are run in a less than perfect networking\r
+environment.\r
+\r
+mainCREATE_TCP_ECHO_TASKS_SINGLE:  When set to 1 a set of tasks are created that\r
+send TCP echo requests to the standard echo port (port 7), then wait for and\r
+verify the echo reply, from within the same task (Tx and Rx are performed in the\r
+same RTOS task).  The IP address of the echo server must be configured using the\r
+configECHO_SERVER_ADDR0 to configECHO_SERVER_ADDR3 constants in\r
+FreeRTOSConfig.h.\r
+*/\r
+#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS      1\r
+#define mainCREATE_TCP_ECHO_TASKS_SINGLE                       1\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Just seeds the simple pseudo random number generator.\r
+ */\r
+static void prvSRand( UBaseType_t ulSeed );\r
+\r
+/*\r
+ * Miscellaneous initialisation including preparing the logging and seeding the\r
+ * random number generator.\r
+ */\r
+static void prvMiscInitialisation( void );\r
+\r
+/* The default IP and MAC address used by the demo.  The address configuration\r
+defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is\r
+1 but a DHCP server could not be contacted.  See the online documentation for\r
+more information. */\r
+static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };\r
+static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };\r
+static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };\r
+static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };\r
+\r
+/* Set the following constant to pdTRUE to log using the method indicated by the\r
+name of the constant, or pdFALSE to not log using the method indicated by the\r
+name of the constant.  Options include to standard out (xLogToStdout), to a disk\r
+file (xLogToFile), and to a UDP port (xLogToUDP).  If xLogToUDP is set to pdTRUE\r
+then UDP messages are sent to the IP address configured as the echo server\r
+address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and\r
+the port number set by configPRINT_PORT in FreeRTOSConfig.h. */\r
+const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;\r
+\r
+/* Default MAC address configuration.  The demo creates a virtual network\r
+connection that uses this MAC address by accessing the raw Ethernet data\r
+to and from a real network connection on the host PC.  See the\r
+configNETWORK_INTERFACE_TO_USE definition for information on how to configure\r
+the real network connection to use. */\r
+const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };\r
+\r
+/* Use by the pseudo random number generator. */\r
+static UBaseType_t ulNextRand;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+int main( void )\r
+{\r
+const uint32_t ulLongTime_ms = pdMS_TO_TICKS( 1000UL );\r
+\r
+       /*\r
+        * Instructions for using this project are provided on:\r
+        * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html\r
+        */\r
+\r
+       /* Miscellaneous initialisation including preparing the logging and seeding\r
+       the random number generator. */\r
+       prvMiscInitialisation();\r
+\r
+       /* Initialise the network interface.\r
+\r
+       ***NOTE*** Tasks that use the network are created in the network event hook\r
+       when the network is connected and ready for use (see the definition of\r
+       vApplicationIPNetworkEventHook() below).  The address values passed in here\r
+       are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1\r
+       but a DHCP server cannot be     contacted. */\r
+       FreeRTOS_debug_printf( ( "FreeRTOS_IPInit\n" ) );\r
+       FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );\r
+\r
+       /* Start the RTOS scheduler. */\r
+       FreeRTOS_debug_printf( ("vTaskStartScheduler\n") );\r
+       vTaskStartScheduler();\r
+\r
+       /* If all is well, the scheduler will now be running, and the following\r
+       line will never be reached.  If the following line does execute, then\r
+       there was insufficient FreeRTOS heap memory available for the idle and/or\r
+       timer tasks     to be created.  See the memory management section on the\r
+       FreeRTOS web site for more details (this is standard text that is not not\r
+       really applicable to the Win32 simulator port). */\r
+       for( ;; )\r
+       {\r
+               Sleep( ulLongTime_ms );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+const uint32_t ulMSToSleep = 1;\r
+\r
+       /* This is just a trivial example of an idle hook.  It is called on each\r
+       cycle of the idle task if configUSE_IDLE_HOOK is set to 1 in\r
+       FreeRTOSConfig.h.  It must *NOT* attempt to block.  In this case the\r
+       idle task just sleeps to lower the CPU usage. */\r
+       Sleep( ulMSToSleep );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vAssertCalled( const char *pcFile, uint32_t ulLine )\r
+{\r
+const uint32_t ulLongSleep = 1000UL;\r
+volatile uint32_t ulBlockVariable = 0UL;\r
+volatile char *pcFileName = ( volatile char *  ) pcFile;\r
+volatile uint32_t ulLineNumber = ulLine;\r
+\r
+       ( void ) pcFileName;\r
+       ( void ) ulLineNumber;\r
+\r
+       FreeRTOS_debug_printf( ( "vAssertCalled( %s, %ld\n", pcFile, ulLine ) );\r
+\r
+       /* Setting ulBlockVariable to a non-zero value in the debugger will allow\r
+       this function to be exited. */\r
+       taskDISABLE_INTERRUPTS();\r
+       {\r
+               while( ulBlockVariable == 0UL )\r
+               {\r
+                       Sleep( ulLongSleep );\r
+               }\r
+       }\r
+       taskENABLE_INTERRUPTS();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Called by FreeRTOS+TCP when the network connects or disconnects.  Disconnect\r
+events are only received if implemented in the MAC driver. */\r
+void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )\r
+{\r
+uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;\r
+char cBuffer[ 16 ];\r
+static BaseType_t xTasksAlreadyCreated = pdFALSE;\r
+\r
+       /* If the network has just come up...*/\r
+       if( eNetworkEvent == eNetworkUp )\r
+       {\r
+               /* Create the tasks that use the IP stack if they have not already been\r
+               created. */\r
+               if( xTasksAlreadyCreated == pdFALSE )\r
+               {\r
+                       /* See the comments above the definitions of these pre-processor\r
+                       macros at the top of this file for a description of the individual\r
+                       demo tasks. */\r
+                       #if( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 )\r
+                       {\r
+                               vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY );\r
+                       }\r
+                       #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */\r
+\r
+                       #if( mainCREATE_TCP_ECHO_TASKS_SINGLE == 1 )\r
+                       {\r
+                               vStartTCPEchoClientTasks_SingleTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );\r
+                       }\r
+                       #endif /* mainCREATE_TCP_ECHO_TASKS_SINGLE */\r
+\r
+                       xTasksAlreadyCreated = pdTRUE;\r
+               }\r
+\r
+               /* Print out the network configuration, which may have come from a DHCP\r
+               server. */\r
+               FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );\r
+               FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );\r
+               FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );\r
+\r
+               FreeRTOS_inet_ntoa( ulNetMask, cBuffer );\r
+               FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );\r
+\r
+               FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );\r
+               FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );\r
+\r
+               FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );\r
+               FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+       /* Called if a call to pvPortMalloc() fails because there is insufficient\r
+       free memory available in the FreeRTOS heap.  pvPortMalloc() is called\r
+       internally by FreeRTOS API functions that create tasks, queues, software\r
+       timers, and semaphores.  The size of the FreeRTOS heap is set by the\r
+       configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */\r
+       vAssertCalled( __FILE__, __LINE__ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+UBaseType_t uxRand( void )\r
+{\r
+const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;\r
+\r
+       /* Utility function to generate a pseudo random number. */\r
+\r
+       ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;\r
+       return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSRand( UBaseType_t ulSeed )\r
+{\r
+       /* Utility function to seed the pseudo random number generator. */\r
+    ulNextRand = ulSeed;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMiscInitialisation( void )\r
+{\r
+time_t xTimeNow;\r
+uint32_t ulLoggingIPAddress;\r
+\r
+       ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );\r
+       vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );\r
+\r
+       /* Seed the random number generator. */\r
+       time( &xTimeNow );\r
+       FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );\r
+       prvSRand( ( uint32_t ) xTimeNow );\r
+       FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )\r
+\r
+       const char *pcApplicationHostnameHook( void )\r
+       {\r
+               /* Assign the name "FreeRTOS" to this network node.  This function will\r
+               be called during the DHCP: the machine will be registered with an IP\r
+               address plus this name. */\r
+               return mainHOST_NAME;\r
+       }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )\r
+\r
+       BaseType_t xApplicationDNSQueryHook( const char *pcName )\r
+       {\r
+       BaseType_t xReturn;\r
+\r
+               /* Determine if a name lookup is for this node.  Two names are given\r
+               to this node: that returned by pcApplicationHostnameHook() and that set\r
+               by mainDEVICE_NICK_NAME. */\r
+               if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )\r
+               {\r
+                       xReturn = pdPASS;\r
+               }\r
+               else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )\r
+               {\r
+                       xReturn = pdPASS;\r
+               }\r
+               else\r
+               {\r
+                       xReturn = pdFAIL;\r
+               }\r
+\r
+               return xReturn;\r
+       }\r
+\r
+#endif\r