]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
0ee1b62246cb51b91eda5e13d9c604250fbf2fb5
[freertos] / FreeRTOS-Plus / Demo / Common / FreeRTOS_Plus_CLI_Demos / Sample-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 \r
29  /******************************************************************************\r
30  *\r
31  * http://www.FreeRTOS.org/cli\r
32  *\r
33  ******************************************************************************/\r
34 \r
35 \r
36 /* FreeRTOS includes. */\r
37 #include "FreeRTOS.h"\r
38 #include "task.h"\r
39 \r
40 /* Standard includes. */\r
41 #include <stdint.h>\r
42 #include <stdio.h>\r
43 #include <stdlib.h>\r
44 #include <string.h>\r
45 \r
46 /* FreeRTOS+CLI includes. */\r
47 #include "FreeRTOS_CLI.h"\r
48 \r
49 #ifndef  configINCLUDE_TRACE_RELATED_CLI_COMMANDS\r
50         #define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0\r
51 #endif\r
52 \r
53 #ifndef configINCLUDE_QUERY_HEAP_COMMAND\r
54         #define configINCLUDE_QUERY_HEAP_COMMAND 0\r
55 #endif\r
56 \r
57 /*\r
58  * The function that registers the commands that are defined within this file.\r
59  */\r
60 void vRegisterSampleCLICommands( void );\r
61 \r
62 /*\r
63  * Implements the task-stats command.\r
64  */\r
65 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
66 \r
67 /*\r
68  * Implements the run-time-stats command.\r
69  */\r
70 #if( configGENERATE_RUN_TIME_STATS == 1 )\r
71         static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
72 #endif /* configGENERATE_RUN_TIME_STATS */\r
73 \r
74 /*\r
75  * Implements the echo-three-parameters command.\r
76  */\r
77 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
78 \r
79 /*\r
80  * Implements the echo-parameters command.\r
81  */\r
82 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
83 \r
84 /*\r
85  * Implements the "query heap" command.\r
86  */\r
87 #if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )\r
88         static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
89 #endif\r
90 \r
91 /*\r
92  * Implements the "trace start" and "trace stop" commands;\r
93  */\r
94 #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )\r
95         static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );\r
96 #endif\r
97 \r
98 /* Structure that defines the "task-stats" command line command.  This generates\r
99 a table that gives information on each task in the system. */\r
100 static const CLI_Command_Definition_t xTaskStats =\r
101 {\r
102         "task-stats", /* The command string to type. */\r
103         "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",\r
104         prvTaskStatsCommand, /* The function to run. */\r
105         0 /* No parameters are expected. */\r
106 };\r
107 \r
108 /* Structure that defines the "echo_3_parameters" command line command.  This\r
109 takes exactly three parameters that the command simply echos back one at a\r
110 time. */\r
111 static const CLI_Command_Definition_t xThreeParameterEcho =\r
112 {\r
113         "echo-3-parameters",\r
114         "\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",\r
115         prvThreeParameterEchoCommand, /* The function to run. */\r
116         3 /* Three parameters are expected, which can take any value. */\r
117 };\r
118 \r
119 /* Structure that defines the "echo_parameters" command line command.  This\r
120 takes a variable number of parameters that the command simply echos back one at\r
121 a time. */\r
122 static const CLI_Command_Definition_t xParameterEcho =\r
123 {\r
124         "echo-parameters",\r
125         "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",\r
126         prvParameterEchoCommand, /* The function to run. */\r
127         -1 /* The user can enter any number of commands. */\r
128 };\r
129 \r
130 #if( configGENERATE_RUN_TIME_STATS == 1 )\r
131         /* Structure that defines the "run-time-stats" command line command.   This\r
132         generates a table that shows how much run time each task has */\r
133         static const CLI_Command_Definition_t xRunTimeStats =\r
134         {\r
135                 "run-time-stats", /* The command string to type. */\r
136                 "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",\r
137                 prvRunTimeStatsCommand, /* The function to run. */\r
138                 0 /* No parameters are expected. */\r
139         };\r
140 #endif /* configGENERATE_RUN_TIME_STATS */\r
141 \r
142 #if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )\r
143         /* Structure that defines the "query_heap" command line command. */\r
144         static const CLI_Command_Definition_t xQueryHeap =\r
145         {\r
146                 "query-heap",\r
147                 "\r\nquery-heap:\r\n Displays the free heap space, and minimum ever free heap space.\r\n",\r
148                 prvQueryHeapCommand, /* The function to run. */\r
149                 0 /* The user can enter any number of commands. */\r
150         };\r
151 #endif /* configQUERY_HEAP_COMMAND */\r
152 \r
153 #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
154         /* Structure that defines the "trace" command line command.  This takes a single\r
155         parameter, which can be either "start" or "stop". */\r
156         static const CLI_Command_Definition_t xStartStopTrace =\r
157         {\r
158                 "trace",\r
159                 "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",\r
160                 prvStartStopTraceCommand, /* The function to run. */\r
161                 1 /* One parameter is expected.  Valid values are "start" and "stop". */\r
162         };\r
163 #endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r
164 \r
165 /*-----------------------------------------------------------*/\r
166 \r
167 void vRegisterSampleCLICommands( void )\r
168 {\r
169         /* Register all the command line commands defined immediately above. */\r
170         FreeRTOS_CLIRegisterCommand( &xTaskStats );     \r
171         FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );\r
172         FreeRTOS_CLIRegisterCommand( &xParameterEcho );\r
173 \r
174         #if( configGENERATE_RUN_TIME_STATS == 1 )\r
175         {\r
176                 FreeRTOS_CLIRegisterCommand( &xRunTimeStats );\r
177         }\r
178         #endif\r
179         \r
180         #if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )\r
181         {\r
182                 FreeRTOS_CLIRegisterCommand( &xQueryHeap );\r
183         }\r
184         #endif\r
185 \r
186         #if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )\r
187         {\r
188                 FreeRTOS_CLIRegisterCommand( &xStartStopTrace );\r
189         }\r
190         #endif\r
191 }\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 static BaseType_t prvTaskStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
195 {\r
196 const char *const pcHeader = "     State   Priority  Stack    #\r\n************************************************\r\n";\r
197 BaseType_t xSpacePadding;\r
198 \r
199         /* Remove compile time warnings about unused parameters, and check the\r
200         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
201         write buffer length is adequate, so does not check for buffer overflows. */\r
202         ( void ) pcCommandString;\r
203         ( void ) xWriteBufferLen;\r
204         configASSERT( pcWriteBuffer );\r
205 \r
206         /* Generate a table of task stats. */\r
207         strcpy( pcWriteBuffer, "Task" );\r
208         pcWriteBuffer += strlen( pcWriteBuffer );\r
209 \r
210         /* Minus three for the null terminator and half the number of characters in\r
211         "Task" so the column lines up with the centre of the heading. */\r
212         configASSERT( configMAX_TASK_NAME_LEN > 3 );\r
213         for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )\r
214         {\r
215                 /* Add a space to align columns after the task's name. */\r
216                 *pcWriteBuffer = ' ';\r
217                 pcWriteBuffer++;\r
218 \r
219                 /* Ensure always terminated. */\r
220                 *pcWriteBuffer = 0x00;\r
221         }\r
222         strcpy( pcWriteBuffer, pcHeader );\r
223         vTaskList( pcWriteBuffer + strlen( pcHeader ) );\r
224 \r
225         /* There is no more data to return after this single string, so return\r
226         pdFALSE. */\r
227         return pdFALSE;\r
228 }\r
229 /*-----------------------------------------------------------*/\r
230 \r
231 #if( configINCLUDE_QUERY_HEAP_COMMAND == 1 )\r
232 \r
233         static BaseType_t prvQueryHeapCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
234         {\r
235                 /* Remove compile time warnings about unused parameters, and check the\r
236                 write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
237                 write buffer length is adequate, so does not check for buffer overflows. */\r
238                 ( void ) pcCommandString;\r
239                 ( void ) xWriteBufferLen;\r
240                 configASSERT( pcWriteBuffer );\r
241 \r
242                 sprintf( pcWriteBuffer, "Current free heap %d bytes, minimum ever free heap %d bytes\r\n", ( int ) xPortGetFreeHeapSize(), ( int ) xPortGetMinimumEverFreeHeapSize() );\r
243 \r
244                 /* There is no more data to return after this single string, so return\r
245                 pdFALSE. */\r
246                 return pdFALSE;\r
247         }\r
248 \r
249 #endif /* configINCLUDE_QUERY_HEAP */\r
250 /*-----------------------------------------------------------*/\r
251 \r
252 #if( configGENERATE_RUN_TIME_STATS == 1 )\r
253         \r
254         static BaseType_t prvRunTimeStatsCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
255         {\r
256         const char * const pcHeader = "  Abs Time      % Time\r\n****************************************\r\n";\r
257         BaseType_t xSpacePadding;\r
258 \r
259                 /* Remove compile time warnings about unused parameters, and check the\r
260                 write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
261                 write buffer length is adequate, so does not check for buffer overflows. */\r
262                 ( void ) pcCommandString;\r
263                 ( void ) xWriteBufferLen;\r
264                 configASSERT( pcWriteBuffer );\r
265 \r
266                 /* Generate a table of task stats. */\r
267                 strcpy( pcWriteBuffer, "Task" );\r
268                 pcWriteBuffer += strlen( pcWriteBuffer );\r
269 \r
270                 /* Pad the string "task" with however many bytes necessary to make it the\r
271                 length of a task name.  Minus three for the null terminator and half the\r
272                 number of characters in "Task" so the column lines up with the centre of\r
273                 the heading. */\r
274                 for( xSpacePadding = strlen( "Task" ); xSpacePadding < ( configMAX_TASK_NAME_LEN - 3 ); xSpacePadding++ )\r
275                 {\r
276                         /* Add a space to align columns after the task's name. */\r
277                         *pcWriteBuffer = ' ';\r
278                         pcWriteBuffer++;\r
279 \r
280                         /* Ensure always terminated. */\r
281                         *pcWriteBuffer = 0x00;\r
282                 }\r
283 \r
284                 strcpy( pcWriteBuffer, pcHeader );\r
285                 vTaskGetRunTimeStats( pcWriteBuffer + strlen( pcHeader ) );\r
286 \r
287                 /* There is no more data to return after this single string, so return\r
288                 pdFALSE. */\r
289                 return pdFALSE;\r
290         }\r
291         \r
292 #endif /* configGENERATE_RUN_TIME_STATS */\r
293 /*-----------------------------------------------------------*/\r
294 \r
295 static BaseType_t prvThreeParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
296 {\r
297 const char *pcParameter;\r
298 BaseType_t xParameterStringLength, xReturn;\r
299 static UBaseType_t uxParameterNumber = 0;\r
300 \r
301         /* Remove compile time warnings about unused parameters, and check the\r
302         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
303         write buffer length is adequate, so does not check for buffer overflows. */\r
304         ( void ) pcCommandString;\r
305         ( void ) xWriteBufferLen;\r
306         configASSERT( pcWriteBuffer );\r
307 \r
308         if( uxParameterNumber == 0 )\r
309         {\r
310                 /* The first time the function is called after the command has been\r
311                 entered just a header string is returned. */\r
312                 sprintf( pcWriteBuffer, "The three parameters were:\r\n" );\r
313 \r
314                 /* Next time the function is called the first parameter will be echoed\r
315                 back. */\r
316                 uxParameterNumber = 1U;\r
317 \r
318                 /* There is more data to be returned as no parameters have been echoed\r
319                 back yet. */\r
320                 xReturn = pdPASS;\r
321         }\r
322         else\r
323         {\r
324                 /* Obtain the parameter string. */\r
325                 pcParameter = FreeRTOS_CLIGetParameter\r
326                                                 (\r
327                                                         pcCommandString,                /* The command string itself. */\r
328                                                         uxParameterNumber,              /* Return the next parameter. */\r
329                                                         &xParameterStringLength /* Store the parameter string length. */\r
330                                                 );\r
331 \r
332                 /* Sanity check something was returned. */\r
333                 configASSERT( pcParameter );\r
334 \r
335                 /* Return the parameter string. */\r
336                 memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
337                 sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber );\r
338                 strncat( pcWriteBuffer, pcParameter, ( size_t ) xParameterStringLength );\r
339                 strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
340 \r
341                 /* If this is the last of the three parameters then there are no more\r
342                 strings to return after this one. */\r
343                 if( uxParameterNumber == 3U )\r
344                 {\r
345                         /* If this is the last of the three parameters then there are no more\r
346                         strings to return after this one. */\r
347                         xReturn = pdFALSE;\r
348                         uxParameterNumber = 0;\r
349                 }\r
350                 else\r
351                 {\r
352                         /* There are more parameters to return after this one. */\r
353                         xReturn = pdTRUE;\r
354                         uxParameterNumber++;\r
355                 }\r
356         }\r
357 \r
358         return xReturn;\r
359 }\r
360 /*-----------------------------------------------------------*/\r
361 \r
362 static BaseType_t prvParameterEchoCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
363 {\r
364 const char *pcParameter;\r
365 BaseType_t xParameterStringLength, xReturn;\r
366 static UBaseType_t uxParameterNumber = 0;\r
367 \r
368         /* Remove compile time warnings about unused parameters, and check the\r
369         write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
370         write buffer length is adequate, so does not check for buffer overflows. */\r
371         ( void ) pcCommandString;\r
372         ( void ) xWriteBufferLen;\r
373         configASSERT( pcWriteBuffer );\r
374 \r
375         if( uxParameterNumber == 0 )\r
376         {\r
377                 /* The first time the function is called after the command has been\r
378                 entered just a header string is returned. */\r
379                 sprintf( pcWriteBuffer, "The parameters were:\r\n" );\r
380 \r
381                 /* Next time the function is called the first parameter will be echoed\r
382                 back. */\r
383                 uxParameterNumber = 1U;\r
384 \r
385                 /* There is more data to be returned as no parameters have been echoed\r
386                 back yet. */\r
387                 xReturn = pdPASS;\r
388         }\r
389         else\r
390         {\r
391                 /* Obtain the parameter string. */\r
392                 pcParameter = FreeRTOS_CLIGetParameter\r
393                                                 (\r
394                                                         pcCommandString,                /* The command string itself. */\r
395                                                         uxParameterNumber,              /* Return the next parameter. */\r
396                                                         &xParameterStringLength /* Store the parameter string length. */\r
397                                                 );\r
398 \r
399                 if( pcParameter != NULL )\r
400                 {\r
401                         /* Return the parameter string. */\r
402                         memset( pcWriteBuffer, 0x00, xWriteBufferLen );\r
403                         sprintf( pcWriteBuffer, "%d: ", ( int ) uxParameterNumber );\r
404                         strncat( pcWriteBuffer, ( char * ) pcParameter, ( size_t ) xParameterStringLength );\r
405                         strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ) );\r
406 \r
407                         /* There might be more parameters to return after this one. */\r
408                         xReturn = pdTRUE;\r
409                         uxParameterNumber++;\r
410                 }\r
411                 else\r
412                 {\r
413                         /* No more parameters were found.  Make sure the write buffer does\r
414                         not contain a valid string. */\r
415                         pcWriteBuffer[ 0 ] = 0x00;\r
416 \r
417                         /* No more data to return. */\r
418                         xReturn = pdFALSE;\r
419 \r
420                         /* Start over the next time this command is executed. */\r
421                         uxParameterNumber = 0;\r
422                 }\r
423         }\r
424 \r
425         return xReturn;\r
426 }\r
427 /*-----------------------------------------------------------*/\r
428 \r
429 #if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1\r
430 \r
431         static BaseType_t prvStartStopTraceCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )\r
432         {\r
433         const char *pcParameter;\r
434         BaseType_t lParameterStringLength;\r
435 \r
436                 /* Remove compile time warnings about unused parameters, and check the\r
437                 write buffer is not NULL.  NOTE - for simplicity, this example assumes the\r
438                 write buffer length is adequate, so does not check for buffer overflows. */\r
439                 ( void ) pcCommandString;\r
440                 ( void ) xWriteBufferLen;\r
441                 configASSERT( pcWriteBuffer );\r
442 \r
443                 /* Obtain the parameter string. */\r
444                 pcParameter = FreeRTOS_CLIGetParameter\r
445                                                 (\r
446                                                         pcCommandString,                /* The command string itself. */\r
447                                                         1,                                              /* Return the first parameter. */\r
448                                                         &lParameterStringLength /* Store the parameter string length. */\r
449                                                 );\r
450 \r
451                 /* Sanity check something was returned. */\r
452                 configASSERT( pcParameter );\r
453 \r
454                 /* There are only two valid parameter values. */\r
455                 if( strncmp( pcParameter, "start", strlen( "start" ) ) == 0 )\r
456                 {\r
457                         /* Start or restart the trace. */\r
458                         vTraceStop();\r
459                         vTraceClear();\r
460                         vTraceStart();\r
461 \r
462                         sprintf( pcWriteBuffer, "Trace recording (re)started.\r\n" );\r
463                 }\r
464                 else if( strncmp( pcParameter, "stop", strlen( "stop" ) ) == 0 )\r
465                 {\r
466                         /* End the trace, if one is running. */\r
467                         vTraceStop();\r
468                         sprintf( pcWriteBuffer, "Stopping trace recording.\r\n" );\r
469                 }\r
470                 else\r
471                 {\r
472                         sprintf( pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );\r
473                 }\r
474 \r
475                 /* There is no more data to return after this single string, so return\r
476                 pdFALSE. */\r
477                 return pdFALSE;\r
478         }\r
479 \r
480 #endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */\r