4 changed files with 270 additions and 1 deletions
-
1components/cmdscheduler/cmd_scheduler.hpp
-
189components/cmdscheduler/cmd_scheduler_v2.cpp
-
79components/cmdscheduler/cmd_scheduler_v2.hpp
-
2components/zprotocols/zcancmder_v2
@ -0,0 +1,189 @@ |
|||||
|
|
||||
|
#include "cmd_scheduler_v2.hpp"
|
||||
|
|
||||
|
#include <stdlib.h>
|
||||
|
#include <string.h>
|
||||
|
|
||||
|
#include "sdk\components\zprotocols\errorcode\errorcode.hpp"
|
||||
|
using namespace iflytop; |
||||
|
|
||||
|
#define TAG "CMD"
|
||||
|
|
||||
|
void CmdSchedulerV2::registerCmd(const char* cmdname, const char* helpinfo, int paraNum, ICmdFunction_t cmdimpl) { |
||||
|
CMD cmdinfo; |
||||
|
cmdinfo.call_cmd = cmdimpl; |
||||
|
cmdinfo.help_info = helpinfo; |
||||
|
cmdinfo.npara = paraNum; |
||||
|
m_cmdMap[cmdname] = cmdinfo; |
||||
|
} |
||||
|
|
||||
|
void CmdSchedulerV2::regbasiccmd() { |
||||
|
this->registerCmd("help", "", 0, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
||||
|
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](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
||||
|
int ms = atoi(paraV[0]); |
||||
|
osDelay(ms); |
||||
|
return 0; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
void CmdSchedulerV2::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(); |
||||
|
} |
||||
|
// int32_t getAckInt32Val(int index) {
|
||||
|
// int32_t getAckInt32Num() {
|
||||
|
|
||||
|
void CmdSchedulerV2::schedule() { |
||||
|
ICmdParserACK ack; |
||||
|
|
||||
|
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]);
|
||||
|
printf("docmd: %s \n", &rxbuf[i]); |
||||
|
|
||||
|
int inext = strlen(&rxbuf[i]) + i; |
||||
|
memset(&ack, 0, sizeof(ack)); |
||||
|
callcmd(&rxbuf[i], &ack); |
||||
|
i = inext; |
||||
|
|
||||
|
if (ack.ecode != 0) { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
// if (m_rxsize != 1) {
|
||||
|
// ZLOGI(TAG, "doscript:end");
|
||||
|
// }
|
||||
|
m_dataisready = false; |
||||
|
} |
||||
|
void CmdSchedulerV2::dumpack(ICmdParserACK* ack) { |
||||
|
if (ack->ecode == 0) { |
||||
|
printf("\tok -> "); |
||||
|
if (ack->acktype == ack->kAckType_none) { |
||||
|
printf("\n"); |
||||
|
} else if (ack->acktype == ack->kAckType_int32) { |
||||
|
for (int i = 0; i < ack->getAckInt32Num(); i++) { |
||||
|
printf(" %d", ack->getAckInt32Val(i)); |
||||
|
} |
||||
|
printf("\n"); |
||||
|
} else if (ack->acktype == ack->kAckType_buf) { |
||||
|
for (int i = 0; i < ack->rawlen; i++) { |
||||
|
printf(" %02x", ack->rawdata[i]); |
||||
|
} |
||||
|
printf("\n"); |
||||
|
} else { |
||||
|
printf("\n"); |
||||
|
} |
||||
|
} else { |
||||
|
printf("\tfailed:%s(%d)\n", err::error2str(ack->ecode), ack->ecode); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// void CmdSchedulerV2::tx(const char* data, int len) { m_uart->tx((uint8_t*)data, len); }
|
||||
|
int32_t CmdSchedulerV2::callcmd(const char* cmd, ICmdParserACK* ack) { |
||||
|
int32_t 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()) { |
||||
|
if (cmder->second.npara != argc - 1) { |
||||
|
ack->ecode = err::kcmd_param_num_error; |
||||
|
return err::kcmd_param_num_error; |
||||
|
} |
||||
|
cmder->second.call_cmd((int32_t)(argc - 1), (const char**)(&argv[1]), ack); |
||||
|
return ack->ecode; |
||||
|
|
||||
|
} else { |
||||
|
ack->ecode = err::kcmd_not_found; |
||||
|
return err::kcmd_not_found; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void CmdSchedulerV2::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 CmdSchedulerV2::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; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,79 @@ |
|||||
|
#pragma once
|
||||
|
#include <map>
|
||||
|
#include <string>
|
||||
|
|
||||
|
#include "sdk/os/zos.hpp"
|
||||
|
#include "sdk\components\zprotocols\errorcode\errorcode.hpp"
|
||||
|
#include "sdk\components\zprotocols\zcancmder_v2\api\api.hpp"
|
||||
|
|
||||
|
namespace iflytop { |
||||
|
using namespace std; |
||||
|
|
||||
|
class CmdSchedulerV2 : public ICmdParser { |
||||
|
public: |
||||
|
class CMD { |
||||
|
public: |
||||
|
ICmdFunction_t call_cmd; |
||||
|
string help_info; |
||||
|
int npara; |
||||
|
}; |
||||
|
|
||||
|
private: |
||||
|
map<string, CMD> m_cmdMap; |
||||
|
|
||||
|
ZUART* m_uart; |
||||
|
char* rxbuf; |
||||
|
int32_t m_rxsize = 0; |
||||
|
|
||||
|
uint32_t m_rxbufsize; |
||||
|
|
||||
|
bool m_dataisready = false; |
||||
|
|
||||
|
char cmdcache[1024] = {0}; |
||||
|
|
||||
|
public: |
||||
|
void initialize(UART_HandleTypeDef* huart, uint32_t rxbufsize); |
||||
|
void registerCmd(const char* cmdname, const char* helpinfo, int paraNum, ICmdFunction_t cmdimpl); |
||||
|
// void tx(const char* data, int len);
|
||||
|
void schedule(); |
||||
|
|
||||
|
private: |
||||
|
void regbasiccmd(); |
||||
|
int32_t callcmd(const char* cmd, ICmdParserACK* ack); |
||||
|
void prase_cmd(char* input, int inputlen, int& argc, char* argv[]); |
||||
|
void remove_note(char* input, int inputlen); |
||||
|
void dumpack(ICmdParserACK* ack); |
||||
|
}; |
||||
|
#if 0
|
||||
|
|
||||
|
#define DO_CMD(cond) \
|
||||
|
{ \ |
||||
|
int32_t ret = cond; \ |
||||
|
if (ret != 0) { \ |
||||
|
return ret; \ |
||||
|
} \ |
||||
|
} |
||||
|
#define IMPL_CMD(cmd, ...) \
|
||||
|
DO_CMD(findmodule(con->getInt(1), &module)); \ |
||||
|
DO_CMD(module->cmd(__VA_ARGS__)); \ |
||||
|
return (int32_t)0; |
||||
|
|
||||
|
#define IMPL_READ_STATE(cmd, ...) \
|
||||
|
DO_CMD(findmodule(con->getInt(1), &module)); \ |
||||
|
DO_CMD(module->cmd(__VA_ARGS__)); \ |
||||
|
cmd_dump_ack(ack); \ |
||||
|
return (int32_t)0; |
||||
|
|
||||
|
#define REG_CMD___NO_ACK(prefix, cmd, para, npara, ...) /**/ \
|
||||
|
m_cmdScheduler->registerCmd(prefix #cmd, para, npara, [this](CmdSchedulerV2::Context* con) { /**/ \ |
||||
|
IMPL_CMD(cmd, __VA_ARGS__); /**/ \ |
||||
|
}); |
||||
|
|
||||
|
#define REG_CMD_WITH_ACK(prefix, cmd, para, npara, acktype, ...) /**/ \
|
||||
|
m_cmdScheduler->registerCmd(prefix #cmd, para, npara, [this](CmdSchedulerV2::Context* con) { /**/ \ |
||||
|
acktype ack; /**/ \ |
||||
|
IMPL_READ_STATE(cmd, __VA_ARGS__); /**/ \ |
||||
|
}); |
||||
|
#endif
|
||||
|
|
||||
|
} // namespace iflytop
|
@ -1 +1 @@ |
|||||
Subproject commit 307d17935801671e62bf07864b08b88499a712db |
|
||||
|
Subproject commit 81e5d4c18295ebc8e79e14a7ea072efe7fb62b4a |
Write
Preview
Loading…
Cancel
Save
Reference in new issue