#include "task.h"\r
#include "CommandInterpreter.h"\r
\r
+typedef struct xCOMMAND_INPUT_LIST\r
+{\r
+ const xCommandLineInput *pxCommandLineDefinition;\r
+ struct xCOMMAND_INPUT_LIST *pxNext;\r
+} xCommandLineInputListItem;\r
+\r
/*\r
* The callback function that is executed when "help" is entered. This is the\r
* only default command that is always present.\r
\r
/* The definition of the "help" command. This command is always at the front\r
of the list of registered commands. */\r
-const xCommandLineInput xHelpCommand = \r
+static const xCommandLineInput xHelpCommand = \r
{\r
"help",\r
"help: Lists all the registered commands\r\n",\r
- prvHelpCommand,\r
- NULL\r
+ prvHelpCommand\r
+};\r
+\r
+/* The definition of the list of commands. Commands that are registered are\r
+added to this list. */\r
+static xCommandLineInputListItem xRegisteredCommands =\r
+{ \r
+ &xHelpCommand, /* The first command in the list is always the help command, defined in this file. */\r
+ NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */\r
};\r
\r
/*-----------------------------------------------------------*/\r
\r
-void vCmdIntRegisterCommand( const xCommandLineInput *pxCommandToRegister )\r
+portBASE_TYPE xCmdIntRegisterCommand( const xCommandLineInput * const pxCommandToRegister )\r
{\r
-/* Used to point to the last command in the list of registered command, just to\r
-make registering commands faster. */\r
-static xCommandLineInput *pxLastCommandInList = &xHelpCommand;\r
+static xCommandLineInputListItem *pxLastCommandInList = &xRegisteredCommands;\r
+xCommandLineInputListItem *pxNewListItem;\r
+portBASE_TYPE xReturn = pdFAIL;\r
+\r
+ /* Check the parameter is not NULL. */\r
+ configASSERT( pxCommandToRegister );\r
+\r
+ /* Create a new list item that will reference the command being registered. */\r
+ pxNewListItem = ( xCommandLineInputListItem * ) pvPortMalloc( sizeof( xCommandLineInputListItem ) );\r
+ configASSERT( pxNewListItem );\r
+\r
+ if( pxNewListItem != NULL )\r
+ {\r
+ taskENTER_CRITICAL();\r
+ {\r
+ /* Reference the command being registered from the newly created \r
+ list item. */\r
+ pxNewListItem->pxCommandLineDefinition = pxCommandToRegister;\r
\r
- configASSERT( pxLastCommandInList );\r
- pxLastCommandInList->pxNext = pxCommandToRegister;\r
- pxLastCommandInLIst = pxCommandToRegister;\r
+ /* The new list item will get added to the end of the list, so \r
+ pxNext has nowhere to point. */\r
+ pxNewListItem->pxNext = NULL;\r
+\r
+ /* Add the newly created list item to the end of the already existing\r
+ list. */\r
+ pxLastCommandInList->pxNext = pxNewListItem;\r
+\r
+ /* Set the end of list marker to the new list item. */\r
+ pxLastCommandInList = pxNewListItem;\r
+ }\r
+ \r
+ xReturn = pdPASS;\r
+ }\r
+\r
+ return xReturn;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-const signed char *pcCmdIntProcessCommand( const signed char *pcCommandInput )\r
+const signed char *pcCmdIntProcessCommand( const signed char * const pcCommandInput )\r
{\r
-static const xCommandLineInput *pxCommand = NULL;\r
+static const xCommandLineInputListItem *pxCommand = NULL;\r
signed const char *pcReturn = NULL;\r
- \r
+\r
+ /* Note: This function is not re-entrant. It must not be called from more\r
+ thank one task. */\r
+\r
if( pxCommand == NULL )\r
{\r
/* Search for the command string in the list of registered commands. */\r
- for( pxCommand = &xHelpCommand; pxCommand != NULL; pxCommand = pxCommand->pxNext )\r
+ for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext )\r
{\r
- if( strcmp( ( const char * ) pcCommandInput, ( const char * ) pxCommand->pcCommand ) == 0 )\r
+ if( strcmp( ( const char * ) pcCommandInput, ( const char * ) pxCommand->pxCommandLineDefinition->pcCommand ) == 0 )\r
{\r
/* The command has been found, the loop can exit so the command\r
can be executed. */\r
\r
if( pxCommand != NULL )\r
{\r
- pcReturn = pxCommand->pxCommandInterpreter();\r
+ pcReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter();\r
\r
/* If no strings were returned, then all the strings that are going to\r
be returned by the current command have already been returned, and\r
}\r
else\r
{\r
- pcReturn = "Command not recognised\r\n\r\n";\r
- pxCommand = &xHelpCommand;\r
+ pcReturn = "Command not recognised. Available commands are listed below.\r\n\r\n";\r
+\r
+ /* Print out the help string. */\r
+ pxCommand = &xRegisteredCommands;\r
}\r
\r
return pcReturn;\r
\r
static const signed char *prvHelpCommand( void )\r
{\r
-static const xCommandLineInput * pxCommand = &xHelpCommand;\r
+static const xCommandLineInputListItem * pxCommand = &xRegisteredCommands;\r
signed const char *pcReturn;\r
\r
/* pxCommand will be NULL if all the commands in the list have already been\r
{\r
/* Return the next command help string, before moving the pointer on to\r
the next command in the list. */\r
- pcReturn = pxCommand->pcHelpString;\r
+ pcReturn = pxCommand->pxCommandLineDefinition->pcHelpString;\r
pxCommand = pxCommand->pxNext;\r
}\r
else\r
{\r
/* Reset the pointer back to the start of the list. */\r
- pxCommand = &xHelpCommand;\r
+ pxCommand = &xRegisteredCommands;\r
\r
/* Return NULL to show that there are no more strings to return. */\r
pcReturn = NULL;\r
should be defined by declaring a const structure of this type. */\r
typedef struct xCOMMAND_LINE_INPUT\r
{\r
- const signed char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */\r
- const signed char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For exxample "help: Returns a list of all the commands\r\n". */\r
- pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */\r
- const struct xCOMMAND_LINE_INPUT *pxNext; /* A pointer to the next xCommandLinInput structure. This should be NULL when the command is defined. It will get filled in automatically when the command is registered. */\r
+ const signed char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */\r
+ const signed char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For exxample "help: Returns a list of all the commands\r\n". */\r
+ const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */\r
} xCommandLineInput;\r
\r
/*\r
* handled by the command interpreter. Once a command has been registered it\r
* can be executed from the command line.\r
*/\r
-void vCmdIntRegisterCommand( const xCommandLineInput *pxCommandToRegister );\r
+portBASE_TYPE xCmdIntRegisterCommand( const xCommandLineInput * const pxCommandToRegister );\r
\r
/*\r
* Runns the command interpreter for the command string "pcCommandInput". If\r
* pcCmdIntProcessCommand is not reentrant. It must not be called from more\r
* than one task - or at least - by more than one task at a time.\r
*/\r
-const signed char *pcCmdIntProcessCommand( const signed char *pcCommandInput );\r
+const signed char *pcCmdIntProcessCommand( const signed char * const pcCommandInput );\r
\r
#endif /* COMMAND_INTERPRETER_H */\r
\r