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