SAM4S-EK_FreeRTOS+FAT-SL  1.0
An example project to test the functionality of FreeRTOS+FAT-SL using SD card as data storage medium
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
FreeRTOS_CLI.c
Go to the documentation of this file.
1 /*
2  * FreeRTOS+CLI V1.0.3 (C) 2014 Real Time Engineers ltd. All rights reserved.
3  *
4  * This file is part of the FreeRTOS+CLI distribution. The FreeRTOS+CLI license
5  * terms are different to the FreeRTOS license terms.
6  *
7  * FreeRTOS+CLI uses a dual license model that allows the software to be used
8  * under a standard GPL open source license, or a commercial license. The
9  * standard GPL license (unlike the modified GPL license under which FreeRTOS
10  * itself is distributed) requires that all software statically linked with
11  * FreeRTOS+CLI is also distributed under the same GPL V2 license terms.
12  * Details of both license options follow:
13  *
14  * - Open source licensing -
15  * FreeRTOS+CLI is a free download and may be used, modified, evaluated and
16  * distributed without charge provided the user adheres to version two of the
17  * GNU General Public License (GPL) and does not remove the copyright notice or
18  * this text. The GPL V2 text is available on the gnu.org web site, and on the
19  * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
20  *
21  * - Commercial licensing -
22  * Businesses and individuals that for commercial or other reasons cannot comply
23  * with the terms of the GPL V2 license must obtain a low cost commercial
24  * license before incorporating FreeRTOS+CLI into proprietary software for
25  * distribution in any form. Commercial licenses can be purchased from
26  * http://shop.freertos.org/cli and do not require any source files to be
27  * changed.
28  *
29  * FreeRTOS+CLI is distributed in the hope that it will be useful. You cannot
30  * use FreeRTOS+CLI unless you agree that you use the software 'as is'.
31  * FreeRTOS+CLI is provided WITHOUT ANY WARRANTY; without even the implied
32  * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
33  * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
34  * implied, expressed, or statutory.
35  *
36  * 1 tab == 4 spaces!
37  *
38  * http://www.FreeRTOS.org
39  * http://www.FreeRTOS.org/FreeRTOS-Plus
40  *
41  */
42 
43 /* Standard includes. */
44 #include <string.h>
45 #include <stdint.h>
46 
47 /* FreeRTOS includes. */
48 #include "FreeRTOS.h"
49 #include "task.h"
50 
51 /* Utils includes. */
52 #include "FreeRTOS_CLI.h"
53 
54 typedef struct xCOMMAND_INPUT_LIST
55 {
59 
60 /*
61  * The callback function that is executed when "help" is entered. This is the
62  * only default command that is always present.
63  */
64 static portBASE_TYPE prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
65 
66 /*
67  * Return the number of parameters that follow the command name.
68  */
69 static int8_t prvGetNumberOfParameters( const char *pcCommandString );
70 
71 /* The definition of the "help" command. This command is always at the front
72 of the list of registered commands. */
73 static const CLI_Command_Definition_t xHelpCommand =
74 {
75  "help",
76  "\r\nhelp:\r\n Lists all the registered commands\r\n\r\n",
77  prvHelpCommand,
78  0
79 };
80 
81 /* The definition of the list of commands. Commands that are registered are
82 added to this list. */
83 static CLI_Definition_List_Item_t xRegisteredCommands =
84 {
85  &xHelpCommand, /* The first command in the list is always the help command, defined in this file. */
86  NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */
87 };
88 
89 /* A buffer into which command outputs can be written is declared here, rather
90 than in the command console implementation, to allow multiple command consoles
91 to share the same buffer. For example, an application may allow access to the
92 command interpreter by UART and by Ethernet. Sharing a buffer is done purely
93 to save RAM. Note, however, that the command console itself is not re-entrant,
94 so only one command interpreter interface can be used at any one time. For that
95 reason, no attempt at providing mutual exclusion to the cOutputBuffer array is
96 attempted. */
97 static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
98 
99 /*-----------------------------------------------------------*/
100 
102 {
103 static CLI_Definition_List_Item_t *pxLastCommandInList = &xRegisteredCommands;
104 CLI_Definition_List_Item_t *pxNewListItem;
105 portBASE_TYPE xReturn = pdFAIL;
106 
107  /* Check the parameter is not NULL. */
108  configASSERT( pxCommandToRegister );
109 
110  /* Create a new list item that will reference the command being registered. */
111  pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) );
112  configASSERT( pxNewListItem );
113 
114  if( pxNewListItem != NULL )
115  {
117  {
118  /* Reference the command being registered from the newly created
119  list item. */
120  pxNewListItem->pxCommandLineDefinition = pxCommandToRegister;
121 
122  /* The new list item will get added to the end of the list, so
123  pxNext has nowhere to point. */
124  pxNewListItem->pxNext = NULL;
125 
126  /* Add the newly created list item to the end of the already existing
127  list. */
128  pxLastCommandInList->pxNext = pxNewListItem;
129 
130  /* Set the end of list marker to the new list item. */
131  pxLastCommandInList = pxNewListItem;
132  }
134 
135  xReturn = pdPASS;
136  }
137 
138  return xReturn;
139 }
140 /*-----------------------------------------------------------*/
141 
142 portBASE_TYPE FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen )
143 {
144 static const CLI_Definition_List_Item_t *pxCommand = NULL;
145 portBASE_TYPE xReturn = pdTRUE;
146 const char *pcRegisteredCommandString;
147 size_t xCommandStringLength;
148 
149  /* Note: This function is not re-entrant. It must not be called from more
150  thank one task. */
151 
152  if( pxCommand == NULL )
153  {
154  /* Search for the command string in the list of registered commands. */
155  for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext )
156  {
157  pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand;
158  xCommandStringLength = strlen( pcRegisteredCommandString );
159 
160  /* To ensure the string lengths match exactly, so as not to pick up
161  a sub-string of a longer command, check the byte after the expected
162  end of the string is either the end of the string or a space before
163  a parameter. */
164  if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) )
165  {
166  if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 )
167  {
168  /* The command has been found. Check it has the expected
169  number of parameters. If cExpectedNumberOfParameters is -1,
170  then there could be a variable number of parameters and no
171  check is made. */
173  {
174  if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters )
175  {
176  xReturn = pdFALSE;
177  }
178  }
179 
180  break;
181  }
182  }
183  }
184  }
185 
186  if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) )
187  {
188  /* The command was found, but the number of parameters with the command
189  was incorrect. */
190  strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen );
191  pxCommand = NULL;
192  }
193  else if( pxCommand != NULL )
194  {
195  /* Call the callback function that is registered to this command. */
196  xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput );
197 
198  /* If xReturn is pdFALSE, then no further strings will be returned
199  after this one, and pxCommand can be reset to NULL ready to search
200  for the next entered command. */
201  if( xReturn == pdFALSE )
202  {
203  pxCommand = NULL;
204  }
205  }
206  else
207  {
208  /* pxCommand was NULL, the command was not found. */
209  strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n\r\n", xWriteBufferLen );
210  xReturn = pdFALSE;
211  }
212 
213  return xReturn;
214 }
215 /*-----------------------------------------------------------*/
216 
218 {
219  return cOutputBuffer;
220 }
221 /*-----------------------------------------------------------*/
222 
223 const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, unsigned portBASE_TYPE uxWantedParameter, portBASE_TYPE *pxParameterStringLength )
224 {
225 unsigned portBASE_TYPE uxParametersFound = 0;
226 const char *pcReturn = NULL;
227 
228  *pxParameterStringLength = 0;
229 
230  while( uxParametersFound < uxWantedParameter )
231  {
232  /* Index the character pointer past the current word. If this is the start
233  of the command string then the first word is the command itself. */
234  while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
235  {
236  pcCommandString++;
237  }
238 
239  /* Find the start of the next string. */
240  while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) )
241  {
242  pcCommandString++;
243  }
244 
245  /* Was a string found? */
246  if( *pcCommandString != 0x00 )
247  {
248  /* Is this the start of the required parameter? */
249  uxParametersFound++;
250 
251  if( uxParametersFound == uxWantedParameter )
252  {
253  /* How long is the parameter? */
254  pcReturn = pcCommandString;
255  while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
256  {
257  ( *pxParameterStringLength )++;
258  pcCommandString++;
259  }
260 
261  if( *pxParameterStringLength == 0 )
262  {
263  pcReturn = NULL;
264  }
265 
266  break;
267  }
268  }
269  else
270  {
271  break;
272  }
273  }
274 
275  return pcReturn;
276 }
277 /*-----------------------------------------------------------*/
278 
279 static portBASE_TYPE prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
280 {
281 static const CLI_Definition_List_Item_t * pxCommand = NULL;
282 signed portBASE_TYPE xReturn;
283 
284  ( void ) pcCommandString;
285 
286  if( pxCommand == NULL )
287  {
288  /* Reset the pxCommand pointer back to the start of the list. */
289  pxCommand = &xRegisteredCommands;
290  }
291 
292  /* Return the next command help string, before moving the pointer on to
293  the next command in the list. */
294  strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen );
295  pxCommand = pxCommand->pxNext;
296 
297  if( pxCommand == NULL )
298  {
299  /* There are no more commands in the list, so there will be no more
300  strings to return after this one and pdFALSE should be returned. */
301  xReturn = pdFALSE;
302  }
303  else
304  {
305  xReturn = pdTRUE;
306  }
307 
308  return xReturn;
309 }
310 /*-----------------------------------------------------------*/
311 
312 static int8_t prvGetNumberOfParameters( const char *pcCommandString )
313 {
314 int8_t cParameters = 0;
315 portBASE_TYPE xLastCharacterWasSpace = pdFALSE;
316 
317  /* Count the number of space delimited words in pcCommandString. */
318  while( *pcCommandString != 0x00 )
319  {
320  if( ( *pcCommandString ) == ' ' )
321  {
322  if( xLastCharacterWasSpace != pdTRUE )
323  {
324  cParameters++;
325  xLastCharacterWasSpace = pdTRUE;
326  }
327  }
328  else
329  {
330  xLastCharacterWasSpace = pdFALSE;
331  }
332 
333  pcCommandString++;
334  }
335 
336  /* If the command string ended with spaces, then there will have been too
337  many parameters counted. */
338  if( xLastCharacterWasSpace == pdTRUE )
339  {
340  cParameters--;
341  }
342 
343  /* The value returned is one less than the number of space delimited words,
344  as the first word should be the command itself. */
345  return cParameters;
346 }
347 
#define pdTRUE
Definition: projdefs.h:76
#define taskEXIT_CRITICAL()
Definition: task.h:216
struct xCOMMAND_INPUT_LIST CLI_Definition_List_Item_t
#define configASSERT(x)
portBASE_TYPE FreeRTOS_CLIRegisterCommand(const CLI_Command_Definition_t *const pxCommandToRegister)
Definition: FreeRTOS_CLI.c:101
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:147
int8_t cExpectedNumberOfParameters
Definition: FreeRTOS_CLI.h:60
portBASE_TYPE FreeRTOS_CLIProcessCommand(const char *const pcCommandInput, char *pcWriteBuffer, size_t xWriteBufferLen)
Definition: FreeRTOS_CLI.c:142
const char *const pcHelpString
Definition: FreeRTOS_CLI.h:58
#define configCOMMAND_INT_MAX_OUTPUT_SIZE
struct xCOMMAND_INPUT_LIST * pxNext
Definition: FreeRTOS_CLI.c:57
const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter
Definition: FreeRTOS_CLI.h:59
#define pdFAIL
Definition: projdefs.h:79
#define pdPASS
Definition: projdefs.h:78
#define pdFALSE
Definition: projdefs.h:75
const char * FreeRTOS_CLIGetParameter(const char *pcCommandString, unsigned portBASE_TYPE uxWantedParameter, portBASE_TYPE *pxParameterStringLength)
Definition: FreeRTOS_CLI.c:223
#define taskENTER_CRITICAL()
Definition: task.h:202
const CLI_Command_Definition_t * pxCommandLineDefinition
Definition: FreeRTOS_CLI.c:56
#define portBASE_TYPE
Definition: portmacro.h:91
const char *const pcCommand
Definition: FreeRTOS_CLI.h:57
char * FreeRTOS_CLIGetOutputBuffer(void)
Definition: FreeRTOS_CLI.c:217