
Typical controller demo program based on Seeed Arch Max. Features: - Multi-thread architecture - Inter-thread message communication - Independent command shell using thread - HTTPD with CGI, WS, RPC - Key & value pair configuration load/save
Dependencies: CMDB EthernetInterface HTTPD dconfig mbed-rpc mbed-rtos mbed storage_on_flash
console.cpp@2:d7ffadba49b9, 2015-06-17 (annotated)
- Committer:
- hillkim7
- Date:
- Wed Jun 17 01:55:19 2015 +0000
- Revision:
- 2:d7ffadba49b9
- Parent:
- 0:2ffd10976643
Fix stack overflow problem of the console task.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hillkim7 | 0:2ffd10976643 | 1 | /** |
hillkim7 | 0:2ffd10976643 | 2 | * @file console.cpp |
hillkim7 | 0:2ffd10976643 | 3 | * |
hillkim7 | 0:2ffd10976643 | 4 | * @brief console implementation using CMDB library. |
hillkim7 | 0:2ffd10976643 | 5 | * |
hillkim7 | 0:2ffd10976643 | 6 | * After boot, it prompts "CMD>" in console. Type "help" command to get help. |
hillkim7 | 0:2ffd10976643 | 7 | */ |
hillkim7 | 0:2ffd10976643 | 8 | |
hillkim7 | 0:2ffd10976643 | 9 | #include <vector> |
hillkim7 | 0:2ffd10976643 | 10 | #include "mbed.h" |
hillkim7 | 0:2ffd10976643 | 11 | #include "cmdb.h" |
hillkim7 | 0:2ffd10976643 | 12 | #include "util.h" |
hillkim7 | 0:2ffd10976643 | 13 | #include "main.h" |
hillkim7 | 0:2ffd10976643 | 14 | |
hillkim7 | 0:2ffd10976643 | 15 | #define CID_TEST 1 |
hillkim7 | 0:2ffd10976643 | 16 | #define CID_FREE 2 |
hillkim7 | 0:2ffd10976643 | 17 | #define CID_CFG_SET 3 |
hillkim7 | 2:d7ffadba49b9 | 18 | #define CID_CFG_RESET 4 |
hillkim7 | 2:d7ffadba49b9 | 19 | #define CID_CFG_SAVE 5 |
hillkim7 | 2:d7ffadba49b9 | 20 | #define CID_CFG_PRINT 6 |
hillkim7 | 2:d7ffadba49b9 | 21 | #define CID_IF_UP 7 |
hillkim7 | 2:d7ffadba49b9 | 22 | #define CID_IF_DOWN 8 |
hillkim7 | 2:d7ffadba49b9 | 23 | #define CID_IF_STAT 9 |
hillkim7 | 2:d7ffadba49b9 | 24 | |
hillkim7 | 0:2ffd10976643 | 25 | |
hillkim7 | 0:2ffd10976643 | 26 | /** Sample User Command Dispatcher. |
hillkim7 | 0:2ffd10976643 | 27 | * |
hillkim7 | 0:2ffd10976643 | 28 | * @parm cmdb the command interpreter object. |
hillkim7 | 0:2ffd10976643 | 29 | * @parm cid the command id. |
hillkim7 | 0:2ffd10976643 | 30 | */ |
hillkim7 | 0:2ffd10976643 | 31 | void my_dispatcher(Cmdb& cmdb, int cid) |
hillkim7 | 0:2ffd10976643 | 32 | { |
hillkim7 | 0:2ffd10976643 | 33 | //cmdb.printf("my_dispatcher: cid=%d\r\n", cid); |
hillkim7 | 0:2ffd10976643 | 34 | |
hillkim7 | 0:2ffd10976643 | 35 | switch (cid) { |
hillkim7 | 0:2ffd10976643 | 36 | case CID_FREE : |
hillkim7 | 0:2ffd10976643 | 37 | //cmdb.printf("my_dispatcher: parm 0=%d\r\n",cmdb.INTPARM(0)); |
hillkim7 | 0:2ffd10976643 | 38 | print_memstat(); |
hillkim7 | 0:2ffd10976643 | 39 | break; |
hillkim7 | 0:2ffd10976643 | 40 | case CID_CFG_SET : |
hillkim7 | 0:2ffd10976643 | 41 | _config.lock_config(); |
hillkim7 | 0:2ffd10976643 | 42 | if (!_config.value_replace(cmdb.STRINGPARM(0), cmdb.STRINGPARM(1))) { |
hillkim7 | 0:2ffd10976643 | 43 | cmdb.printf("invalid key='%s'\r\n", cmdb.STRINGPARM(0)); |
hillkim7 | 0:2ffd10976643 | 44 | } |
hillkim7 | 0:2ffd10976643 | 45 | _config.unlock_config(); |
hillkim7 | 0:2ffd10976643 | 46 | break; |
hillkim7 | 2:d7ffadba49b9 | 47 | case CID_CFG_RESET : |
hillkim7 | 2:d7ffadba49b9 | 48 | _config.lock_config(); |
hillkim7 | 2:d7ffadba49b9 | 49 | _config.reset_default(); |
hillkim7 | 2:d7ffadba49b9 | 50 | _config.unlock_config(); |
hillkim7 | 2:d7ffadba49b9 | 51 | break; |
hillkim7 | 0:2ffd10976643 | 52 | case CID_CFG_SAVE : |
hillkim7 | 0:2ffd10976643 | 53 | _config.lock_config(); |
hillkim7 | 0:2ffd10976643 | 54 | if (!_config.save_config()) { |
hillkim7 | 0:2ffd10976643 | 55 | cmdb.printf("save fail\r\n"); |
hillkim7 | 0:2ffd10976643 | 56 | } |
hillkim7 | 0:2ffd10976643 | 57 | _config.unlock_config(); |
hillkim7 | 0:2ffd10976643 | 58 | break; |
hillkim7 | 0:2ffd10976643 | 59 | case CID_CFG_PRINT : |
hillkim7 | 0:2ffd10976643 | 60 | _config.lock_config(); |
hillkim7 | 0:2ffd10976643 | 61 | _config.print_all(); |
hillkim7 | 0:2ffd10976643 | 62 | _config.unlock_config(); |
hillkim7 | 0:2ffd10976643 | 63 | break; |
hillkim7 | 0:2ffd10976643 | 64 | case CID_IF_UP : |
hillkim7 | 0:2ffd10976643 | 65 | send_main_message(MSG_IFUP, 0, 0); |
hillkim7 | 0:2ffd10976643 | 66 | break; |
hillkim7 | 0:2ffd10976643 | 67 | case CID_IF_DOWN: |
hillkim7 | 0:2ffd10976643 | 68 | send_main_message(MSG_IFDOWN, 0, 0); |
hillkim7 | 0:2ffd10976643 | 69 | break; |
hillkim7 | 0:2ffd10976643 | 70 | case CID_IF_STAT : |
hillkim7 | 0:2ffd10976643 | 71 | send_main_message(MSG_IFSTAT, 0, 0); |
hillkim7 | 0:2ffd10976643 | 72 | break; |
hillkim7 | 0:2ffd10976643 | 73 | default: |
hillkim7 | 0:2ffd10976643 | 74 | printf("unknown CID=%u\r\n", cid); |
hillkim7 | 0:2ffd10976643 | 75 | break; |
hillkim7 | 0:2ffd10976643 | 76 | } |
hillkim7 | 0:2ffd10976643 | 77 | } |
hillkim7 | 0:2ffd10976643 | 78 | |
hillkim7 | 0:2ffd10976643 | 79 | static const cmd user_cmd[] = { |
hillkim7 | 0:2ffd10976643 | 80 | {"Test",SUBSYSTEM,CID_TEST,"" ,"* Test Subsystem"}, |
hillkim7 | 0:2ffd10976643 | 81 | {"free",CID_TEST,CID_FREE,"" ,"show amount of free memory", ""}, |
hillkim7 | 0:2ffd10976643 | 82 | {"cfgset",CID_TEST,CID_CFG_SET,"%s %s" ,"config set", "config_key value"}, |
hillkim7 | 2:d7ffadba49b9 | 83 | {"cfgreset",CID_TEST,CID_CFG_RESET,"" ,"config reset", ""}, |
hillkim7 | 0:2ffd10976643 | 84 | {"cfgsave",CID_TEST,CID_CFG_SAVE,"" ,"config save to flash"}, |
hillkim7 | 0:2ffd10976643 | 85 | {"cfgprint",CID_TEST,CID_CFG_PRINT,"" ,"print all config"}, |
hillkim7 | 0:2ffd10976643 | 86 | {"ifup",CID_TEST,CID_IF_UP,"" ,"bring a network interface up"}, |
hillkim7 | 0:2ffd10976643 | 87 | {"ifdown",CID_TEST,CID_IF_DOWN,"" ,"bring a network interface down"}, |
hillkim7 | 0:2ffd10976643 | 88 | {"ifstat",CID_TEST,CID_IF_STAT,"" ,"print network info"}, |
hillkim7 | 0:2ffd10976643 | 89 | }; |
hillkim7 | 0:2ffd10976643 | 90 | |
hillkim7 | 0:2ffd10976643 | 91 | |
hillkim7 | 0:2ffd10976643 | 92 | void console_thread(void const *args) |
hillkim7 | 0:2ffd10976643 | 93 | { |
hillkim7 | 0:2ffd10976643 | 94 | Serial &serial = *((Serial *)args); |
hillkim7 | 0:2ffd10976643 | 95 | |
hillkim7 | 0:2ffd10976643 | 96 | // Test the serial connection by |
hillkim7 | 0:2ffd10976643 | 97 | serial.printf("\r\n\r\nCmdb Command Interpreter Demo Version %0.2f.\r\n\r\n", Cmdb::version()); |
hillkim7 | 0:2ffd10976643 | 98 | |
hillkim7 | 0:2ffd10976643 | 99 | //Create a Command Table Vector. |
hillkim7 | 0:2ffd10976643 | 100 | std::vector<cmd> cmds(&user_cmd[0], &user_cmd[sizeof(user_cmd)/sizeof(user_cmd[0])]); |
hillkim7 | 0:2ffd10976643 | 101 | |
hillkim7 | 0:2ffd10976643 | 102 | //Add some of our own first... |
hillkim7 | 0:2ffd10976643 | 103 | //Add some predefined... |
hillkim7 | 0:2ffd10976643 | 104 | cmds.push_back(COMMANDS); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 105 | cmds.push_back(BOOT); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 106 | |
hillkim7 | 0:2ffd10976643 | 107 | cmds.push_back(ECHO); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 108 | cmds.push_back(BOLD); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 109 | cmds.push_back(CLS); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 110 | |
hillkim7 | 0:2ffd10976643 | 111 | cmds.push_back(MACRO); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 112 | cmds.push_back(RUN); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 113 | cmds.push_back(MACROS); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 114 | |
hillkim7 | 0:2ffd10976643 | 115 | //Add some predefined and mandatory... |
hillkim7 | 0:2ffd10976643 | 116 | cmds.push_back(IDLE); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 117 | cmds.push_back(HELP); //Handled by Cmdb internally. |
hillkim7 | 0:2ffd10976643 | 118 | |
hillkim7 | 0:2ffd10976643 | 119 | //Create and initialize the Command Interpreter. |
hillkim7 | 0:2ffd10976643 | 120 | Cmdb cmdb(serial, cmds, &my_dispatcher); |
hillkim7 | 0:2ffd10976643 | 121 | |
hillkim7 | 0:2ffd10976643 | 122 | //cmdb.printf("%d=%d\r\n",cmds[0].subs,cmds[0].cid); |
hillkim7 | 0:2ffd10976643 | 123 | //cmdb.printf("%d=%d\r\n",cmds[1].subs,cmds[1].cid); |
hillkim7 | 0:2ffd10976643 | 124 | |
hillkim7 | 0:2ffd10976643 | 125 | while (1) { |
hillkim7 | 0:2ffd10976643 | 126 | //Check for input... |
hillkim7 | 0:2ffd10976643 | 127 | if (cmdb.hasnext()==true) { |
hillkim7 | 0:2ffd10976643 | 128 | |
hillkim7 | 0:2ffd10976643 | 129 | //Supply input to Command Interpreter |
hillkim7 | 0:2ffd10976643 | 130 | if (cmdb.scan(cmdb.next())) { |
hillkim7 | 0:2ffd10976643 | 131 | } |
hillkim7 | 0:2ffd10976643 | 132 | } |
hillkim7 | 0:2ffd10976643 | 133 | |
hillkim7 | 0:2ffd10976643 | 134 | //For Macro Support we basically do the same but take characters from the macro buffer. |
hillkim7 | 0:2ffd10976643 | 135 | //Example Macro: Test|Int_42|Idle |
hillkim7 | 0:2ffd10976643 | 136 | while (cmdb.macro_hasnext()) { |
hillkim7 | 0:2ffd10976643 | 137 | //Get and process next character. |
hillkim7 | 0:2ffd10976643 | 138 | cmdb.scan(cmdb.macro_next()); |
hillkim7 | 0:2ffd10976643 | 139 | |
hillkim7 | 0:2ffd10976643 | 140 | //After the last character we need to add a cr to force execution. |
hillkim7 | 0:2ffd10976643 | 141 | if (!cmdb.macro_peek()) { |
hillkim7 | 0:2ffd10976643 | 142 | cmdb.scan(cr); |
hillkim7 | 0:2ffd10976643 | 143 | } |
hillkim7 | 0:2ffd10976643 | 144 | } |
hillkim7 | 0:2ffd10976643 | 145 | } |
hillkim7 | 0:2ffd10976643 | 146 | } |
hillkim7 | 0:2ffd10976643 | 147 | |
hillkim7 | 2:d7ffadba49b9 | 148 |