You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.0 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. #include "cmd_scheduler.hpp"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "sdk\components\zprotocols\errorcode\errorcode.hpp"
  5. using namespace iflytop;
  6. #define TAG "CMD"
  7. void CmdScheduler::registerCmd(std::string cmd, const char* helpinfo, int npara, call_cmd_t call_cmd) {
  8. CMD cmdinfo;
  9. cmdinfo.call_cmd = call_cmd;
  10. cmdinfo.help_info = helpinfo;
  11. cmdinfo.npara = npara;
  12. m_cmdMap[cmd] = cmdinfo;
  13. }
  14. void CmdScheduler::regbasiccmd() {
  15. this->registerCmd("help", "", 0, [this](Context* context) {
  16. ZLOGI(TAG, "cmdlist:");
  17. for (auto it = m_cmdMap.begin(); it != m_cmdMap.end(); it++) {
  18. ZLOGI(TAG, " %s %s", it->first.c_str(), it->second.help_info.c_str());
  19. }
  20. return (int32_t)0;
  21. });
  22. this->registerCmd("sleep_ms", "(ms)", 1, [this](Context* context) {
  23. int ms = atoi(context->argv[1]);
  24. osDelay(ms);
  25. return 0;
  26. });
  27. }
  28. void CmdScheduler::initialize(UART_HandleTypeDef* huart, uint32_t rxbufsize) {
  29. m_rxbufsize = rxbufsize;
  30. m_uart = new ZUART();
  31. ZASSERT(m_uart != NULL);
  32. ZUART::cfg_t cfg;
  33. cfg.huart = huart;
  34. cfg.rxbuffersize = rxbufsize;
  35. cfg.rxovertime_ms = 3;
  36. cfg.name = "CmdSchedulerUart";
  37. rxbuf = new char[rxbufsize + 1];
  38. ZASSERT(rxbuf != NULL);
  39. m_uart->initialize(&cfg);
  40. ZASSERT(m_uart->startRxIt());
  41. m_uart->setrxcb([this](uint8_t* data, size_t len) {
  42. if (m_dataisready) {
  43. return;
  44. }
  45. memcpy(rxbuf, data, len);
  46. rxbuf[len] = '\0';
  47. m_rxsize = len;
  48. m_dataisready = true;
  49. // on data ,in irq context
  50. });
  51. regbasiccmd();
  52. }
  53. void CmdScheduler::schedule() {
  54. if (!m_dataisready) {
  55. return;
  56. }
  57. for (int i = 0; i < m_rxsize; i++) {
  58. if (rxbuf[i] == '\r' || rxbuf[i] == '\n') {
  59. rxbuf[i] = '\0';
  60. }
  61. }
  62. for (int i = 0; i < m_rxsize; i++) {
  63. if (rxbuf[i] != '\0') {
  64. ZLOGI(TAG, "docmd: %s", &rxbuf[i]);
  65. int inext = strlen(&rxbuf[i]) + i;
  66. int32_t ecode = callcmd(&rxbuf[i]);
  67. i = inext;
  68. if (ecode != 0) {
  69. ZLOGE(TAG, "callcmd %s fail:%s(%d)", &rxbuf[i], err::error2str(ecode), ecode);
  70. break;
  71. }
  72. }
  73. }
  74. ZLOGI(TAG, "process_rx_cmd:end");
  75. m_dataisready = false;
  76. }
  77. void CmdScheduler::tx(const char* data, int len) { m_uart->tx((uint8_t*)data, len); }
  78. int32_t CmdScheduler::callcmd(const char* cmd) {
  79. int argc = 0;
  80. char* argv[10] = {0};
  81. memset(cmdcache, 0, sizeof(cmdcache));
  82. argc = 0;
  83. memset(argv, 0, sizeof(argv));
  84. strcpy(cmdcache, cmd);
  85. remove_note(cmdcache, strlen(cmdcache));
  86. prase_cmd(cmdcache, strlen(cmdcache), argc, argv);
  87. if (argc == 0) {
  88. return (int32_t)0;
  89. }
  90. // printf("argc:%d\n", argc);
  91. // for (size_t i = 0; i < argc; i++) {
  92. // printf("argv[%d]:%s\n", i, argv[i]);
  93. // }
  94. /**
  95. * @brief ָ
  96. */
  97. auto cmder = m_cmdMap.find(string(argv[0]));
  98. if (cmder != m_cmdMap.end()) {
  99. Context context;
  100. context.argc = argc;
  101. context.argv = argv;
  102. // ZLOGI(TAG, "callcmd:argc %d %d", argc, cmder->second.npara);
  103. if (cmder->second.npara != context.argc - 1) return err::kce_cmd_param_num_error;
  104. int32_t ret = cmder->second.call_cmd(&context);
  105. if (ret == 0) {
  106. ZLOGI(TAG, "success", argv[0]);
  107. }
  108. return ret;
  109. } else {
  110. return err::kce_cmd_not_found;
  111. }
  112. }
  113. void CmdScheduler::remove_note(char* input, int inputlen) {
  114. bool detect_note = false;
  115. for (size_t i = 0; i < inputlen; i++) {
  116. if (!detect_note && input[i] == '#') {
  117. detect_note = true;
  118. }
  119. if (detect_note) {
  120. input[i] = 0;
  121. }
  122. }
  123. }
  124. void CmdScheduler::prase_cmd(char* input, int inputlen, int& argc, char* argv[]) {
  125. for (size_t i = 0; input[i] == 0 || i < inputlen; i++) {
  126. if (input[i] == ' ' || input[i] == '\r' || input[i] == '\n') {
  127. input[i] = 0;
  128. }
  129. }
  130. int j = 0;
  131. for (int i = 0; input[i] == 0 || i < inputlen; i++) {
  132. if (input[i] != 0 && j == 0) {
  133. argv[argc++] = &input[i];
  134. j = 1;
  135. continue;
  136. }
  137. if (input[i] == 0 && j == 1) {
  138. j = 0;
  139. continue;
  140. }
  141. }
  142. }