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