#include "cmd_scheduler.hpp" #include #include #include "sdk\components\zprotocols\errorcode\errorcode.hpp" using namespace iflytop; #define TAG "CMD" void CmdScheduler::registerCmd(std::string cmd, const char* helpinfo, int npara, call_cmd_t call_cmd) { CMD cmdinfo; cmdinfo.call_cmd = call_cmd; cmdinfo.help_info = helpinfo; cmdinfo.npara = npara; m_cmdMap[cmd] = cmdinfo; } void CmdScheduler::regbasiccmd() { this->registerCmd("help", "", 0, [this](Context* context) { ZLOGI(TAG, "cmdlist:"); for (auto it = m_cmdMap.begin(); it != m_cmdMap.end(); it++) { ZLOGI(TAG, " %s %s", it->first.c_str(), it->second.help_info.c_str()); } return (int32_t)0; }); this->registerCmd("sleep_ms", "(ms)", 1, [this](Context* context) { int ms = atoi(context->argv[1]); osDelay(ms); return 0; }); } void CmdScheduler::initialize(UART_HandleTypeDef* huart, uint32_t rxbufsize) { m_rxbufsize = rxbufsize; m_uart = new ZUART(); ZASSERT(m_uart != NULL); ZUART::cfg_t cfg; cfg.huart = huart; cfg.rxbuffersize = rxbufsize; cfg.rxovertime_ms = 3; cfg.name = "CmdSchedulerUart"; rxbuf = new char[rxbufsize + 1]; ZASSERT(rxbuf != NULL); m_uart->initialize(&cfg); ZASSERT(m_uart->startRxIt()); m_uart->setrxcb([this](uint8_t* data, size_t len) { if (m_dataisready) { return; } memcpy(rxbuf, data, len); rxbuf[len] = '\0'; m_rxsize = len; m_dataisready = true; // on data ,in irq context }); regbasiccmd(); } void CmdScheduler::schedule() { if (!m_dataisready) { return; } for (int i = 0; i < m_rxsize; i++) { if (rxbuf[i] == '\r' || rxbuf[i] == '\n') { rxbuf[i] = '\0'; } } for (int i = 0; i < m_rxsize; i++) { if (rxbuf[i] != '\0') { ZLOGI(TAG, "docmd: %s", &rxbuf[i]); int inext = strlen(&rxbuf[i]) + i; int32_t ecode = callcmd(&rxbuf[i]); i = inext; if (ecode == 0) { ZLOGI(TAG, "\tsuccess"); } else { ZLOGE(TAG, "\tfailed:%s(%d)", err::error2str(ecode), ecode); } ZLOGI(TAG, "\r\n"); if (ecode != 0) { break; } } } // if (m_rxsize != 1) { // ZLOGI(TAG, "doscript:end"); // } m_dataisready = false; } void CmdScheduler::tx(const char* data, int len) { m_uart->tx((uint8_t*)data, len); } int32_t CmdScheduler::callcmd(const char* cmd) { int argc = 0; char* argv[10] = {0}; memset(cmdcache, 0, sizeof(cmdcache)); argc = 0; memset(argv, 0, sizeof(argv)); strcpy(cmdcache, cmd); remove_note(cmdcache, strlen(cmdcache)); prase_cmd(cmdcache, strlen(cmdcache), argc, argv); if (argc == 0) { return (int32_t)0; } // printf("argc:%d\n", argc); // for (size_t i = 0; i < argc; i++) { // printf("argv[%d]:%s\n", i, argv[i]); // } /** * @brief 在这里处理指令 */ auto cmder = m_cmdMap.find(string(argv[0])); if (cmder != m_cmdMap.end()) { Context context; context.argc = argc; context.argv = argv; // ZLOGI(TAG, "callcmd:argc %d %d", argc, cmder->second.npara); if (cmder->second.npara != context.argc - 1) return err::kcmd_param_num_error; int32_t ret = cmder->second.call_cmd(&context); return ret; } else { return err::kcmd_not_found; } } void CmdScheduler::remove_note(char* input, int inputlen) { bool detect_note = false; for (int i = 0; i < inputlen; i++) { if (!detect_note && input[i] == '#') { detect_note = true; } if (detect_note) { input[i] = 0; } } } void CmdScheduler::prase_cmd(char* input, int inputlen, int& argc, char* argv[]) { for (int i = 0; input[i] == 0 || i < inputlen; i++) { if (input[i] == ' ' || input[i] == '\r' || input[i] == '\n') { input[i] = 0; } } int j = 0; for (int i = 0; input[i] == 0 || i < inputlen; i++) { if (input[i] != 0 && j == 0) { argv[argc++] = &input[i]; j = 1; continue; } if (input[i] == 0 && j == 1) { j = 0; continue; } } }