]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_UDP_and_CLI_Windows_Simulator/main.c
Update FreeRTOS+ version number ready for version 9 release candidate 1.
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_UDP_and_CLI_Windows_Simulator / main.c
1 /*\r
2     FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 /* Standard includes. */\r
71 #include <stdio.h>\r
72 #include <stdint.h>\r
73 \r
74 /* FreeRTOS includes. */\r
75 #include <FreeRTOS.h>\r
76 #include "task.h"\r
77 #include "queue.h"\r
78 #include "semphr.h"\r
79 \r
80 /* Demo application includes. */\r
81 #include "FreeRTOS_UDP_IP.h"\r
82 #include "FreeRTOS_Sockets.h"\r
83 #include "SimpleClientAndServer.h"\r
84 #include "TwoEchoClients.h"\r
85 #include "UDPCommandInterpreter.h"\r
86 #include "SelectServer.h"\r
87 \r
88 /* UDP command server task parameters. */\r
89 #define mainUDP_CLI_TASK_PRIORITY                                       ( tskIDLE_PRIORITY )\r
90 #define mainUDP_CLI_PORT_NUMBER                                         ( 5001UL )\r
91 #define mainUDP_CLI_TASK_STACK_SIZE                                     ( configMINIMAL_STACK_SIZE )\r
92 \r
93 /* Simple UDP client and server task parameters. */\r
94 #define mainSIMPLE_CLIENT_SERVER_TASK_PRIORITY          ( tskIDLE_PRIORITY )\r
95 #define mainSIMPLE_CLIENT_SERVER_PORT                           ( 5005UL )\r
96 #define mainSIMPLE_CLIENT_SERVER_TASK_STACK_SIZE        ( configMINIMAL_STACK_SIZE )\r
97 \r
98 /* Select UDP server task parameters. */\r
99 #define mainSELECT_SERVER_TASK_PRIORITY                         ( tskIDLE_PRIORITY )\r
100 #define mainSELECT_SERVER_PORT                                          ( 10001UL )\r
101 #define mainSELECT_SERVER_TASK_STACK_SIZE                       ( configMINIMAL_STACK_SIZE )\r
102 \r
103 /* Echo client task parameters. */\r
104 #define mainECHO_CLIENT_TASK_STACK_SIZE                         ( configMINIMAL_STACK_SIZE * 2 )\r
105 #define mainECHO_CLIENT_TASK_PRIORITY                           ( tskIDLE_PRIORITY + 1 )\r
106 \r
107 /* Set the following constants to 1 or 0 to define which tasks to include and \r
108 exclude. */\r
109 #define mainCREATE_UDP_CLI_TASKS                                        1\r
110 #define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS       0\r
111 #define mainCREATE_SELECT_UDP_SERVER_TASKS                      0\r
112 #define mainCREATE_UDP_ECHO_TASKS                                       1\r
113 \r
114 /*-----------------------------------------------------------*/\r
115 \r
116 /*\r
117  * Register commands that can be used with FreeRTOS+CLI through the UDP socket.\r
118  * The commands are defined in CLI-commands.c.\r
119  */\r
120 extern void vRegisterCLICommands( void );\r
121 \r
122 /* The default IP and MAC address used by the demo.  The address configuration\r
123 defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is\r
124 1 but a DHCP server could not be contacted.  See the online documentation for\r
125 more information. */\r
126 static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };\r
127 static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };\r
128 static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };\r
129 static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };\r
130 \r
131 /* Default MAC address configuration.  The demo creates a virtual network\r
132 connection that uses this MAC address by accessing the raw Ethernet data\r
133 to and from a real network connection on the host PC.  See the\r
134 configNETWORK_INTERFACE_TO_USE definition for information on how to configure\r
135 the real network connection to use. */\r
136 const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };\r
137 \r
138 /* Used to guard prints to the console. */\r
139 static xSemaphoreHandle xConsoleMutex = NULL;\r
140 \r
141 /*-----------------------------------------------------------*/\r
142 \r
143 \r
144 \r
145 /******************************************************************************\r
146  *\r
147  * See the following web page for information on using this demo.\r
148  * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/RTOS_UDP_CLI_Windows_Simulator.shtml\r
149  *\r
150  ******************************************************************************/\r
151 \r
152 \r
153 int main( void )\r
154 {\r
155 const uint32_t ulLongTime_ms = 250UL;\r
156 \r
157         /* Create a mutex that is used to guard against the console being accessed \r
158         by more than one task simultaniously. */\r
159         xConsoleMutex = xSemaphoreCreateMutex();\r
160 \r
161         /* Initialise the network interface.  Tasks that use the network are\r
162         created in the network event hook when the network is connected and ready\r
163         for use.  The address values passed in here are used if ipconfigUSE_DHCP is\r
164         set to 0, or if ipconfigUSE_DHCP is set to 1 but a DHCP server cannot be\r
165         contacted. */\r
166         FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );\r
167 \r
168         /* Register commands with the FreeRTOS+CLI command interpreter. */\r
169         vRegisterCLICommands();\r
170 \r
171         /* Start the RTOS scheduler. */\r
172         vTaskStartScheduler();\r
173 \r
174         /* If all is well, the scheduler will now be running, and the following\r
175         line will never be reached.  If the following line does execute, then\r
176         there was insufficient FreeRTOS heap memory available for the idle and/or\r
177         timer tasks     to be created.  See the memory management section on the\r
178         FreeRTOS web site for more details (this is standard text that is not not\r
179         really applicable to the Win32 simulator port). */\r
180         for( ;; )\r
181         {\r
182                 Sleep( ulLongTime_ms );\r
183         }\r
184 }\r
185 /*-----------------------------------------------------------*/\r
186 \r
187 void vApplicationIdleHook( void )\r
188 {\r
189 const unsigned long ulMSToSleep = 5;\r
190 \r
191         /* This function is called on each cycle of the idle task if\r
192         configUSE_IDLE_HOOK is set to 1 in FreeRTOSConfig.h.  Sleep to reduce CPU\r
193         load. */\r
194         Sleep( ulMSToSleep );\r
195 }\r
196 /*-----------------------------------------------------------*/\r
197 \r
198 void vAssertCalled( void )\r
199 {\r
200 const unsigned long ulLongSleep = 1000UL;\r
201 volatile uint32_t ulBlockVariable = 0UL;\r
202 \r
203         /* Setting ulBlockVariable to a non-zero value in the debugger will allow\r
204         this function to be exited. */\r
205         taskDISABLE_INTERRUPTS();\r
206         {\r
207                 while( ulBlockVariable == 0UL )\r
208                 {\r
209                         Sleep( ulLongSleep );\r
210                 }\r
211         }\r
212         taskENABLE_INTERRUPTS();\r
213 }\r
214 /*-----------------------------------------------------------*/\r
215 \r
216 void vOutputString( char *pcMessage )\r
217 {\r
218         /* Wrap the standard windows console output (as opposed to the FreeRTOS+CLI\r
219         console) with a mutex to ensure it can only be accessed by one task at a\r
220         time. */\r
221         xSemaphoreTake( xConsoleMutex, portMAX_DELAY );\r
222                 printf( pcMessage );\r
223         xSemaphoreGive( xConsoleMutex );\r
224 }\r
225 /*-----------------------------------------------------------*/\r
226 \r
227 /* Called by FreeRTOS+UDP when the network connects. */\r
228 void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )\r
229 {\r
230 uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;\r
231 int8_t cBuffer[ 16 ];\r
232 static BaseType_t xTasksAlreadyCreated = pdFALSE;\r
233 \r
234         if( eNetworkEvent == eNetworkUp )\r
235         {\r
236                 /* Create the tasks that use the IP stack if they have not already been\r
237                 created. */\r
238                 if( xTasksAlreadyCreated == pdFALSE )\r
239                 {\r
240                         #if( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 )\r
241                         {\r
242                                 /* Create tasks that demonstrate sending and receiving in both\r
243                                 standard and zero copy mode. */\r
244                                 vStartSimpleUDPClientServerTasks( mainSIMPLE_CLIENT_SERVER_TASK_STACK_SIZE, mainSIMPLE_CLIENT_SERVER_PORT, mainSIMPLE_CLIENT_SERVER_TASK_PRIORITY );\r
245                         }\r
246                         #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */\r
247 \r
248                         #if( mainCREATE_SELECT_UDP_SERVER_TASKS == 1 )\r
249                         {\r
250                                 /* Create tasks that demonstrate sending and receiving in both\r
251                                 standard and zero copy mode. */\r
252                                 vStartSelectUDPServerTasks( mainSELECT_SERVER_TASK_STACK_SIZE, mainSELECT_SERVER_PORT, mainSELECT_SERVER_TASK_PRIORITY );\r
253                         }\r
254                         #endif /* mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS */\r
255 \r
256 \r
257                         #if( mainCREATE_UDP_ECHO_TASKS == 1 )\r
258                         {\r
259                                 /* Create the tasks that transmit to and receive from a standard\r
260                                 echo server (see the web documentation for this port) in both\r
261                                 standard and zero copy mode. */\r
262                                 vStartEchoClientTasks( mainECHO_CLIENT_TASK_STACK_SIZE, mainECHO_CLIENT_TASK_PRIORITY );\r
263                         }\r
264                         #endif /* mainCREATE_UDP_ECHO_TASKS */\r
265 \r
266                         #if( mainCREATE_UDP_CLI_TASKS == 1 )\r
267                         {\r
268                                 /* Create the task that handles the CLI on a UDP port.  The port number\r
269                                 is set using the configUDP_CLI_PORT_NUMBER setting in FreeRTOSConfig.h. */\r
270                                 vStartUDPCommandInterpreterTask( mainUDP_CLI_TASK_STACK_SIZE, mainUDP_CLI_PORT_NUMBER, mainUDP_CLI_TASK_PRIORITY );\r
271                         }\r
272                         #endif /* mainCREATE_UDP_CLI_TASKS */\r
273 \r
274                         xTasksAlreadyCreated = pdTRUE;\r
275                 }\r
276 \r
277                 /* Print out the network configuration, which may have come from a DHCP\r
278                 server. */\r
279                 FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );\r
280                 vOutputString( "IP Address: " );\r
281                 FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );\r
282                 vOutputString( ( char * ) cBuffer );\r
283                 vOutputString( "\r\nSubnet Mask: " );\r
284                 FreeRTOS_inet_ntoa( ulNetMask, cBuffer );\r
285                 vOutputString( ( char * ) cBuffer );\r
286                 vOutputString( "\r\nGateway Address: " );\r
287                 FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );\r
288                 vOutputString( ( char * ) cBuffer );\r
289                 vOutputString( "\r\nDNS Server Address: " );\r
290                 FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );\r
291                 vOutputString( ( char * ) cBuffer );\r
292                 vOutputString( "\r\n\r\n" );\r
293         }\r
294 }\r
295 /*-----------------------------------------------------------*/\r
296 \r
297 /* Called automatically when a reply to an outgoing ping is received. */\r
298 void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier )\r
299 {\r
300 static const uint8_t *pcSuccess = ( uint8_t * ) "Ping reply received - ";\r
301 static const uint8_t *pcInvalidChecksum = ( uint8_t * ) "Ping reply received with invalid checksum - ";\r
302 static const uint8_t *pcInvalidData = ( uint8_t * ) "Ping reply received with invalid data - ";\r
303 static uint8_t cMessage[ 50 ];\r
304 \r
305 \r
306         switch( eStatus )\r
307         {\r
308                 case eSuccess   :\r
309                         vOutputString( ( char * ) pcSuccess );\r
310                         break;\r
311 \r
312                 case eInvalidChecksum :\r
313                         vOutputString( ( char * ) pcInvalidChecksum );\r
314                         break;\r
315 \r
316                 case eInvalidData :\r
317                         vOutputString( ( char * ) pcInvalidData );\r
318                         break;\r
319 \r
320                 default :\r
321                         /* It is not possible to get here as all enums have their own\r
322                         case. */\r
323                         break;\r
324         }\r
325 \r
326         sprintf( ( char * ) cMessage, "identifier %d\r\n", ( int ) usIdentifier );\r
327         vOutputString( ( char * ) cMessage );\r
328 }\r
329 /*-----------------------------------------------------------*/\r
330 \r
331 void vApplicationMallocFailedHook( void )\r
332 {\r
333         /* vApplicationMallocFailedHook() will only be called if\r
334         configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook\r
335         function that will get called if a call to pvPortMalloc() fails.\r
336         pvPortMalloc() is called internally by the kernel whenever a task, queue,\r
337         timer or semaphore is created.  It is also called by various parts of the\r
338         demo application.  If heap_1.c, heap_2.c or heap_4.c are used, then the \r
339         size of the heap available to pvPortMalloc() is defined by \r
340         configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize() \r
341         API function can be used to query the size of free heap space that remains \r
342         (although it does not provide information on how the remaining heap might \r
343         be fragmented). */\r
344         taskDISABLE_INTERRUPTS();\r
345         for( ;; );\r
346 }\r
347 \r
348 \r
349 \r