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