The CommandProcessor is the interface to install a run-time menu into an embedded system.
Dependents: A_CANAdapter USB2I2C
CommandProcessor.h@1:1c81feb2f8bd, 2011-03-20 (annotated)
- Committer:
- WiredHome
- Date:
- Sun Mar 20 21:54:25 2011 +0000
- Revision:
- 1:1c81feb2f8bd
- Parent:
- 0:198f53da1bc8
- Child:
- 2:14cafb06b4c5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:198f53da1bc8 | 1 | /// @file CommandProcessor.h defined the interface to the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 2 | /// |
WiredHome | 0:198f53da1bc8 | 3 | /// @mainpage |
WiredHome | 0:198f53da1bc8 | 4 | /// The CommandProcessor is the interface to install a run-time menu into an embedded system. |
WiredHome | 0:198f53da1bc8 | 5 | /// This contains the complete interface to the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 6 | /// |
WiredHome | 0:198f53da1bc8 | 7 | /// @version 1.0 |
WiredHome | 0:198f53da1bc8 | 8 | /// |
WiredHome | 0:198f53da1bc8 | 9 | /// @note The CommandProcessor is text-based, because it is intended to interact with a |
WiredHome | 0:198f53da1bc8 | 10 | /// user. |
WiredHome | 0:198f53da1bc8 | 11 | /// |
WiredHome | 0:198f53da1bc8 | 12 | /// The menu is designed to be interactively accessed, perhaps via a console interface |
WiredHome | 0:198f53da1bc8 | 13 | /// or a serial port. The actual interface to the user is provided by the application |
WiredHome | 0:198f53da1bc8 | 14 | /// during initialization, so it can be connected to a serial port, or it could |
WiredHome | 0:198f53da1bc8 | 15 | /// be interface to CAN, telnet, or by some other method. |
WiredHome | 0:198f53da1bc8 | 16 | /// |
WiredHome | 0:198f53da1bc8 | 17 | /// The CommandProcessor has a few special features: |
WiredHome | 0:198f53da1bc8 | 18 | /// \li If the minimum number of characters of a command have been entered, the |
WiredHome | 0:198f53da1bc8 | 19 | /// user does not have to type the entire command. (e.g. 'He' will execute |
WiredHome | 0:198f53da1bc8 | 20 | /// the command for 'Help', if no other command beings with 'He'). |
WiredHome | 0:198f53da1bc8 | 21 | /// \li If the user does not type the entire set of characters, the command |
WiredHome | 0:198f53da1bc8 | 22 | /// will be rewritten to the output device with the entire command word. |
WiredHome | 0:198f53da1bc8 | 23 | /// \li The user is not permitted to enter an incorrect command (e.g. If 'Help' |
WiredHome | 0:198f53da1bc8 | 24 | /// is the only command started with 'Hel', the user cannot enter 'Heu'. |
WiredHome | 0:198f53da1bc8 | 25 | /// The CommandProcessor will trap the 'u' and issue a beep). |
WiredHome | 0:198f53da1bc8 | 26 | /// \li Simple editing of parameters to commands is permitted with \<bs\> to |
WiredHome | 0:198f53da1bc8 | 27 | /// erase incorrect text. |
WiredHome | 0:198f53da1bc8 | 28 | /// \li Tab completion of a command is available - so long as the user has |
WiredHome | 0:198f53da1bc8 | 29 | /// typed at least the minimum number of unique characters. (e.g. 'He\<tab\>' |
WiredHome | 0:198f53da1bc8 | 30 | /// will be replaced with 'Help') |
WiredHome | 0:198f53da1bc8 | 31 | /// \li Command cancellation is available - just enter the \<esc\> key and |
WiredHome | 0:198f53da1bc8 | 32 | /// the buffer is erased. |
WiredHome | 0:198f53da1bc8 | 33 | /// \li The user is not permitted to enter text longer than the defined buffer, |
WiredHome | 0:198f53da1bc8 | 34 | /// to avoid buffer overrun and the possible memory damaging results. |
WiredHome | 0:198f53da1bc8 | 35 | /// |
WiredHome | 0:198f53da1bc8 | 36 | /// The CommandProcessor is designed as a set of C functions, which makes it |
WiredHome | 0:198f53da1bc8 | 37 | /// reusable in more systems (as C++ compilers are not always available for |
WiredHome | 0:198f53da1bc8 | 38 | /// all micros). |
WiredHome | 0:198f53da1bc8 | 39 | /// |
WiredHome | 0:198f53da1bc8 | 40 | /// Example: |
WiredHome | 0:198f53da1bc8 | 41 | /// @code |
WiredHome | 0:198f53da1bc8 | 42 | /// extern "C" { |
WiredHome | 0:198f53da1bc8 | 43 | /// #include "CommandProcessor.h" |
WiredHome | 0:198f53da1bc8 | 44 | /// } |
WiredHome | 0:198f53da1bc8 | 45 | /// |
WiredHome | 0:198f53da1bc8 | 46 | /// RUNRESULT_T Who(char *p); |
WiredHome | 0:198f53da1bc8 | 47 | /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; |
WiredHome | 0:198f53da1bc8 | 48 | /// |
WiredHome | 0:198f53da1bc8 | 49 | /// RUNRESULT_T Who(char *p) |
WiredHome | 0:198f53da1bc8 | 50 | /// { |
WiredHome | 0:198f53da1bc8 | 51 | /// printf("\r\nwho...\r\n"); |
WiredHome | 0:198f53da1bc8 | 52 | /// if (*p) |
WiredHome | 0:198f53da1bc8 | 53 | /// printf(" Sorry, no help for [%s]\r\n", p); |
WiredHome | 0:198f53da1bc8 | 54 | /// return runok; |
WiredHome | 0:198f53da1bc8 | 55 | /// } |
WiredHome | 0:198f53da1bc8 | 56 | /// |
WiredHome | 0:198f53da1bc8 | 57 | /// int main(int argc, char* argv[]) |
WiredHome | 0:198f53da1bc8 | 58 | /// { |
WiredHome | 0:198f53da1bc8 | 59 | /// CMDP_T * cp = GetCommandProcessor(); |
WiredHome | 0:198f53da1bc8 | 60 | /// cp->Init(TRUE, TRUE, 50, _kbhit, _getch, _putch, printf); |
WiredHome | 0:198f53da1bc8 | 61 | /// cp->Add(&WhoCmd); |
WiredHome | 0:198f53da1bc8 | 62 | /// |
WiredHome | 0:198f53da1bc8 | 63 | /// while (cp->Run()) |
WiredHome | 0:198f53da1bc8 | 64 | /// { |
WiredHome | 0:198f53da1bc8 | 65 | /// ; |
WiredHome | 0:198f53da1bc8 | 66 | /// } |
WiredHome | 0:198f53da1bc8 | 67 | /// cp->End(); |
WiredHome | 0:198f53da1bc8 | 68 | /// return 0; |
WiredHome | 0:198f53da1bc8 | 69 | /// } |
WiredHome | 0:198f53da1bc8 | 70 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 71 | /// |
WiredHome | 0:198f53da1bc8 | 72 | /// @note Copyright © 2011 by Smartware Computing, all rights reserved. |
WiredHome | 0:198f53da1bc8 | 73 | /// This program may be used by others as long as this copyright notice |
WiredHome | 0:198f53da1bc8 | 74 | /// remains intact. |
WiredHome | 0:198f53da1bc8 | 75 | /// @author David Smart |
WiredHome | 0:198f53da1bc8 | 76 | /// |
WiredHome | 0:198f53da1bc8 | 77 | #ifndef COMMANDPROCESSOR_H |
WiredHome | 0:198f53da1bc8 | 78 | #define COMMANDPROCESSOR_H |
WiredHome | 0:198f53da1bc8 | 79 | |
WiredHome | 0:198f53da1bc8 | 80 | #ifndef TRUE |
WiredHome | 0:198f53da1bc8 | 81 | #define TRUE 1 ///< Definition for TRUE, if not already provided |
WiredHome | 0:198f53da1bc8 | 82 | #define FALSE 0 ///< Definition for FALSE, if not already provided |
WiredHome | 0:198f53da1bc8 | 83 | #endif |
WiredHome | 0:198f53da1bc8 | 84 | |
WiredHome | 0:198f53da1bc8 | 85 | /// @brief This type determines if menu items are visible to the Help system, or hidden. |
WiredHome | 0:198f53da1bc8 | 86 | /// @details This is used in the definition of the menu item. |
WiredHome | 0:198f53da1bc8 | 87 | typedef enum |
WiredHome | 0:198f53da1bc8 | 88 | { |
WiredHome | 0:198f53da1bc8 | 89 | invisible, ///< use this value to have invisible (hidden) a menu in the Help |
WiredHome | 0:198f53da1bc8 | 90 | visible ///< use this value to have visible a menu in the Help |
WiredHome | 0:198f53da1bc8 | 91 | } VISIBLE_T; ///< This determines if menu items are made visible in the Help system. |
WiredHome | 0:198f53da1bc8 | 92 | |
WiredHome | 0:198f53da1bc8 | 93 | /// Callbacks that are executed return a value to indicate if the menu |
WiredHome | 0:198f53da1bc8 | 94 | /// should remain active |
WiredHome | 0:198f53da1bc8 | 95 | typedef enum |
WiredHome | 0:198f53da1bc8 | 96 | { |
WiredHome | 0:198f53da1bc8 | 97 | runexit, ///< use this return value to cause the menu (perhaps the program) to exit |
WiredHome | 0:198f53da1bc8 | 98 | runok ///< use this return value to keep the menu running |
WiredHome | 0:198f53da1bc8 | 99 | } RUNRESULT_T; |
WiredHome | 0:198f53da1bc8 | 100 | |
WiredHome | 0:198f53da1bc8 | 101 | /// Adding items to the menu can succeed, or fail. |
WiredHome | 0:198f53da1bc8 | 102 | typedef enum |
WiredHome | 0:198f53da1bc8 | 103 | { |
WiredHome | 0:198f53da1bc8 | 104 | addfailed, ///< this indicates the menu was not added (usually failure to allocate memory) |
WiredHome | 0:198f53da1bc8 | 105 | addok ///< this indicates the menu was successfully added |
WiredHome | 0:198f53da1bc8 | 106 | } ADDRESULT_T; |
WiredHome | 0:198f53da1bc8 | 107 | |
WiredHome | 0:198f53da1bc8 | 108 | /// Initialization can succeed, or fail. |
WiredHome | 0:198f53da1bc8 | 109 | typedef enum |
WiredHome | 0:198f53da1bc8 | 110 | { |
WiredHome | 0:198f53da1bc8 | 111 | initfailed, ///< this indicates that the menu system was not initialized (usually failure to allocate memory) |
WiredHome | 0:198f53da1bc8 | 112 | initok ///< this indicates that the menu system was successfully initialized |
WiredHome | 0:198f53da1bc8 | 113 | } INITRESULT_T; |
WiredHome | 0:198f53da1bc8 | 114 | |
WiredHome | 0:198f53da1bc8 | 115 | /// This is the type for the basic callback, when a menu pick is activated. |
WiredHome | 0:198f53da1bc8 | 116 | /// |
WiredHome | 0:198f53da1bc8 | 117 | /// The callback function is executed when a command is entered on the menu and \<enter\> |
WiredHome | 0:198f53da1bc8 | 118 | /// is signaled. If there is any additional text entered on the commandline, it is |
WiredHome | 0:198f53da1bc8 | 119 | /// passed to the callback. |
WiredHome | 0:198f53da1bc8 | 120 | /// |
WiredHome | 0:198f53da1bc8 | 121 | /// example: |
WiredHome | 0:198f53da1bc8 | 122 | /// "Test1 ab c 123 567" |
WiredHome | 0:198f53da1bc8 | 123 | /// If "Test1" is a valid command, the corresponding function would be called |
WiredHome | 0:198f53da1bc8 | 124 | /// passing to that function the string "ab c 123 567". Note that the delimiter space |
WiredHome | 0:198f53da1bc8 | 125 | /// was removed. |
WiredHome | 0:198f53da1bc8 | 126 | /// |
WiredHome | 0:198f53da1bc8 | 127 | /// @param p is a pointer to a character string |
WiredHome | 1:1c81feb2f8bd | 128 | /// @returns RUNRESULT_T to indicate if the CommandProcessor should continue |
WiredHome | 0:198f53da1bc8 | 129 | /// |
WiredHome | 0:198f53da1bc8 | 130 | typedef RUNRESULT_T (*MENU_CALLBACK)(char *p); |
WiredHome | 0:198f53da1bc8 | 131 | |
WiredHome | 0:198f53da1bc8 | 132 | /// This defines the type for a single item to be added to the CommandProcessor menu. |
WiredHome | 0:198f53da1bc8 | 133 | /// |
WiredHome | 0:198f53da1bc8 | 134 | /// This is defined in the application code, and a pointer to this item is passed to the |
WiredHome | 0:198f53da1bc8 | 135 | /// CommandProcessor to add this item to the menu system. |
WiredHome | 0:198f53da1bc8 | 136 | /// |
WiredHome | 0:198f53da1bc8 | 137 | /// example: |
WiredHome | 0:198f53da1bc8 | 138 | /// @code |
WiredHome | 0:198f53da1bc8 | 139 | /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; |
WiredHome | 0:198f53da1bc8 | 140 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 141 | /// |
WiredHome | 0:198f53da1bc8 | 142 | typedef const struct |
WiredHome | 0:198f53da1bc8 | 143 | { |
WiredHome | 0:198f53da1bc8 | 144 | char * command; ///< a pointer to the command to match (e.g. 'Help') |
WiredHome | 0:198f53da1bc8 | 145 | char * helptext; ///< a pointer to some text to show when user types 'Help' |
WiredHome | 0:198f53da1bc8 | 146 | MENU_CALLBACK callback; ///< the function to call when user enters this command |
WiredHome | 0:198f53da1bc8 | 147 | VISIBLE_T visible; ///< a flag that determines if this command is visible in Help. |
WiredHome | 0:198f53da1bc8 | 148 | } CMD_T; |
WiredHome | 0:198f53da1bc8 | 149 | |
WiredHome | 0:198f53da1bc8 | 150 | /// This is the CommandProcessor interface from the user application. |
WiredHome | 0:198f53da1bc8 | 151 | /// |
WiredHome | 1:1c81feb2f8bd | 152 | /// The user aquires a handle to this set of functions with the GetCommandProcessor command. |
WiredHome | 0:198f53da1bc8 | 153 | /// After this, the user may then initialize the CommandProcessor, add items to the menu, |
WiredHome | 0:198f53da1bc8 | 154 | /// cause the CommandProcessor to run periodically, and if need be the application can end |
WiredHome | 0:198f53da1bc8 | 155 | /// the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 156 | /// |
WiredHome | 0:198f53da1bc8 | 157 | typedef const struct |
WiredHome | 0:198f53da1bc8 | 158 | { |
WiredHome | 0:198f53da1bc8 | 159 | /// Init is the first function to call to configure the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 160 | /// |
WiredHome | 0:198f53da1bc8 | 161 | /// This function has a number of parameters, which make the CommandProcessor quite flexible. |
WiredHome | 0:198f53da1bc8 | 162 | /// The user can enable a default menu, which can consist of the following functions. |
WiredHome | 0:198f53da1bc8 | 163 | /// Note that when the [bit] is set, that menu item is enabled. |
WiredHome | 0:198f53da1bc8 | 164 | /// * [2] Help - which in turn will show all the menu items and their brief descriptions |
WiredHome | 0:198f53da1bc8 | 165 | /// * [1] About - just a tiny statement about the CommandProcessor itself |
WiredHome | 0:198f53da1bc8 | 166 | /// * [0] Exit - a method to permit a consistent means to exit the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 167 | /// |
WiredHome | 0:198f53da1bc8 | 168 | /// @param defaultMenu enables various default menu items, based on the bit values. |
WiredHome | 0:198f53da1bc8 | 169 | /// @param caseinsensitive when TRUE, as the name implies, permits "help" and "HeLp" to function the same |
WiredHome | 0:198f53da1bc8 | 170 | /// @param maxCmdLen sets the memory allocation for the command buffer. This should be sized |
WiredHome | 0:198f53da1bc8 | 171 | /// to the maximum command, including any passed in text as parameters. |
WiredHome | 0:198f53da1bc8 | 172 | /// @param kbhit is a user provided function to detect if a character is available for the CommandProcessor, |
WiredHome | 0:198f53da1bc8 | 173 | /// and when using standard io, you can typically use kbhit, or _kbhit as your system provides. |
WiredHome | 0:198f53da1bc8 | 174 | /// @param getch is a user provided function that provides a single character to the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 175 | /// @param putch is a user provided function that permits the CommandProcessor to output a character |
WiredHome | 0:198f53da1bc8 | 176 | /// @param puts is a user provided function that permits the CommandProcessor to output a string |
WiredHome | 0:198f53da1bc8 | 177 | /// to which is automatically appended a \\n |
WiredHome | 1:1c81feb2f8bd | 178 | /// @returns INITRESULT_T to indicate if the init was successful or failed |
WiredHome | 0:198f53da1bc8 | 179 | INITRESULT_T (*Init)( |
WiredHome | 0:198f53da1bc8 | 180 | int defaultMenu, |
WiredHome | 0:198f53da1bc8 | 181 | int caseinsensitive, |
WiredHome | 0:198f53da1bc8 | 182 | int maxCmdLen, |
WiredHome | 0:198f53da1bc8 | 183 | int (*kbhit)(void), |
WiredHome | 0:198f53da1bc8 | 184 | int (*getch)(void), |
WiredHome | 0:198f53da1bc8 | 185 | int (*putch)(int ch), |
WiredHome | 0:198f53da1bc8 | 186 | int (*puts)(const char * s) |
WiredHome | 0:198f53da1bc8 | 187 | ); |
WiredHome | 0:198f53da1bc8 | 188 | |
WiredHome | 0:198f53da1bc8 | 189 | /// Add is called to add an item to the CommandProcessor menu |
WiredHome | 0:198f53da1bc8 | 190 | /// |
WiredHome | 1:1c81feb2f8bd | 191 | /// This passes in a reference to a user provided CMD_T item, which is |
WiredHome | 0:198f53da1bc8 | 192 | /// added to the menu system. |
WiredHome | 0:198f53da1bc8 | 193 | /// |
WiredHome | 0:198f53da1bc8 | 194 | /// @param m is a pointer to the user provided menu |
WiredHome | 1:1c81feb2f8bd | 195 | /// @returns ADDRESULT_T to indicate if the add was successful or failed |
WiredHome | 0:198f53da1bc8 | 196 | /// |
WiredHome | 0:198f53da1bc8 | 197 | ADDRESULT_T (*Add)(CMD_T * m); |
WiredHome | 0:198f53da1bc8 | 198 | |
WiredHome | 0:198f53da1bc8 | 199 | /// Run is the primary runtime entry point for the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 200 | /// |
WiredHome | 0:198f53da1bc8 | 201 | /// This function should be called periodically - fast enough not to miss user input. |
WiredHome | 0:198f53da1bc8 | 202 | /// This function always returns, so if not character is available for the CommandProcessor |
WiredHome | 1:1c81feb2f8bd | 203 | /// it will return very fast. If there is a character (as detected by the kbhit callback), |
WiredHome | 0:198f53da1bc8 | 204 | /// then it will process that character and determine what to do. It may then execute one |
WiredHome | 0:198f53da1bc8 | 205 | /// of the menu functions. In this case, CPU cycles spent are based on the function |
WiredHome | 0:198f53da1bc8 | 206 | /// being executed. |
WiredHome | 0:198f53da1bc8 | 207 | /// |
WiredHome | 1:1c81feb2f8bd | 208 | /// @returns RUNRESULT_T to indicate if the CommandProcessor should remain active or if the |
WiredHome | 0:198f53da1bc8 | 209 | /// command that was executed is requesting the CommandProcessor to exit. |
WiredHome | 0:198f53da1bc8 | 210 | /// |
WiredHome | 0:198f53da1bc8 | 211 | RUNRESULT_T (*Run)(void); |
WiredHome | 0:198f53da1bc8 | 212 | |
WiredHome | 0:198f53da1bc8 | 213 | /// End if the function to be called when you want to gracefully end the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 214 | /// |
WiredHome | 0:198f53da1bc8 | 215 | /// Calling this function causes the CommandProcessor to free any memory that was previously |
WiredHome | 1:1c81feb2f8bd | 216 | /// allocated by the Init and Add functions. |
WiredHome | 0:198f53da1bc8 | 217 | RUNRESULT_T (*End)(void); ///< Called to shutdown the processor |
WiredHome | 0:198f53da1bc8 | 218 | } CMDP_T; |
WiredHome | 0:198f53da1bc8 | 219 | |
WiredHome | 0:198f53da1bc8 | 220 | /// GetCommandProcessor is called to get a handle to the CommandProcessor itself. |
WiredHome | 0:198f53da1bc8 | 221 | /// |
WiredHome | 0:198f53da1bc8 | 222 | /// Call this function to get a handle to the CommandProcessor. After this is done, then |
WiredHome | 0:198f53da1bc8 | 223 | /// you can use that handle to activate the CommandProcessor methods. |
WiredHome | 0:198f53da1bc8 | 224 | /// |
WiredHome | 0:198f53da1bc8 | 225 | /// example: |
WiredHome | 0:198f53da1bc8 | 226 | /// @code |
WiredHome | 0:198f53da1bc8 | 227 | /// CMDP_T * cp = GetCommandProcessor(); |
WiredHome | 0:198f53da1bc8 | 228 | /// cp->Init(TRUE, TRUE, 50, _kbhit, _getch, _putch, printf); |
WiredHome | 0:198f53da1bc8 | 229 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 230 | /// |
WiredHome | 1:1c81feb2f8bd | 231 | /// @returns CMDP_T a handle to the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 232 | /// |
WiredHome | 0:198f53da1bc8 | 233 | #ifdef WIN32 |
WiredHome | 0:198f53da1bc8 | 234 | CMDP_T * GetCommandProcessor(void); |
WiredHome | 0:198f53da1bc8 | 235 | #else // This is necessary for the mbed - not sure why. |
WiredHome | 0:198f53da1bc8 | 236 | extern "C" CMDP_T * GetCommandProcessor(void); |
WiredHome | 0:198f53da1bc8 | 237 | #endif |
WiredHome | 0:198f53da1bc8 | 238 | |
WiredHome | 1:1c81feb2f8bd | 239 | #endif // COMMANDPROCESSOR_H |