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

Committer:
hillkim7
Date:
2015-07-03
Revision:
3:df8a882e33a6
Parent:
2:d7ffadba49b9

File content as of revision 3:df8a882e33a6:

/**
 * @file console.cpp
 *
 * @brief console implementation using CMDB library.
 *
 * After boot, it prompts "CMD>" in console. Type "help" command to get help.
 */

#include <vector>
#include "mbed.h"
#include "cmdb.h"
#include "util.h"
#include "main.h"

#define CID_TEST		1
#define CID_FREE		2
#define CID_CFG_SET		3
#define CID_CFG_RESET	4
#define CID_CFG_SAVE	5
#define CID_CFG_PRINT	6
#define CID_IF_UP		7
#define CID_IF_DOWN		8
#define CID_IF_STAT		9


/** Sample User Command Dispatcher.
 *
 * @parm cmdb the command interpreter object.
 * @parm cid the command id.
 */
void my_dispatcher(Cmdb& cmdb, int cid)
{
    //cmdb.printf("my_dispatcher: cid=%d\r\n", cid);

    switch (cid) {
        case CID_FREE :
            //cmdb.printf("my_dispatcher: parm 0=%d\r\n",cmdb.INTPARM(0));
            print_memstat();
            break;
        case CID_CFG_SET :
            _config.lock_config();
            if (!_config.value_replace(cmdb.STRINGPARM(0), cmdb.STRINGPARM(1))) {
                cmdb.printf("invalid key='%s'\r\n", cmdb.STRINGPARM(0));
            }
            _config.unlock_config();
            break;
        case CID_CFG_RESET :
           _config.lock_config();
           _config.reset_default();
            _config.unlock_config();
            break;
        case CID_CFG_SAVE :
            _config.lock_config();
            if (!_config.save_config()) {
                cmdb.printf("save fail\r\n");
            }
            _config.unlock_config();
            break;
        case CID_CFG_PRINT :
            _config.lock_config();
            _config.print_all();
            _config.unlock_config();
            break;
        case CID_IF_UP :
            send_main_message(MSG_IFUP, 0, 0);
            break;
        case CID_IF_DOWN:
            send_main_message(MSG_IFDOWN, 0, 0);
            break;
        case CID_IF_STAT :
            send_main_message(MSG_IFSTAT, 0, 0);
            break;
        default:
            printf("unknown CID=%u\r\n", cid);
            break;
    }
}

static const cmd user_cmd[] = {
    {"Test",SUBSYSTEM,CID_TEST,""  ,"* Test Subsystem"},
    {"free",CID_TEST,CID_FREE,""	,"show amount of free memory", ""},
    {"cfgset",CID_TEST,CID_CFG_SET,"%s %s"  ,"config set", "config_key value"},
    {"cfgreset",CID_TEST,CID_CFG_RESET,""  ,"config reset", ""},
    {"cfgsave",CID_TEST,CID_CFG_SAVE,""  ,"config save to flash"},
    {"cfgprint",CID_TEST,CID_CFG_PRINT,""  ,"print all config"},
    {"ifup",CID_TEST,CID_IF_UP,""  ,"bring a network interface up"},
    {"ifdown",CID_TEST,CID_IF_DOWN,""  ,"bring a network interface down"},
    {"ifstat",CID_TEST,CID_IF_STAT,""  ,"print network info"},
};


void console_thread(void const *args)
{
    Serial &serial = *((Serial *)args);

    // Test the serial connection by
    serial.printf("\r\n\r\nCmdb Command Interpreter Demo Version %0.2f.\r\n\r\n", Cmdb::version());

    //Create a Command Table Vector.
    std::vector<cmd> cmds(&user_cmd[0], &user_cmd[sizeof(user_cmd)/sizeof(user_cmd[0])]);

    //Add some of our own first...
    //Add some predefined...
    cmds.push_back(COMMANDS); //Handled by Cmdb internally.
    cmds.push_back(BOOT); //Handled by Cmdb internally.

    cmds.push_back(ECHO); //Handled by Cmdb internally.
    cmds.push_back(BOLD); //Handled by Cmdb internally.
    cmds.push_back(CLS);  //Handled by Cmdb internally.

    cmds.push_back(MACRO);  //Handled by Cmdb internally.
    cmds.push_back(RUN);    //Handled by Cmdb internally.
    cmds.push_back(MACROS); //Handled by Cmdb internally.

    //Add some predefined and mandatory...
    cmds.push_back(IDLE); //Handled by Cmdb internally.
    cmds.push_back(HELP); //Handled by Cmdb internally.

    //Create and initialize the Command Interpreter.
    Cmdb cmdb(serial, cmds, &my_dispatcher);

    //cmdb.printf("%d=%d\r\n",cmds[0].subs,cmds[0].cid);
    //cmdb.printf("%d=%d\r\n",cmds[1].subs,cmds[1].cid);

    while (1) {
        //Check for input...
        if (cmdb.hasnext()==true) {

            //Supply input to Command Interpreter
            if (cmdb.scan(cmdb.next())) {
            }
        }

        //For Macro Support we basically do the same but take characters from the macro buffer.
        //Example Macro: Test|Int_42|Idle
        while (cmdb.macro_hasnext()) {
            //Get and process next character.
            cmdb.scan(cmdb.macro_next());

            //After the last character we need to add a cr to force execution.
            if (!cmdb.macro_peek()) {
                cmdb.scan(cr);
            }
        }
    }
}