]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c
Update FreeRTOS+ version number ready for version 9 release candidate 1.
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator / CLI-commands.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 /* FreeRTOS includes. */\r
71 #include "FreeRTOS.h"\r
72 #include "task.h"\r
73 \r
74 /* FreeRTOS+CLI includes. */\r
75 #include "FreeRTOS_CLI.h"\r
76 \r
77 /* FreeRTOS+Trace includes. */\r
78 #include "trcUser.h"\r
79 \r
80 /*\r
81  * Writes trace data to a disk file when the trace recording is stopped.\r
82  * This function will simply overwrite any trace files that already exist.\r
83  */\r
84 static void prvSaveTraceFile( void );\r
85 \r
86 /*\r
87  * Defines a command that returns a table showing the state of each task at the\r
88  * time the command is called.\r
89  */\r
90 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
91 \r
92 /*\r
93  * Defines a command that returns a table showing how much time each task has\r
94  * spent in the Running state.\r
95  */\r
96 static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
97 \r
98 /*\r
99  * Defines a command that expects exactly three parameters.  Each of the three\r
100  * parameter are echoed back one at a time.\r
101  */\r
102 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
103 \r
104 /*\r
105  * Defines a command that can take a variable number of parameters.  Each\r
106  * parameter is echoes back one at a time.\r
107  */\r
108 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
109 \r
110 /*\r
111  * Defines a command that starts/stops events being recorded for offline viewing\r
112  * in FreeRTOS+Trace.\r
113  */\r
114 static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
115 \r
116 /* Structure that defines the "run-time-stats" command line command. */\r
117 static const CLI_Command_Definition_t xRunTimeStats =\r
118 {\r
119         "run-time-stats", /* The command string to type. */\r
120         "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n",\r
121         prvRunTimeStatsCommand, /* The function to run. */\r
122         0 /* No parameters are expected. */\r
123 };\r
124 \r
125 /* Structure that defines the "task-stats" command line command. */\r
126 static const CLI_Command_Definition_t xTaskStats =\r
127 {\r
128         "task-stats", /* The command string to type. */\r
129         "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n",\r
130         prvTaskStatsCommand, /* The function to run. */\r
131         0 /* No parameters are expected. */\r
132 };\r
133 \r
134 /* Structure that defines the "echo_3_parameters" command line command.  This\r
135 takes exactly three parameters that the command simply echos back one at a\r
136 time. */\r
137 static const CLI_Command_Definition_t xThreeParameterEcho =\r
138 {\r
139         "echo_3_parameters",\r
140         "\r\necho_3_parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n\r\n",\r
141         prvThreeParameterEchoCommand, /* The function to run. */\r
142         3 /* Three parameters are expected, which can take any value. */\r
143 };\r
144 \r
145 /* Structure that defines the "echo_parameters" command line command.  This\r
146 takes a variable number of parameters that the command simply echos back one at\r
147 a time. */\r
148 static const CLI_Command_Definition_t xParameterEcho =\r
149 {\r
150         "echo_parameters",\r
151         "\r\necho_parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n",\r
152         prvParameterEchoCommand, /* The function to run. */\r
153         -1 /* The user can enter any number of commands. */\r
154 };\r
155 \r
156 /* Structure that defines the "trace" command line command.  This takes a single\r
157 parameter, which can be either "start" or "stop". */\r
158 static const CLI_Command_Definition_t xStartTrace =\r
159 {\r
160         "trace",\r
161         "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n",\r
162         prvStartStopTraceCommand, /* The function to run. */\r
163         1 /* One parameter is expected.  Valid values are "start" and "stop". */\r
164 };\r
165 \r
166 /*-----------------------------------------------------------*/\r
167 \r
168 void vRegisterCLICommands( void )\r
169 {\r
170         /* Register all the command line commands defined immediately above. */\r
171         FreeRTOS_CLIRegisterCommand( &xTaskStats );\r
172         FreeRTOS_CLIRegisterCommand( &xRunTimeStats );\r
173         FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );\r
174         FreeRTOS_CLIRegisterCommand( &xParameterEcho );\r
175         FreeRTOS_CLIRegisterCommand( &xStartTrace );\r
176 }\r
177 /*-----------------------------------------------------------*/\r
178 \r
179 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
180 {\r
181 const char *const pcHeader = "Task          State  Priority  Stack      #\r\n************************************************\r\n";\r
182 \r
183         /* Remove compile time warnings about unused parameters, and check the\r
184         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
185         write buffer length is adequate, so does not check for buffer overflows. */\r
186         ( void ) pcCommandString;\r
187         ( void ) xWriteBufferLen;\r
188         configASSERT( pcWriteBuffer );\r
189 \r
190         /* Generate a table of task stats. */\r
191         strcpy( pcWriteBuffer, pcHeader );\r
192         vTaskList( pcWriteBuffer + strlen( pcHeader ) );\r
193 \r
194         /* There is no more data to return after this single string, so return\r
195         pdFALSE. */\r
196         return pdFALSE;\r
197 }\r
198 /*-----------------------------------------------------------*/\r
199 \r
200 static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
201 {\r
202 const char * const pcHeader = "Task            Abs Time      % Time\r\n****************************************\r\n";\r
203 \r
204         /* Remove compile time warnings about unused parameters, and check the\r
205         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
206         write buffer length is adequate, so does not check for buffer overflows. */\r
207         ( void ) pcCommandString;\r
208         ( void ) xWriteBufferLen;\r
209         configASSERT( pcWriteBuffer );\r
210 \r
211         /* Generate a table of task stats. */\r
212         strcpy( pcWriteBuffer, pcHeader );\r
213         vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );\r
214 \r
215         /* There is no more data to return after this single string, so return\r
216         pdFALSE. */\r
217         return pdFALSE;\r
218 }\r
219 /*-----------------------------------------------------------*/\r
220 \r
221 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
222 {\r
223 const char *pcParameter;\r
224 BaseType_t lParameterStringLength, xReturn;\r
225 static BaseType_t lParameterNumber = 0;\r
226 \r
227         /* Remove compile time warnings about unused parameters, and check the\r
228         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
229         write buffer length is adequate, so does not check for buffer overflows. */\r
230         ( void ) pcCommandString;\r
231         ( void ) xWriteBufferLen;\r
232         configASSERT( pcWriteBuffer );\r
233 \r
234         if( lParameterNumber == 0 )\r
235         {\r
236                 /* The first time the function is called after the command has been\r
237                 entered just a header string is returned. */\r
238                 sprintf( pcWriteBuffer, "The three parameters were:\r\n" );\r
239 \r
240                 /* Next time the function is called the first parameter will be echoed\r
241                 back. */\r
242                 lParameterNumber = 1L;\r
243 \r
244                 /* There is more data to be returned as no parameters have been echoed\r
245                 back yet. */\r
246                 xReturn = pdPASS;\r
247         }\r
248         else\r
249         {\r
250                 /* Obtain the parameter string. */\r
251                 pcParameter = FreeRTOS_CLIGetParameter\r
252                                                 (\r
253                                                         pcCommandString,                /* The command string itself. */\r
254                                                         lParameterNumber,               /* Return the next parameter. */\r
255                                                         &lParameterStringLength /* Store the parameter string length. */\r
256                                                 );\r
257 \r
258                 /* Sanity check something was returned. */\r
259                 configASSERT( pcParameter );\r
260 \r
261                 /* Return the parameter string. */\r
262                 memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
263                 sprintf( pcWriteBuffer, "%d: ", lParameterNumber );\r
264                 strncat( pcWriteBuffer, pcParameter, lParameterStringLength );\r
265                 strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
266 \r
267                 /* If this is the last of the three parameters then there are no more\r
268                 strings to return after this one. */\r
269                 if( lParameterNumber == 3L )\r
270                 {\r
271                         /* If this is the last of the three parameters then there are no more\r
272                         strings to return after this one. */\r
273                         xReturn = pdFALSE;\r
274                         lParameterNumber = 0L;\r
275                 }\r
276                 else\r
277                 {\r
278                         /* There are more parameters to return after this one. */\r
279                         xReturn = pdTRUE;\r
280                         lParameterNumber++;\r
281                 }\r
282         }\r
283 \r
284         return xReturn;\r
285 }\r
286 /*-----------------------------------------------------------*/\r
287 \r
288 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
289 {\r
290 const char *pcParameter;\r
291 BaseType_t lParameterStringLength, xReturn;\r
292 static BaseType_t lParameterNumber = 0;\r
293 \r
294         /* Remove compile time warnings about unused parameters, and check the\r
295         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
296         write buffer length is adequate, so does not check for buffer overflows. */\r
297         ( void ) pcCommandString;\r
298         ( void ) xWriteBufferLen;\r
299         configASSERT( pcWriteBuffer );\r
300 \r
301         if( lParameterNumber == 0 )\r
302         {\r
303                 /* The first time the function is called after the command has been\r
304                 entered just a header string is returned. */\r
305                 sprintf( pcWriteBuffer, "The parameters were:\r\n" );\r
306 \r
307                 /* Next time the function is called the first parameter will be echoed\r
308                 back. */\r
309                 lParameterNumber = 1L;\r
310 \r
311                 /* There is more data to be returned as no parameters have been echoed\r
312                 back yet. */\r
313                 xReturn = pdPASS;\r
314         }\r
315         else\r
316         {\r
317                 /* Obtain the parameter string. */\r
318                 pcParameter = FreeRTOS_CLIGetParameter\r
319                                                 (\r
320                                                         pcCommandString,                /* The command string itself. */\r
321                                                         lParameterNumber,               /* Return the next parameter. */\r
322                                                         &lParameterStringLength /* Store the parameter string length. */\r
323                                                 );\r
324 \r
325                 if( pcParameter != NULL )\r
326                 {\r
327                         /* Return the parameter string. */\r
328                         memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
329                         sprintf( pcWriteBuffer, "%d: ", lParameterNumber );\r
330                         strncat( pcWriteBuffer, pcParameter, lParameterStringLength );\r
331                         strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
332 \r
333                         /* There might be more parameters to return after this one. */\r
334                         xReturn = pdTRUE;\r
335                         lParameterNumber++;\r
336                 }\r
337                 else\r
338                 {\r
339                         /* No more parameters were found.  Make sure the write buffer does\r
340                         not contain a valid string. */\r
341                         pcWriteBuffer[ 0 ] = 0x00;\r
342 \r
343                         /* No more data to return. */\r
344                         xReturn = pdFALSE;\r
345 \r
346                         /* Start over the next time this command is executed. */\r
347                         lParameterNumber = 0;\r
348                 }\r
349         }\r
350 \r
351         return xReturn;\r
352 }\r
353 /*-----------------------------------------------------------*/\r
354 \r
355 static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
356 {\r
357 const char *pcParameter;\r
358 BaseType_t lParameterStringLength;\r
359 \r
360         /* Remove compile time warnings about unused parameters, and check the\r
361         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
362         write buffer length is adequate, so does not check for buffer overflows. */\r
363         ( void ) pcCommandString;\r
364         ( void ) xWriteBufferLen;\r
365         configASSERT( pcWriteBuffer );\r
366 \r
367         /* Obtain the parameter string. */\r
368         pcParameter = FreeRTOS_CLIGetParameter\r
369                                         (\r
370                                                 pcCommandString,                /* The command string itself. */\r
371                                                 1,                                              /* Return the first parameter. */\r
372                                                 &lParameterStringLength /* Store the parameter string length. */\r
373                                         );\r
374 \r
375         /* Sanity check something was returned. */\r
376         configASSERT( pcParameter );\r
377 \r
378         /* There are only two valid parameter values. */\r
379         if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )\r
380         {\r
381                 /* Start or restart the trace. */\r
382                 vTraceStop();\r
383                 vTraceClear();\r
384                 uiTraceStart();\r
385 \r
386                 sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );\r
387         }\r
388         else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )\r
389         {\r
390                 /* End the trace, if one is running. */\r
391                 vTraceStop();\r
392                 sprintf( pcWriteBuffer, "Stopping trace recording and dumping log to disk.\r\n" );\r
393                 prvSaveTraceFile();\r
394         }\r
395         else\r
396         {\r
397                 sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );\r
398         }\r
399 \r
400         /* There is no more data to return after this single string, so return\r
401         pdFALSE. */\r
402         return pdFALSE;\r
403 }\r
404 /*-----------------------------------------------------------*/\r
405 \r
406 static void prvSaveTraceFile( void )\r
407 {\r
408 FILE* pxOutputFile;\r
409 \r
410         fopen_s( &pxOutputFile, "Trace.dump", "wb");\r
411 \r
412         if( pxOutputFile != NULL )\r
413         {\r
414                 fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );\r
415                 fclose( pxOutputFile );\r
416                 printf( "\r\nTrace output saved to Trace.dump\r\n" );\r
417         }\r
418         else\r
419         {\r
420                 printf( "\r\nFailed to create trace dump file\r\n" );\r
421         }\r
422 }\r
423 \r