]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator / CLI-commands.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /* FreeRTOS includes. */\r
30 #include "FreeRTOS.h"\r
31 #include "task.h"\r
32 \r
33 /* FreeRTOS+CLI includes. */\r
34 #include "FreeRTOS_CLI.h"\r
35 \r
36 /*\r
37  * Writes trace data to a disk file when the trace recording is stopped.\r
38  * This function will simply overwrite any trace files that already exist.\r
39  */\r
40 static void prvSaveTraceFile( void );\r
41 \r
42 /*\r
43  * Defines a command that returns a table showing the state of each task at the\r
44  * time the command is called.\r
45  */\r
46 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
47 \r
48 /*\r
49  * Defines a command that returns a table showing how much time each task has\r
50  * spent in the Running state.\r
51  */\r
52 static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
53 \r
54 /*\r
55  * Defines a command that expects exactly three parameters.  Each of the three\r
56  * parameter are echoed back one at a time.\r
57  */\r
58 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
59 \r
60 /*\r
61  * Defines a command that can take a variable number of parameters.  Each\r
62  * parameter is echoes back one at a time.\r
63  */\r
64 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
65 \r
66 /*\r
67  * Defines a command that starts/stops events being recorded for offline viewing\r
68  * in FreeRTOS+Trace.\r
69  */\r
70 static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
71 \r
72 /* Structure that defines the "run-time-stats" command line command. */\r
73 static const CLI_Command_Definition_t xRunTimeStats =\r
74 {\r
75         "run-time-stats", /* The command string to type. */\r
76         "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n",\r
77         prvRunTimeStatsCommand, /* The function to run. */\r
78         0 /* No parameters are expected. */\r
79 };\r
80 \r
81 /* Structure that defines the "task-stats" command line command. */\r
82 static const CLI_Command_Definition_t xTaskStats =\r
83 {\r
84         "task-stats", /* The command string to type. */\r
85         "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n\r\n",\r
86         prvTaskStatsCommand, /* The function to run. */\r
87         0 /* No parameters are expected. */\r
88 };\r
89 \r
90 /* Structure that defines the "echo_3_parameters" command line command.  This\r
91 takes exactly three parameters that the command simply echos back one at a\r
92 time. */\r
93 static const CLI_Command_Definition_t xThreeParameterEcho =\r
94 {\r
95         "echo_3_parameters",\r
96         "\r\necho_3_parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n\r\n",\r
97         prvThreeParameterEchoCommand, /* The function to run. */\r
98         3 /* Three parameters are expected, which can take any value. */\r
99 };\r
100 \r
101 /* Structure that defines the "echo_parameters" command line command.  This\r
102 takes a variable number of parameters that the command simply echos back one at\r
103 a time. */\r
104 static const CLI_Command_Definition_t xParameterEcho =\r
105 {\r
106         "echo_parameters",\r
107         "\r\necho_parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n\r\n",\r
108         prvParameterEchoCommand, /* The function to run. */\r
109         -1 /* The user can enter any number of commands. */\r
110 };\r
111 \r
112 /* Structure that defines the "trace" command line command.  This takes a single\r
113 parameter, which can be either "start" or "stop". */\r
114 static const CLI_Command_Definition_t xStartTrace =\r
115 {\r
116         "trace",\r
117         "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n\r\n",\r
118         prvStartStopTraceCommand, /* The function to run. */\r
119         1 /* One parameter is expected.  Valid values are "start" and "stop". */\r
120 };\r
121 \r
122 /*-----------------------------------------------------------*/\r
123 \r
124 void vRegisterCLICommands( void )\r
125 {\r
126         /* Register all the command line commands defined immediately above. */\r
127         FreeRTOS_CLIRegisterCommand( &xTaskStats );\r
128         FreeRTOS_CLIRegisterCommand( &xRunTimeStats );\r
129         FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );\r
130         FreeRTOS_CLIRegisterCommand( &xParameterEcho );\r
131         FreeRTOS_CLIRegisterCommand( &xStartTrace );\r
132 }\r
133 /*-----------------------------------------------------------*/\r
134 \r
135 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
136 {\r
137 const char *const pcHeader = "Task          State  Priority  Stack      #\r\n************************************************\r\n";\r
138 \r
139         /* Remove compile time warnings about unused parameters, and check the\r
140         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
141         write buffer length is adequate, so does not check for buffer overflows. */\r
142         ( void ) pcCommandString;\r
143         ( void ) xWriteBufferLen;\r
144         configASSERT( pcWriteBuffer );\r
145 \r
146         /* Generate a table of task stats. */\r
147         strcpy( pcWriteBuffer, pcHeader );\r
148         vTaskList( pcWriteBuffer + strlen( pcHeader ) );\r
149 \r
150         /* There is no more data to return after this single string, so return\r
151         pdFALSE. */\r
152         return pdFALSE;\r
153 }\r
154 /*-----------------------------------------------------------*/\r
155 \r
156 static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
157 {\r
158 const char * const pcHeader = "Task            Abs Time      % Time\r\n****************************************\r\n";\r
159 \r
160         /* Remove compile time warnings about unused parameters, and check the\r
161         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
162         write buffer length is adequate, so does not check for buffer overflows. */\r
163         ( void ) pcCommandString;\r
164         ( void ) xWriteBufferLen;\r
165         configASSERT( pcWriteBuffer );\r
166 \r
167         /* Generate a table of task stats. */\r
168         strcpy( pcWriteBuffer, pcHeader );\r
169         vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );\r
170 \r
171         /* There is no more data to return after this single string, so return\r
172         pdFALSE. */\r
173         return pdFALSE;\r
174 }\r
175 /*-----------------------------------------------------------*/\r
176 \r
177 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
178 {\r
179 const char *pcParameter;\r
180 BaseType_t lParameterStringLength, xReturn;\r
181 static BaseType_t lParameterNumber = 0;\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         if( lParameterNumber == 0 )\r
191         {\r
192                 /* The first time the function is called after the command has been\r
193                 entered just a header string is returned. */\r
194                 sprintf( pcWriteBuffer, "The three parameters were:\r\n" );\r
195 \r
196                 /* Next time the function is called the first parameter will be echoed\r
197                 back. */\r
198                 lParameterNumber = 1L;\r
199 \r
200                 /* There is more data to be returned as no parameters have been echoed\r
201                 back yet. */\r
202                 xReturn = pdPASS;\r
203         }\r
204         else\r
205         {\r
206                 /* Obtain the parameter string. */\r
207                 pcParameter = FreeRTOS_CLIGetParameter\r
208                                                 (\r
209                                                         pcCommandString,                /* The command string itself. */\r
210                                                         lParameterNumber,               /* Return the next parameter. */\r
211                                                         &lParameterStringLength /* Store the parameter string length. */\r
212                                                 );\r
213 \r
214                 /* Sanity check something was returned. */\r
215                 configASSERT( pcParameter );\r
216 \r
217                 /* Return the parameter string. */\r
218                 memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
219                 sprintf( pcWriteBuffer, "%d: ", lParameterNumber );\r
220                 strncat( pcWriteBuffer, pcParameter, lParameterStringLength );\r
221                 strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
222 \r
223                 /* If this is the last of the three parameters then there are no more\r
224                 strings to return after this one. */\r
225                 if( lParameterNumber == 3L )\r
226                 {\r
227                         /* If this is the last of the three parameters then there are no more\r
228                         strings to return after this one. */\r
229                         xReturn = pdFALSE;\r
230                         lParameterNumber = 0L;\r
231                 }\r
232                 else\r
233                 {\r
234                         /* There are more parameters to return after this one. */\r
235                         xReturn = pdTRUE;\r
236                         lParameterNumber++;\r
237                 }\r
238         }\r
239 \r
240         return xReturn;\r
241 }\r
242 /*-----------------------------------------------------------*/\r
243 \r
244 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
245 {\r
246 const char *pcParameter;\r
247 BaseType_t lParameterStringLength, xReturn;\r
248 static BaseType_t lParameterNumber = 0;\r
249 \r
250         /* Remove compile time warnings about unused parameters, and check the\r
251         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
252         write buffer length is adequate, so does not check for buffer overflows. */\r
253         ( void ) pcCommandString;\r
254         ( void ) xWriteBufferLen;\r
255         configASSERT( pcWriteBuffer );\r
256 \r
257         if( lParameterNumber == 0 )\r
258         {\r
259                 /* The first time the function is called after the command has been\r
260                 entered just a header string is returned. */\r
261                 sprintf( pcWriteBuffer, "The parameters were:\r\n" );\r
262 \r
263                 /* Next time the function is called the first parameter will be echoed\r
264                 back. */\r
265                 lParameterNumber = 1L;\r
266 \r
267                 /* There is more data to be returned as no parameters have been echoed\r
268                 back yet. */\r
269                 xReturn = pdPASS;\r
270         }\r
271         else\r
272         {\r
273                 /* Obtain the parameter string. */\r
274                 pcParameter = FreeRTOS_CLIGetParameter\r
275                                                 (\r
276                                                         pcCommandString,                /* The command string itself. */\r
277                                                         lParameterNumber,               /* Return the next parameter. */\r
278                                                         &lParameterStringLength /* Store the parameter string length. */\r
279                                                 );\r
280 \r
281                 if( pcParameter != NULL )\r
282                 {\r
283                         /* Return the parameter string. */\r
284                         memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
285                         sprintf( pcWriteBuffer, "%d: ", lParameterNumber );\r
286                         strncat( pcWriteBuffer, pcParameter, lParameterStringLength );\r
287                         strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
288 \r
289                         /* There might be more parameters to return after this one. */\r
290                         xReturn = pdTRUE;\r
291                         lParameterNumber++;\r
292                 }\r
293                 else\r
294                 {\r
295                         /* No more parameters were found.  Make sure the write buffer does\r
296                         not contain a valid string. */\r
297                         pcWriteBuffer[ 0 ] = 0x00;\r
298 \r
299                         /* No more data to return. */\r
300                         xReturn = pdFALSE;\r
301 \r
302                         /* Start over the next time this command is executed. */\r
303                         lParameterNumber = 0;\r
304                 }\r
305         }\r
306 \r
307         return xReturn;\r
308 }\r
309 /*-----------------------------------------------------------*/\r
310 \r
311 static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
312 {\r
313 const char *pcParameter;\r
314 BaseType_t lParameterStringLength;\r
315 \r
316         /* Remove compile time warnings about unused parameters, and check the\r
317         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
318         write buffer length is adequate, so does not check for buffer overflows. */\r
319         ( void ) pcCommandString;\r
320         ( void ) xWriteBufferLen;\r
321         configASSERT( pcWriteBuffer );\r
322 \r
323         /* Obtain the parameter string. */\r
324         pcParameter = FreeRTOS_CLIGetParameter\r
325                                         (\r
326                                                 pcCommandString,                /* The command string itself. */\r
327                                                 1,                                              /* Return the first parameter. */\r
328                                                 &lParameterStringLength /* Store the parameter string length. */\r
329                                         );\r
330 \r
331         /* Sanity check something was returned. */\r
332         configASSERT( pcParameter );\r
333 \r
334         /* There are only two valid parameter values. */\r
335         if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )\r
336         {\r
337                 /* Start or restart the trace. */\r
338                 vTraceStop();\r
339                 vTraceClear();\r
340                 uiTraceStart();\r
341 \r
342                 sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );\r
343         }\r
344         else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )\r
345         {\r
346                 /* End the trace, if one is running. */\r
347                 vTraceStop();\r
348                 sprintf( pcWriteBuffer, "Stopping trace recording and dumping log to disk.\r\n" );\r
349                 prvSaveTraceFile();\r
350         }\r
351         else\r
352         {\r
353                 sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );\r
354         }\r
355 \r
356         /* There is no more data to return after this single string, so return\r
357         pdFALSE. */\r
358         return pdFALSE;\r
359 }\r
360 /*-----------------------------------------------------------*/\r
361 \r
362 static void prvSaveTraceFile( void )\r
363 {\r
364 FILE* pxOutputFile;\r
365 \r
366         fopen_s( &pxOutputFile, "Trace.dump", "wb");\r
367 \r
368         if( pxOutputFile != NULL )\r
369         {\r
370                 fwrite( RecorderDataPtr, sizeof( RecorderDataType ), 1, pxOutputFile );\r
371                 fclose( pxOutputFile );\r
372                 printf( "\r\nTrace output saved to Trace.dump\r\n" );\r
373         }\r
374         else\r
375         {\r
376                 printf( "\r\nFailed to create trace dump file\r\n" );\r
377         }\r
378 }\r
379 \r