15 changed files with 8 additions and 1645 deletions
-
199components/cmdscheduler/cmd_scheduler_uart_dma.cpp
-
51components/cmdscheduler/cmd_scheduler_uart_dma.hpp
-
209components/cmdscheduler/cmd_scheduler_v2.cpp
-
114components/cmdscheduler/cmd_scheduler_v2.hpp
-
5components/modbus/modbus_client.hpp
-
7components/subcanmodule/dep.hpp
-
99components/subcanmodule/zcancmder_subboard_initer.cpp
-
47components/subcanmodule/zcancmder_subboard_initer.hpp
-
6components/zcancmder/zcanreceiver.cpp
-
8components/zcancmder/zcanreceiver.hpp
-
541components/zcancmder/zcanreceiver_master.cpp
-
113components/zcancmder/zcanreceiver_master.hpp
-
219components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.cpp
-
33components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.hpp
-
2components/zprotocols/zcancmder_v2
@ -1,199 +0,0 @@ |
|||
|
|||
#include "cmd_scheduler_uart_dma.hpp"
|
|||
|
|||
#include <stdlib.h>
|
|||
#include <string.h>
|
|||
|
|||
#include "project_configs.h"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
|
|||
using namespace iflytop; |
|||
|
|||
#define TAG "CMD"
|
|||
|
|||
#if 0
|
|||
|
|||
void CmdSchedulerUartDMA::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 CmdSchedulerUartDMA::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 CmdSchedulerUartDMA::initialize(UART_HandleTypeDef* huart, uint32_t rxbufsize) { |
|||
m_huart = huart; |
|||
|
|||
rxbuf = new char[rxbufsize + 1]; |
|||
ZASSERT(rxbuf != NULL); |
|||
m_rxbufsize = rxbufsize; |
|||
|
|||
// 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 CmdSchedulerUartDMA::schedule() { |
|||
static ICmdParserACK ack = {0}; |
|||
|
|||
HAL_UART_StateTypeDef state = HAL_UART_GetState(m_huart); |
|||
if (state == HAL_UART_STATE_BUSY_RX || state == HAL_UART_STATE_BUSY_TX_RX) { |
|||
HAL_UARTEx_ReceiveToIdle_DMA(m_huart, (uint8_t*)rxbuf, m_rxbufsize); |
|||
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]);
|
|||
ZLOGI(TAG, "docmd: %s", &rxbuf[i]); |
|||
|
|||
int inext = strlen(&rxbuf[i]) + i; |
|||
memset(&ack, 0, sizeof(ack)); |
|||
#ifdef IFLYTOP_ENABLE_EXCEPTION
|
|||
try { |
|||
callcmd(&rxbuf[i], &ack); |
|||
} catch (...) { |
|||
ack.ecode = err::kcatch_exception; |
|||
} |
|||
#else
|
|||
callcmd(&rxbuf[i], &ack); |
|||
#endif
|
|||
dumpack(&ack); |
|||
i = inext; |
|||
|
|||
if (ack.ecode != 0) { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
// if (m_rxsize != 1) {
|
|||
// ZLOGI(TAG, "doscript:end");
|
|||
// }
|
|||
m_dataisready = false; |
|||
} |
|||
void CmdSchedulerUartDMA::dumpack(ICmdParserACK* ack) { |
|||
if (ack->ecode == 0) { |
|||
if (ack->acktype == ack->kAckType_none) { |
|||
ZLOGI(TAG, "\tok"); |
|||
} else if (ack->acktype == ack->kAckType_int32) { |
|||
ZLOGI(TAG, "\tok-->"); |
|||
for (int i = 0; i < ack->getAckInt32Num(); i++) { |
|||
// printf(" %d", (int)ack->getAckInt32Val(i));
|
|||
ZLOGI(TAG, "\t\t%d", (int)ack->getAckInt32Val(i)); |
|||
} |
|||
} else if (ack->acktype == ack->kAckType_buf) { |
|||
ZLOGI(TAG, "\tok-->"); |
|||
for (int i = 0; i < ack->rawlen; i++) { |
|||
printf(" %02x", ack->rawdata[i]); |
|||
} |
|||
printf("\n"); |
|||
} else { |
|||
ZLOGI(TAG, "\tok"); |
|||
} |
|||
} else { |
|||
ZLOGI(TAG, "\tfailed:%s(%d)", err::error2str(ack->ecode), (int)ack->ecode); |
|||
} |
|||
} |
|||
|
|||
// void CmdSchedulerUartDMA::tx(const char* data, int len) { m_uart->tx((uint8_t*)data, len); }
|
|||
int32_t CmdSchedulerUartDMA::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 CmdSchedulerUartDMA::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 CmdSchedulerUartDMA::prase_cmd(char* input, int inputlen, int32_t& 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; |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif
|
@ -1,51 +0,0 @@ |
|||
#pragma once
|
|||
#include <map>
|
|||
#include <string>
|
|||
|
|||
#include "sdk/os/zos.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\api.hpp"
|
|||
#if 0
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class CmdSchedulerUartDMA : public ICmdParser { |
|||
public: |
|||
class CMD { |
|||
public: |
|||
ICmdFunction_t call_cmd; |
|||
string help_info; |
|||
int npara; |
|||
}; |
|||
|
|||
private: |
|||
map<string, CMD> m_cmdMap; |
|||
|
|||
UART_HandleTypeDef* m_huart; |
|||
char* rxbuf; |
|||
uint32_t m_rxbufsize; |
|||
|
|||
int32_t m_rxsize = 0; |
|||
|
|||
bool m_dataisready = false; |
|||
|
|||
char cmdcache[1024] = {0}; |
|||
bool rxdmaisworking = false; |
|||
|
|||
public: |
|||
void initialize(UART_HandleTypeDef* huart, uint32_t rxbufsize); |
|||
virtual void regCMD(const char* cmdname, const char* helpinfo, int paraNum, ICmdFunction_t cmdimpl) override { registerCmd(cmdname, helpinfo, paraNum, cmdimpl); } |
|||
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, int32_t& argc, char* argv[]); |
|||
void remove_note(char* input, int inputlen); |
|||
void dumpack(ICmdParserACK* ack); |
|||
}; |
|||
} // namespace iflytop
|
|||
|
|||
#endif
|
@ -1,209 +0,0 @@ |
|||
|
|||
#include "cmd_scheduler_v2.hpp"
|
|||
|
|||
#include <stdlib.h>
|
|||
#include <string.h>
|
|||
|
|||
#include "project_configs.h"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\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(ZIUartReceiver* receiver) { |
|||
// m_uart = new ZUARTDmaReceiver();
|
|||
m_uart = receiver; |
|||
ZASSERT(m_uart != NULL); |
|||
|
|||
m_rxbufsize = receiver->gertRxBufSize(); |
|||
rxbuf = new char[m_rxbufsize + 1]; |
|||
ZASSERT(rxbuf != NULL); |
|||
|
|||
// m_uart->initialize(&cfg);
|
|||
m_uart->startRx([this](uint8_t* data, size_t len) { |
|||
if (m_dataisready) return; |
|||
if (len == 0) 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() { |
|||
static ICmdParserACK ack = {0}; |
|||
|
|||
if (!m_dataisready) { |
|||
return; |
|||
} |
|||
ZLOGI(TAG, "----------------------------doscript:begin------------------------"); |
|||
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]);
|
|||
ZLOGI(TAG, "docmd: %s", &rxbuf[i]); |
|||
|
|||
int inext = strlen(&rxbuf[i]) + i; |
|||
memset(&ack, 0, sizeof(ack)); |
|||
#ifdef IFLYTOP_ENABLE_EXCEPTION
|
|||
try { |
|||
callcmd(&rxbuf[i], &ack); |
|||
} catch (...) { |
|||
ack.ecode = err::kcatch_exception; |
|||
} |
|||
#else
|
|||
callcmd(&rxbuf[i], &ack); |
|||
#endif
|
|||
dumpack(&ack); |
|||
i = inext; |
|||
|
|||
if (ack.ecode != 0) { |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
// if (m_rxsize != 1) {
|
|||
// ZLOGI(TAG, "doscript:end");
|
|||
// }
|
|||
m_dataisready = false; |
|||
} |
|||
#define ALIAS_LEN 8
|
|||
|
|||
void CmdSchedulerV2::dumpack(ICmdParserACK* ack) { |
|||
if (ack->ecode == 0) { |
|||
ZLOGI(TAG, "\tok"); |
|||
if (ack->acktype == ack->kAckType_none) { |
|||
} else if (ack->acktype == ack->kAckType_int32) { |
|||
for (int i = 0; i < ack->getAckInt32Num(); i++) { |
|||
ZLOGI(TAG, "\tACK[%d] \t\t%d", i, (int)ack->getAckInt32Val(i)); |
|||
} |
|||
} else if (ack->acktype == ack->kAckType_buf) { |
|||
ZLOGI_NOT_END_LINE(TAG, "\t ACK_BUF(%d):\n", ack->rawlen); |
|||
for (int32_t i = 0; i * ALIAS_LEN < ack->rawlen; i++) { |
|||
ZLOGI_NOT_END_LINE(TAG, "%8x\t\t", i * ALIAS_LEN); |
|||
for (int32_t j = 0; j < ALIAS_LEN; j++) { |
|||
if (i * ALIAS_LEN + j < ack->rawlen) { |
|||
printf("%02x ", ack->rawdata[i * ALIAS_LEN + j]); |
|||
} |
|||
} |
|||
printf("|"); |
|||
for (int32_t j = 0; j < ALIAS_LEN; j++) { |
|||
if (i * ALIAS_LEN + j < ack->rawlen) { |
|||
if (ack->rawdata[i * ALIAS_LEN + j] >= 0x20 && ack->rawdata[i * ALIAS_LEN + j] <= 0x7e) { |
|||
printf("%c", ack->rawdata[i * ALIAS_LEN + j]); |
|||
} else { |
|||
printf("."); |
|||
} |
|||
} |
|||
} |
|||
printf("\n"); |
|||
} |
|||
} else if (ack->acktype == ack->kAckType_str) { |
|||
ZLOGI_NOT_END_LINE(TAG, "\t ACK_BUF(%d):", ack->rawlen); |
|||
printf("%s\n", (char*)ack->rawdata); |
|||
} |
|||
} else { |
|||
ZLOGI(TAG, "\tfailed:%s(%d)", err::error2str(ack->ecode), (int)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 >= 0 && 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, int32_t& argc, char* argv[]) { |
|||
for (int i = 0; input[i] == 0 || i < inputlen; i++) { |
|||
if (input[i] == ' ' || input[i] == '\r' || input[i] == '\n' || input[i] == '\t' || input[i] == '(' || input[i] == ')' || input[i] == ',') { |
|||
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; |
|||
} |
|||
} |
|||
} |
@ -1,114 +0,0 @@ |
|||
#pragma once
|
|||
#include <map>
|
|||
#include <string>
|
|||
|
|||
#include "sdk/os/zos.hpp"
|
|||
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\api.hpp"
|
|||
//
|
|||
#include "sdk\components\api\zi_uart_receiver.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; |
|||
|
|||
ZIUartReceiver* m_uart; |
|||
char* rxbuf; |
|||
int32_t m_rxsize = 0; |
|||
|
|||
uint32_t m_rxbufsize; |
|||
|
|||
bool m_dataisready = false; |
|||
|
|||
char cmdcache[1024] = {0}; |
|||
|
|||
public: |
|||
void initialize(ZIUartReceiver* receiver); |
|||
|
|||
virtual void regCMD(const char* cmdname, const char* helpinfo, int paraNum, ICmdFunction_t cmdimpl) override { registerCmd(cmdname, helpinfo, paraNum, cmdimpl); } |
|||
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, int32_t& argc, char* argv[]); |
|||
void remove_note(char* input, int inputlen); |
|||
void dumpack(ICmdParserACK* ack); |
|||
}; |
|||
|
|||
class __Params { |
|||
int32_t m_paramN; |
|||
const char** m_paraV; |
|||
|
|||
public: |
|||
__Params(int32_t paramN, const char** paraV) : m_paramN(paramN), m_paraV(paraV) {} |
|||
|
|||
int32_t getInt(int32_t index) { |
|||
index -= 1; |
|||
if (index >= m_paramN) { |
|||
return 0; |
|||
} |
|||
if (index < 0) { |
|||
return 0; |
|||
} |
|||
return atoi(m_paraV[index]); |
|||
} |
|||
|
|||
bool getBool(int32_t index) { |
|||
index -= 1; |
|||
if (index >= m_paramN) { |
|||
return false; |
|||
} |
|||
if (index < 0) { |
|||
return false; |
|||
} |
|||
return atoi(m_paraV[index]) != 0; |
|||
} |
|||
}; |
|||
|
|||
#define DO_CMD(cond) \
|
|||
{ \ |
|||
int32_t ret = cond; \ |
|||
if (ret != 0) { \ |
|||
return ret; \ |
|||
} \ |
|||
} |
|||
#define IMPL_CMD(cmd, ...) \
|
|||
__Params con(paramN, paraV); \ |
|||
DO_CMD(findmodule(con.getInt(1), &module)); \ |
|||
DO_CMD(module->cmd(__VA_ARGS__)); \ |
|||
return (int32_t)0; |
|||
|
|||
#define IMPL_READ_STATE(cmd, ...) \
|
|||
__Params con(paramN, paraV); \ |
|||
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](int32_t paramN, const char** paraV, ICmdParserACK* __ack) { /**/ \ |
|||
IMPL_CMD(cmd, __VA_ARGS__); /**/ \ |
|||
}); |
|||
|
|||
#define REG_CMD_WITH_ACK(prefix, cmd, para, npara, acktype, ...) /**/ \
|
|||
m_cmdScheduler->registerCmd(prefix #cmd, para, npara, [this](int32_t paramN, const char** paraV, ICmdParserACK* __ack) { /**/ \ |
|||
acktype ack; /**/ \ |
|||
IMPL_READ_STATE(cmd, __VA_ARGS__); /**/ \ |
|||
}); |
|||
|
|||
} // namespace iflytop
|
@ -1,7 +0,0 @@ |
|||
#pragma once
|
|||
#include "sdk\components\cmdscheduler\cmd_scheduler_v2.hpp"
|
|||
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
|
|||
#include "sdk\components\zcancmder\zcan_board_module.hpp"
|
|||
#include "sdk\components\zprotocol_helper\micro_computer_module_device_script_cmder_paser.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\protocol_parser.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_manager.hpp"
|
@ -1,99 +0,0 @@ |
|||
#include "zcancmder_subboard_initer.hpp"
|
|||
//
|
|||
#include "sdk\components\flash\znvs.hpp"
|
|||
//
|
|||
#include <stdio.h>
|
|||
#include <string.h>
|
|||
|
|||
#include "project_configs.h"
|
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
|
|||
using namespace iflytop; |
|||
const char* TAG = PC_PROJECT_NAME; |
|||
|
|||
__weak void nvs_init_cb() {} |
|||
extern DMA_HandleTypeDef PC_DEBUG_UART_DMA_HANDLER; |
|||
|
|||
int32_t ZCancmderSubboardIniter::get_module_id(int32_t moduleIndex) { return m_cfg.deviceId * 10 + moduleIndex; } |
|||
|
|||
void ZCancmderSubboardIniter::init(cfg_t* cfg) { |
|||
m_cfg = *cfg; |
|||
|
|||
chip_cfg_t chipcfg = {}; |
|||
chipcfg.us_dleay_tim = &PC_SYS_DELAY_US_TIMER; |
|||
chipcfg.tim_irq_scheduler_tim = &PC_SYS_TIM_IRQ_SCHEDULER_TIMER; |
|||
chipcfg.huart = &PC_DEBUG_UART; |
|||
chipcfg.debuglight = PC_DEBUG_LIGHT_GPIO; |
|||
|
|||
chip_init(&chipcfg); |
|||
|
|||
zos_cfg_t zoscfg; |
|||
zos_init(&zoscfg); |
|||
|
|||
ZLOGI(TAG, "boardId:%d,version:%d", m_cfg.deviceId, PC_VERSION); |
|||
|
|||
/*******************************************************************************
|
|||
* NVSINIT * |
|||
*******************************************************************************/ |
|||
#if PC_NVS_ENABLE
|
|||
if (PC_NVS_ENABLE) { |
|||
ZNVS::ins().initialize(PC_NVS_CONFIG_FLASH_SECTOR); |
|||
nvs_init_cb(); |
|||
ZNVS::ins().init_config(); |
|||
} |
|||
#endif
|
|||
|
|||
auto zcanCmder_cfg = zcanCmder.createCFG(m_cfg.deviceId); |
|||
zcanCmder.init(zcanCmder_cfg); |
|||
ziProtocolParser.initialize(&zcanCmder); |
|||
|
|||
{ |
|||
static ZUARTDmaReceiver dmaUartReceiver; |
|||
static ZUARTDmaReceiver::hardware_config_t cfg = { |
|||
.huart = &PC_DEBUG_UART, |
|||
.dma_rx = &PC_DEBUG_UART_DMA_HANDLER, |
|||
.rxbuffersize = PC_DEBUG_UART_RX_BUF_SIZE, |
|||
.rxovertime_ms = 10, |
|||
}; |
|||
dmaUartReceiver.initialize(&cfg); |
|||
cmder.initialize(&dmaUartReceiver); |
|||
zModuleDeviceManager.initialize(nullptr); |
|||
zModuleDeviceScriptCmderPaser.initialize(&cmder, &zModuleDeviceManager); |
|||
} |
|||
eventBusSender.initialize(&zcanCmder); |
|||
|
|||
initmodule(); |
|||
} |
|||
|
|||
void ZCancmderSubboardIniter::initmodule() { |
|||
static ZCanBoardModule boardmodule; |
|||
|
|||
ZCanBoardModule::hardware_config_t hcfg = {}; |
|||
static_assert(ZARRAY_SIZE(hcfg.input) == ZARRAY_SIZE(m_cfg.input_gpio)); |
|||
static_assert(ZARRAY_SIZE(hcfg.output) == ZARRAY_SIZE(m_cfg.output_gpio)); |
|||
static_assert(ZARRAY_SIZE(hcfg.temperature_sensor) == ZARRAY_SIZE(m_cfg.temperature_sensor)); |
|||
static_assert(ZARRAY_SIZE(hcfg.pwmctrl) == ZARRAY_SIZE(m_cfg.pwmctrl)); |
|||
|
|||
memcpy(&hcfg.input, &m_cfg.input_gpio, sizeof(m_cfg.input_gpio)); |
|||
memcpy(&hcfg.output, &m_cfg.output_gpio, sizeof(m_cfg.output_gpio)); |
|||
memcpy(&hcfg.temperature_sensor, &m_cfg.temperature_sensor, sizeof(m_cfg.temperature_sensor)); |
|||
memcpy(&hcfg.pwmctrl, &m_cfg.pwmctrl, sizeof(m_cfg.pwmctrl)); |
|||
|
|||
boardmodule.initialize(get_module_id(0), &hcfg); |
|||
ziProtocolParser.registerModule(&boardmodule); |
|||
zModuleDeviceManager.registerModule(&boardmodule); |
|||
} |
|||
|
|||
void ZCancmderSubboardIniter::register_module(ZIModule* module) { |
|||
ziProtocolParser.registerModule(module); |
|||
zModuleDeviceManager.registerModule(module); |
|||
} |
|||
|
|||
void ZCancmderSubboardIniter::loop() { |
|||
while (true) { |
|||
OSDefaultSchduler::getInstance()->loop(); |
|||
zcanCmder.loop(); |
|||
cmder.schedule(); |
|||
} |
|||
} |
|||
#endif
|
@ -1,47 +0,0 @@ |
|||
#pragma once
|
|||
#include "sdk/os/zos.hpp"
|
|||
#include "sdk\components\cmdscheduler\cmd_scheduler_v2.hpp"
|
|||
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
|
|||
#include "sdk\components\zcancmder\zcan_board_module.hpp"
|
|||
#include "sdk\components\zcancmder\zcanreceiver.hpp"
|
|||
#include "sdk\components\zprotocol_helper\micro_computer_module_device_script_cmder_paser.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\protocol_event_bus_sender.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\protocol_parser.hpp"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_manager.hpp"
|
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
|
|||
namespace iflytop { |
|||
class ZCancmderSubboardIniter { |
|||
public: |
|||
typedef struct { |
|||
int32_t deviceId; |
|||
ZGPIO::InputGpioCfg_t input_gpio[32]; |
|||
ZGPIO::OutputGpioCfg_t output_gpio[32]; |
|||
ZITemperature* temperature_sensor[8]; |
|||
ZIPWMCtrl* pwmctrl[8]; |
|||
} cfg_t; |
|||
|
|||
private: |
|||
ZCanCmder zcanCmder; |
|||
ZIProtocolParser ziProtocolParser; |
|||
ZModuleDeviceManager zModuleDeviceManager; |
|||
MicroComputerModuleDeviceScriptCmderPaser zModuleDeviceScriptCmderPaser; |
|||
ProtocolEventBusSender eventBusSender; |
|||
CmdSchedulerV2 cmder; |
|||
cfg_t m_cfg; |
|||
|
|||
public: |
|||
void init(cfg_t* cfg); |
|||
void register_module(ZIModule* module); |
|||
int32_t get_module_id(int32_t moduleIndex); |
|||
//
|
|||
void loop(); |
|||
|
|||
ZIEventBusSender* get_event_bus_sender() { return &eventBusSender; } |
|||
|
|||
private: |
|||
int32_t getDeviceId(); |
|||
void initmodule(); |
|||
}; |
|||
} // namespace iflytop
|
|||
#endif
|
@ -1,541 +0,0 @@ |
|||
#include "zcanreceiver_master.hpp"
|
|||
|
|||
#include "project_configs.h"
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\api\errorcode.hpp"
|
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
#include <stdio.h>
|
|||
#include <stdlib.h>
|
|||
#include <string.h>
|
|||
using namespace iflytop; |
|||
using namespace zcr; |
|||
|
|||
#define TAG "ZCanCommnaderMaster"
|
|||
|
|||
#define OVER_TIME_MS 5
|
|||
|
|||
#define MASK_32BIT(off) (0x01 << (off))
|
|||
|
|||
ZCanCommnaderMaster::CFG *ZCanCommnaderMaster::createCFG() { |
|||
CFG *cfg = new CFG(); |
|||
ZASSERT(cfg != NULL); |
|||
cfg->deviceId = 0; |
|||
#ifdef STM32F103xB
|
|||
cfg->canHandle = &hcan; |
|||
#else
|
|||
cfg->canHandle = &hcan1; |
|||
#endif
|
|||
cfg->canFilterIndex0 = 0; |
|||
cfg->maxFilterNum = 7; |
|||
cfg->rxfifoNum = CAN_RX_FIFO0; |
|||
return cfg; |
|||
} |
|||
void ZCanCommnaderMaster::init(CFG *cfg) { |
|||
HAL_StatusTypeDef hal_status; |
|||
m_config = cfg; |
|||
m_on_packet_map_lock.init(); |
|||
txlock.init(); |
|||
|
|||
/**
|
|||
* @brief 初始化CAN |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief 初始化消息接收buf |
|||
*/ |
|||
m_canPacketRxBuffer[0].dataIsReady = false; |
|||
m_canPacketRxBuffer[0].id = 1; // 只接收来自主机的消息
|
|||
m_canPacketRxBuffer[0].m_canPacketNum = 0; |
|||
|
|||
/**
|
|||
* @brief 初始化过滤器 |
|||
*/ |
|||
hal_status = initializeFilter(); |
|||
if (hal_status != HAL_OK) { |
|||
ZLOGE(TAG, "start can initializeFilter fail\r\n"); |
|||
return; |
|||
} |
|||
/**
|
|||
* @brief 启动CAN |
|||
*/ |
|||
hal_status = HAL_CAN_Start(m_config->canHandle); // 开启CAN
|
|||
if (hal_status != HAL_OK) { |
|||
ZLOGE(TAG, "start can fail\r\n"); |
|||
return; |
|||
} |
|||
/**
|
|||
* @brief 监听回调 |
|||
*/ |
|||
ZCanIRQDispatcher::instance().regListener(this); |
|||
HAL_StatusTypeDef status = activateRxIT(); |
|||
if (status != HAL_OK) { |
|||
ZLOGE(TAG, "activateRxIT fail\r\n"); |
|||
return; |
|||
} |
|||
m_loopThread.init("ZCanCommnaderMaster", 1024, osPriorityAboveNormal); |
|||
m_loopThread.start([this]() { |
|||
while (true) { |
|||
loop(); |
|||
osDelay(1); |
|||
} |
|||
}); |
|||
} |
|||
HAL_StatusTypeDef ZCanCommnaderMaster::initializeFilter() { |
|||
/**
|
|||
* @brief ID区帧格式 |
|||
* [ 27:0 ] |
|||
* [ STDID ] [ EXTID ] |
|||
* [11 :9] [8:6] [5:0] [17:16] [15:8] [7:0] |
|||
* 优先级 属性 帧类型 目标ID 源ID |
|||
*/ |
|||
HAL_StatusTypeDef HAL_Status; |
|||
CAN_FilterTypeDef sFilterConfig; |
|||
|
|||
uint32_t filterId; |
|||
uint32_t mask; |
|||
|
|||
memset(&sFilterConfig, 0, sizeof(sFilterConfig)); |
|||
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; // 设为MASK模式
|
|||
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; // CAN_FILTERSCALE_16BIT
|
|||
sFilterConfig.FilterFIFOAssignment = m_config->rxfifoNum; // 关联过滤器到rxfifoNum
|
|||
sFilterConfig.FilterActivation = ENABLE; // 激活过滤器
|
|||
sFilterConfig.SlaveStartFilterBank = m_config->maxFilterNum; // slave filter start index
|
|||
|
|||
/*******************************************************************************
|
|||
* 接收所有消息 * |
|||
*******************************************************************************/ |
|||
filterId = (0); //
|
|||
mask = (0); //
|
|||
sFilterConfig.FilterBank = m_config->canFilterIndex0; //
|
|||
sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
|
|||
sFilterConfig.FilterMaskIdHigh = (mask & 0xffff0000) >> 16; //
|
|||
sFilterConfig.FilterIdLow = filterId & 0xffff; //
|
|||
sFilterConfig.FilterIdHigh = (filterId & 0xffff0000) >> 16; //
|
|||
HAL_Status = HAL_CAN_ConfigFilter(m_config->canHandle, &sFilterConfig); |
|||
if (HAL_Status != HAL_OK) { |
|||
ZLOGE(TAG, "HAL_CAN_ConfigFilter filter0 fail"); |
|||
return HAL_Status; |
|||
} |
|||
ZLOGI(TAG, "HAL_CAN_ConfigFilter filterID1 %08x", filterId >> 3); |
|||
return HAL_Status; |
|||
} |
|||
int32_t ZCanCommnaderMaster::sendCmdAndReceiveBuf(int32_t cmdid, int32_t subModuleid, int32_t *param, size_t npara, uint8_t *ack, int32_t *rxsize, int overtime_ms) { |
|||
zcr_cmd_header_t *cmdheader = (zcr_cmd_header_t *)txbuff; |
|||
cmdheader->packetType = kptv2_cmd; |
|||
cmdheader->packetindex = generateFreeIndex(); |
|||
cmdheader->cmdMainId = MODULE_CMDID(cmdid); |
|||
cmdheader->cmdSubId = CMD_SUB_ID(cmdid); |
|||
cmdheader->subModuleid = subModuleid; |
|||
// ZLOGI(TAG, "sendCmd %d %d %d %d", cmdheader->packetindex, cmdheader->cmdMainId, cmdheader->cmdSubId, cmdheader->subModuleid);
|
|||
int32_t *sendparam = (int32_t *)cmdheader->data; |
|||
for (size_t i = 0; i < npara; i++) { |
|||
sendparam[i] = param[i]; |
|||
} |
|||
int32_t txlen = sizeof(zcr_cmd_header_t) + npara * sizeof(int32_t); |
|||
|
|||
// 注册监听者
|
|||
bool rxdataIsReady = false; |
|||
int32_t errocode = 0; |
|||
regListener(cmdheader->packetindex, [this, &rxdataIsReady, &ack, &rxsize, &errocode](CanPacketRxBuffer *report) { |
|||
if (report->get_cmdheader()->packetType == kptv2_error_ack) { |
|||
auto *error_ack = report->get_param_as<int32_t>(); |
|||
errocode = *error_ack; |
|||
} else if (*rxsize < report->get_params_len()) { |
|||
errocode = err::kbuffer_not_enough; |
|||
} else { |
|||
*rxsize = report->get_params_len(); |
|||
memcpy(ack, report->get_params(), *rxsize); |
|||
} |
|||
rxdataIsReady = true; |
|||
}); |
|||
|
|||
// 发送消息
|
|||
sendPacket(txbuff, txlen); |
|||
|
|||
// 等待回执
|
|||
uint32_t enterticket = zos_get_tick(); |
|||
while (!rxdataIsReady) { |
|||
if (zos_haspassedms(enterticket) > (uint32_t)overtime_ms) { |
|||
ZLOGE(TAG, "sendPacketBlock timeout"); |
|||
unregListener(cmdheader->packetindex); |
|||
return err::kovertime; |
|||
} |
|||
osDelay(1); |
|||
} |
|||
unregListener(cmdheader->packetindex); |
|||
|
|||
return errocode; |
|||
} |
|||
|
|||
void ZCanCommnaderMaster::sendRawPacket(uint8_t *packet, size_t len) { sendPacket(packet, len); } |
|||
void ZCanCommnaderMaster::regRawPacketListener(rawpacket_t rawpacketcb) { m_rawpacketcb = rawpacketcb; } |
|||
|
|||
int32_t ZCanCommnaderMaster::sendCmd(int32_t cmdid, int32_t subModuleid, int32_t *param, size_t npara, int32_t *ack, size_t nack, int overtime_ms) { |
|||
zcr_cmd_header_t *cmdheader = (zcr_cmd_header_t *)txbuff; |
|||
cmdheader->packetType = kptv2_cmd; |
|||
cmdheader->packetindex = generateFreeIndex(); |
|||
cmdheader->cmdMainId = MODULE_CMDID(cmdid); |
|||
cmdheader->cmdSubId = CMD_SUB_ID(cmdid); |
|||
cmdheader->subModuleid = subModuleid; |
|||
// ZLOGI(TAG, "sendCmd %d %d %d %d", cmdheader->packetindex, cmdheader->cmdMainId, cmdheader->cmdSubId, cmdheader->subModuleid);
|
|||
int32_t *sendparam = (int32_t *)cmdheader->data; |
|||
for (size_t i = 0; i < npara; i++) { |
|||
sendparam[i] = param[i]; |
|||
} |
|||
|
|||
int32_t txlen = sizeof(zcr_cmd_header_t) + npara * sizeof(int32_t); |
|||
|
|||
/**
|
|||
* @brief 注册监听者 |
|||
*/ |
|||
bool rxdataIsReady = false; |
|||
int32_t errocode = 0; |
|||
regListener(cmdheader->packetindex, [this, &rxdataIsReady, &ack, &nack, &errocode](CanPacketRxBuffer *report) { |
|||
// ZLOGI(TAG, "....................................");
|
|||
if (report->get_cmdheader()->packetType == kptv2_error_ack) { |
|||
auto *error_ack = report->get_param_as<int32_t>(); |
|||
errocode = *error_ack; |
|||
// ZLOGI(TAG, "error_ack %d %s", *error_ack, err::error2str(*error_ack));
|
|||
} else { |
|||
// ZLOGI(TAG, "%d %d", report->get_datalen(), nack);
|
|||
int32_t *rxbuf = report->get_param_as<int32_t>(); |
|||
if (ack != nullptr && nack != 0) { |
|||
for (size_t i = 0; i < nack; i++) { |
|||
// ZLOGI(TAG, "ack[%d] = %d", i, rxbuf[i]);
|
|||
ack[i] = rxbuf[i]; |
|||
} |
|||
} |
|||
} |
|||
rxdataIsReady = true; |
|||
}); |
|||
|
|||
/**
|
|||
* @brief 发送消息 |
|||
*/ |
|||
sendPacket(txbuff, txlen); |
|||
|
|||
/**
|
|||
* @brief 等待回执 |
|||
*/ |
|||
uint32_t enterticket = zos_get_tick(); |
|||
while (!rxdataIsReady) { |
|||
if (zos_haspassedms(enterticket) > (uint32_t)overtime_ms) { |
|||
// ZLOGE(TAG, "sendPacketBlock timeout");
|
|||
unregListener(cmdheader->packetindex); |
|||
return err::kovertime; |
|||
} |
|||
osDelay(1); |
|||
} |
|||
unregListener(cmdheader->packetindex); |
|||
|
|||
return errocode; |
|||
} |
|||
|
|||
void ZCanCommnaderMaster::regEventPacketListener(onpacket_t on_event) { m_on_event = on_event; } |
|||
|
|||
void ZCanCommnaderMaster::regListener(uint16_t index, zcan_commnader_master_onpacket_t onack) { |
|||
zlock_guard l(m_on_packet_map_lock); |
|||
if (m_on_packet_map.size() > 10000) { |
|||
ZLOGW(TAG, "m_on_packet_map.size() = %d>10000", m_on_packet_map.size()); |
|||
} |
|||
ZCanCommnaderMasterListener listener; |
|||
listener.on_ack = onack; |
|||
m_on_packet_map[index] = listener; |
|||
} |
|||
void ZCanCommnaderMaster::unregListener(uint16_t index) { |
|||
zlock_guard l(m_on_packet_map_lock); |
|||
auto it = m_on_packet_map.find(index); |
|||
if (it != m_on_packet_map.end()) { |
|||
m_on_packet_map.erase(it); |
|||
} |
|||
} |
|||
|
|||
int ZCanCommnaderMaster::getListenerNum() { |
|||
zlock_guard l(m_on_packet_map_lock); |
|||
return m_on_packet_map.size(); |
|||
} |
|||
|
|||
bool ZCanCommnaderMaster::isListenerReg(uint16_t index) { |
|||
zlock_guard l(m_on_packet_map_lock); |
|||
auto it = m_on_packet_map.find(index); |
|||
if (it != m_on_packet_map.end()) { |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
void ZCanCommnaderMaster::callListener(CanPacketRxBuffer *report) { |
|||
uint16_t index = report->get_cmdheader()->packetindex; |
|||
|
|||
if (m_rawpacketcb) { |
|||
m_rawpacketcb(report->get_rx_raw(), report->get_rx_raw_len()); |
|||
} |
|||
|
|||
if (report->get_cmdheader()->packetType == kptv2_ack || report->get_cmdheader()->packetType == kptv2_error_ack) { |
|||
zlock_guard l(m_on_packet_map_lock); |
|||
auto it = m_on_packet_map.find(index); |
|||
if (it != m_on_packet_map.end()) { |
|||
if (it->second.on_ack) it->second.on_ack(report); |
|||
} |
|||
} |
|||
|
|||
if (report->get_cmdheader()->packetType == kptv2_event) { |
|||
if (m_on_event) m_on_event(report->id, report->get_cmdheader(), report->get_params_len()); |
|||
} |
|||
} |
|||
|
|||
uint16_t ZCanCommnaderMaster::generateFreeIndex() { |
|||
m_index_off++; |
|||
uint16_t count = 0; |
|||
if (m_index_off == 0) m_index_off = 1; |
|||
while (isListenerReg(m_index_off)) { |
|||
m_index_off++; |
|||
if (m_index_off == 0) m_index_off = 1; |
|||
count++; |
|||
if (count == 0) { |
|||
ZLOGE(TAG, "generateFreeIndex fail"); |
|||
NVIC_SystemReset(); |
|||
} |
|||
} |
|||
return m_index_off; |
|||
} |
|||
|
|||
void ZCanCommnaderMaster::sendPacket(uint8_t *packet, size_t len) { |
|||
zlock_guard txlock_guard(txlock); |
|||
/**
|
|||
* @brief |
|||
*/ |
|||
int npacket = len / 8 + (len % 8 == 0 ? 0 : 1); |
|||
if (npacket > 255) { |
|||
ZLOGE(TAG, "sendPacket fail, len:%d", len); |
|||
return; |
|||
} |
|||
int finalpacketlen = len % 8 == 0 ? 8 : len % 8; |
|||
|
|||
for (uint8_t i = 0; i < npacket; i++) { |
|||
bool suc = false; |
|||
if (i == npacket - 1) { |
|||
suc = sendPacketSub(npacket, i, packet + i * 8, finalpacketlen, OVER_TIME_MS); |
|||
} else { |
|||
suc = sendPacketSub(npacket, i, packet + i * 8, 8, OVER_TIME_MS); |
|||
} |
|||
if (!suc) { |
|||
// ZLOGE(TAG, "sendPacket fail, packet(%d:%d)", npacket, i);
|
|||
return; |
|||
} |
|||
} |
|||
} |
|||
|
|||
bool ZCanCommnaderMaster::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) { |
|||
// ZLOGI(TAG, "sendPacketSub(%d:%d)", npacket, packetIndex);
|
|||
CAN_TxHeaderTypeDef pHeader; |
|||
uint8_t aData[8] /*8byte table*/; |
|||
uint32_t txMailBox = 0; |
|||
|
|||
uint32_t enterticket = zos_get_tick(); |
|||
|
|||
memset(&pHeader, 0, sizeof(pHeader)); |
|||
memset(aData, 0, sizeof(aData)); |
|||
pHeader.StdId = 0x00; |
|||
pHeader.ExtId = (m_config->deviceId << 16) | (npacket << 8) | packetIndex; |
|||
pHeader.IDE = CAN_ID_EXT; |
|||
pHeader.RTR = CAN_RTR_DATA; |
|||
pHeader.DLC = len; |
|||
pHeader.TransmitGlobalTime = DISABLE; |
|||
|
|||
memcpy(aData, packet, len); |
|||
|
|||
m_lastTransmitStatus = HAL_CAN_AddTxMessage(m_config->canHandle, &pHeader, aData, &txMailBox); |
|||
if (m_lastTransmitStatus != HAL_OK) { |
|||
ZLOGE(TAG, "HAL_CAN_AddTxMessage fail"); |
|||
return false; |
|||
} |
|||
|
|||
while (HAL_CAN_IsTxMessagePending(m_config->canHandle, txMailBox)) { |
|||
if (zos_haspassedms(enterticket) > (uint32_t)overtimems) { |
|||
m_lastTransmitStatus = HAL_TIMEOUT; |
|||
HAL_CAN_AbortTxRequest(m_config->canHandle, txMailBox); |
|||
return false; |
|||
} |
|||
// m_os->sleepMS(1);
|
|||
} |
|||
if (txPacketInterval_ms > 0) { |
|||
osDelay(txPacketInterval_ms); |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
bool ZCanCommnaderMaster::getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/) { |
|||
/**
|
|||
* @brief 读取当前FIFO中缓存了多少帧的数据 |
|||
*/ |
|||
uint32_t level = HAL_CAN_GetRxFifoFillLevel(m_config->canHandle, m_config->rxfifoNum); |
|||
if (level == 0) { |
|||
return false; |
|||
} |
|||
HAL_StatusTypeDef HAL_RetVal; |
|||
HAL_RetVal = HAL_CAN_GetRxMessage(m_config->canHandle, m_config->rxfifoNum, pHeader, aData); |
|||
if (HAL_OK == HAL_RetVal) { |
|||
// 处理接收到的can总线数据
|
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
void ZCanCommnaderMaster::initCanPacketRxBuffer(CanPacketRxBuffer *buf, uint16_t id) { |
|||
if (buf == nullptr) return; |
|||
buf->clear(); |
|||
buf->id = id; |
|||
} |
|||
|
|||
CanPacketRxBuffer *ZCanCommnaderMaster::allocCanPacketRxBufferInIRQ(uint16_t id) { |
|||
for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) { |
|||
CanPacketRxBuffer *packetbuf = &m_canPacketRxBuffer[i]; |
|||
if (packetbuf->dataIsReady) { |
|||
// 等待等待处理完成后释放
|
|||
if (packetbuf->dataIsProcessed) packetbuf->isUsed = false; |
|||
} else { |
|||
// 数据已经开始接收,但超时未处理,回收buffer
|
|||
if (packetbuf->isUsed && zos_haspassedms(packetbuf->lastrxtime) > 100) { |
|||
packetbuf->isUsed = false; |
|||
} |
|||
// 数据开始接收了,但又收到了0号包,回收buffer
|
|||
if (packetbuf->isUsed && id == packetbuf->id) { |
|||
packetbuf->isUsed = false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) { |
|||
if (!m_canPacketRxBuffer[i].isUsed) { |
|||
initCanPacketRxBuffer(&m_canPacketRxBuffer[i], id); |
|||
m_canPacketRxBuffer[i].isUsed = true; |
|||
return &m_canPacketRxBuffer[i]; |
|||
} |
|||
} |
|||
return nullptr; |
|||
} |
|||
CanPacketRxBuffer *ZCanCommnaderMaster::findCanPacketRxBufferInIRQ(uint16_t id) { |
|||
for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) { |
|||
if (!m_canPacketRxBuffer[i].dataIsReady && m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].id == id) { |
|||
return &m_canPacketRxBuffer[i]; |
|||
} |
|||
} |
|||
return nullptr; |
|||
} |
|||
|
|||
void ZCanCommnaderMaster::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandle) { |
|||
/**
|
|||
* @brief 中断上下文 |
|||
*/ |
|||
// ZLOG_INFO("%s\n", __FUNCTION__);
|
|||
// printf("------------------%s\n", __FUNCTION__);
|
|||
if (canHandle != m_config->canHandle) { |
|||
return; |
|||
} |
|||
/**
|
|||
* @brief 处理can接收到消息 |
|||
*/ |
|||
CAN_RxHeaderTypeDef pHeader; |
|||
uint8_t aData[8] /*8byte table*/; |
|||
while (getRxMessage(&pHeader, aData)) { |
|||
/**
|
|||
* @brief 消息格式 |
|||
* |
|||
* [2] [3bit] [8bit] [8bit] [8bit] |
|||
* , from frameNum frameId |
|||
*/ |
|||
uint8_t from = (pHeader.ExtId >> 16 & 0xFF); |
|||
uint8_t nframe = (pHeader.ExtId & 0xFF00) >> 8; |
|||
uint8_t frameId = (pHeader.ExtId & 0x00FF); |
|||
CanPacketRxBuffer *rxbuf = nullptr; |
|||
if (frameId == 0) { |
|||
rxbuf = allocCanPacketRxBufferInIRQ(from); |
|||
rxbuf->m_npacket = nframe; |
|||
} else { |
|||
rxbuf = findCanPacketRxBufferInIRQ(from); |
|||
} |
|||
if (!rxbuf) { |
|||
ZLOGE(TAG, "board[%d] packetId[%d] find rx buff fail", from, frameId); |
|||
return; |
|||
} |
|||
|
|||
rxbuf->lastrxtime = zos_get_tick(); |
|||
|
|||
if (rxbuf->m_canPacketNum < ZARRAY_SIZE(rxbuf->m_canPacket)) { |
|||
rxbuf->m_canPacket[rxbuf->m_canPacketNum].dlc = pHeader.DLC; |
|||
memcpy(rxbuf->m_canPacket[rxbuf->m_canPacketNum].aData, aData, 8); |
|||
rxbuf->m_canPacketNum++; |
|||
} |
|||
/**
|
|||
* @brief 接收满了 |
|||
*/ |
|||
if (nframe == frameId + 1) { |
|||
rxbuf->dataIsReady = true; |
|||
rxbuf->dataIsProcessed = false; |
|||
if ((rxbuf->m_canPacketNum) != rxbuf->m_npacket) rxbuf->lostpacket = true; |
|||
} |
|||
} |
|||
|
|||
// deactivateRxIT();
|
|||
} |
|||
void ZCanCommnaderMaster::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) { |
|||
if (canHandle != m_config->canHandle) { |
|||
return; |
|||
} |
|||
ZLOGE(TAG, "onCAN_Error\r\n"); |
|||
} |
|||
void ZCanCommnaderMaster::processReadyPacket(CanPacketRxBuffer *rxbuf) { |
|||
int dataoff = 0; |
|||
for (size_t i = 0; i < rxbuf->m_canPacketNum; i++) { |
|||
memcpy(rxbuf->rxdata + dataoff, rxbuf->m_canPacket[i].aData, rxbuf->m_canPacket[i].dlc); |
|||
dataoff += rxbuf->m_canPacket[i].dlc; |
|||
rxbuf->rxdataSize = dataoff; |
|||
} |
|||
if (rxbuf->lostpacket) { |
|||
ZLOGE(TAG, "lostpacket %d %d", rxbuf->m_canPacketNum, rxbuf->m_npacket); |
|||
} else { |
|||
callListener(rxbuf); |
|||
} |
|||
} |
|||
void ZCanCommnaderMaster::loop() { |
|||
/**
|
|||
* @brief MainLoop上下文 |
|||
*/ |
|||
for (size_t i = 0; i < CAN_PACKET_RX_BUFFER_NUM; i++) { |
|||
if (m_canPacketRxBuffer[i].isUsed && m_canPacketRxBuffer[i].dataIsReady && !m_canPacketRxBuffer[i].dataIsProcessed) { |
|||
processReadyPacket(&m_canPacketRxBuffer[i]); |
|||
m_canPacketRxBuffer[i].dataIsProcessed = true; |
|||
} |
|||
} |
|||
} |
|||
HAL_StatusTypeDef ZCanCommnaderMaster::activateRxIT() { |
|||
HAL_StatusTypeDef hal_status = HAL_ERROR; |
|||
if (m_config->rxfifoNum == CAN_RX_FIFO0) { |
|||
hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING); |
|||
} else if (m_config->rxfifoNum == CAN_RX_FIFO1) { |
|||
hal_status = HAL_CAN_ActivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING); |
|||
} else { |
|||
ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n"); |
|||
return hal_status; |
|||
} |
|||
return hal_status; |
|||
} |
|||
HAL_StatusTypeDef ZCanCommnaderMaster::deactivateRxIT() { |
|||
HAL_StatusTypeDef hal_status = HAL_ERROR; |
|||
if (m_config->rxfifoNum == CAN_RX_FIFO0) { |
|||
hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO0_MSG_PENDING); |
|||
} else if (m_config->rxfifoNum == CAN_RX_FIFO1) { |
|||
hal_status = HAL_CAN_DeactivateNotification(m_config->canHandle, CAN_IT_RX_FIFO1_MSG_PENDING); |
|||
} else { |
|||
ZLOGE(TAG, "start can HAL_CAN_ActivateNotification CAN_IT_RX_FIFO0_MSG_PENDING fail\r\n"); |
|||
return hal_status; |
|||
} |
|||
return hal_status; |
|||
} |
|||
|
|||
size_t ZCanCommnaderMaster::safe_memcpy(void *dst, size_t dst_max_size, void *src, size_t src_len) { //
|
|||
size_t cpysize = dst_max_size < src_len ? dst_max_size : src_len; |
|||
memcpy(dst, src, cpysize); |
|||
return cpysize; |
|||
} |
|||
|
|||
#endif
|
@ -1,113 +0,0 @@ |
|||
//
|
|||
// Created by zwsd
|
|||
//
|
|||
|
|||
#pragma once
|
|||
#include <map>
|
|||
|
|||
#include "basic.hpp"
|
|||
#include "sdk/os/zos.hpp"
|
|||
// #include "sdk\components\zprotocols\zcancmder\zcancmder_protocol.hpp"
|
|||
#ifdef HAL_CAN_MODULE_ENABLED
|
|||
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
typedef function<void(CanPacketRxBuffer *report)> zcan_commnader_master_onpacket_t; |
|||
|
|||
class ZCanCommnaderMasterListener { |
|||
public: |
|||
zcan_commnader_master_onpacket_t on_ack; |
|||
}; |
|||
|
|||
typedef function<void(uint8_t *packet, size_t len)> rawpacket_t; |
|||
|
|||
class ZCanCommnaderMaster : public ZCanIRQListener, public IZcanCmderMaster { |
|||
public: |
|||
class CFG { |
|||
public: |
|||
uint8_t deviceId = 0; //
|
|||
/*******************************************************************************
|
|||
* CANConfig * |
|||
*******************************************************************************/ |
|||
CAN_HandleTypeDef *canHandle; // 默认使用CAN1
|
|||
int canFilterIndex0; // 过滤器0 接收,发给自身的消息
|
|||
int maxFilterNum; // 使用的过滤器数量,最大值14,默认为7
|
|||
int rxfifoNum; // 使用的FIFO,默认使用FIFO0
|
|||
int packetRxOvertime_ms; //
|
|||
}; |
|||
|
|||
uint8_t txbuff[2100]; |
|||
|
|||
public: |
|||
class LoopJobContext { |
|||
public: |
|||
bool hasDoneSomething; |
|||
}; |
|||
|
|||
private: |
|||
CFG *m_config = NULL; // 配置
|
|||
bool m_canOnRxDataFlag = false; // 是否有数据接收,用于从中断上下文转移到MainLoop上下文
|
|||
uint32_t m_lastPacketTicket = 0; // 上一次接收到消息的时间,用于判断与主机是否断开连接
|
|||
HAL_StatusTypeDef m_lastTransmitStatus; // 上次调用can发送方法的返回值
|
|||
|
|||
#define CAN_PACKET_RX_BUFFER_NUM 5
|
|||
CanPacketRxBuffer m_canPacketRxBuffer[CAN_PACKET_RX_BUFFER_NUM]; |
|||
|
|||
int txPacketInterval_ms = 0; |
|||
|
|||
ZThread m_loopThread; |
|||
|
|||
map<uint16_t, ZCanCommnaderMasterListener> m_on_packet_map; |
|||
zmutex m_on_packet_map_lock; |
|||
uint16_t m_index_off = 0; |
|||
onpacket_t m_on_event; |
|||
|
|||
rawpacket_t m_rawpacketcb = nullptr; |
|||
|
|||
zmutex txlock; |
|||
|
|||
public: |
|||
ZCanCommnaderMaster() {} |
|||
CFG *createCFG(); |
|||
void init(CFG *cfg); |
|||
|
|||
void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; } |
|||
virtual int32_t sendCmd(int32_t cmdid, int32_t moduleid, int32_t *param, size_t npara, int32_t *ack, size_t nack, int overtime_ms) override; |
|||
virtual int32_t sendCmdAndReceiveBuf(int32_t cmdid, int32_t moduleid, int32_t *param, size_t npara, uint8_t *ack, int32_t *rxsize, int overtime_ms) override; |
|||
virtual void regEventPacketListener(onpacket_t on_event) override; |
|||
|
|||
void sendRawPacket(uint8_t *packet, size_t len); |
|||
void regRawPacketListener(rawpacket_t rawpacketcb); |
|||
|
|||
public: |
|||
virtual void STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *can); |
|||
virtual void STM32_HAL_onCAN_Error(CAN_HandleTypeDef *can); |
|||
|
|||
private: |
|||
void loop(); |
|||
|
|||
uint8_t getDeviceId() { return m_config->deviceId; } |
|||
void sendPacket(uint8_t *packet, size_t len); |
|||
void regListener(uint16_t index, zcan_commnader_master_onpacket_t onack); |
|||
void unregListener(uint16_t index); |
|||
void callListener(CanPacketRxBuffer *report); |
|||
bool isListenerReg(uint16_t index); |
|||
int getListenerNum(); |
|||
uint16_t generateFreeIndex(); |
|||
bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems); |
|||
|
|||
HAL_StatusTypeDef initializeFilter(); |
|||
HAL_StatusTypeDef activateRxIT(); |
|||
HAL_StatusTypeDef deactivateRxIT(); |
|||
bool getRxMessage(CAN_RxHeaderTypeDef *pHeader, uint8_t aData[] /*8byte table*/); |
|||
|
|||
size_t safe_memcpy(void *dst, size_t dst_max_size, void *src, size_t src_len); |
|||
|
|||
void initCanPacketRxBuffer(CanPacketRxBuffer *buf, uint16_t id); |
|||
CanPacketRxBuffer *allocCanPacketRxBufferInIRQ(uint16_t id); |
|||
CanPacketRxBuffer *findCanPacketRxBufferInIRQ(uint16_t id); |
|||
void processReadyPacket(CanPacketRxBuffer *buf); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
|||
#endif
|
@ -1,219 +0,0 @@ |
|||
#include "micro_computer_module_device_script_cmder_paser.hpp"
|
|||
|
|||
#include <stdio.h>
|
|||
#include <stdlib.h>
|
|||
#include <string.h>
|
|||
|
|||
#include "sdk/os/zos.hpp"
|
|||
using namespace iflytop; |
|||
using namespace std; |
|||
|
|||
#define TAG "CMD"
|
|||
|
|||
static const char* dumpbit(int32_t bit) { |
|||
static char buf[100]; |
|||
sprintf(buf, "%d%d%d%d(0:3) %d%d%d%d(4:7) %d%d%d%d(8:11) %d%d%d%d(12:15)", //
|
|||
(bit >> 0) & 0x1, (bit >> 1) & 0x1, (bit >> 2) & 0x1, (bit >> 3) & 0x1, //
|
|||
(bit >> 4) & 0x1, (bit >> 5) & 0x1, (bit >> 6) & 0x1, (bit >> 7) & 0x1, //
|
|||
(bit >> 8) & 0x1, (bit >> 9) & 0x1, (bit >> 10) & 0x1, (bit >> 11) & 0x1, //
|
|||
(bit >> 12) & 0x1, (bit >> 13) & 0x1, (bit >> 14) & 0x1, (bit >> 15) & 0x1); |
|||
return buf; |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::initialize(ICmdParser* cancmder, ZModuleDeviceManager* deviceManager) { |
|||
ZModuleDeviceScriptCmderPaser::initialize(cancmder, deviceManager); |
|||
m_cmdParser = cancmder; |
|||
m_deviceManager = deviceManager; |
|||
|
|||
/*******************************************************************************
|
|||
* 兼容接口 * |
|||
*******************************************************************************/ |
|||
cancmder->regCMD("dumpreg", "(mid)", 1, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
app_dump_reg(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("scanmodule", "()", 0, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
do_scan_module(paramN, paraV, ack); |
|||
}); |
|||
|
|||
cancmder->regCMD("reboot", "()", 0, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
NVIC_SystemReset(); |
|||
}); |
|||
/*******************************************************************************
|
|||
* 接口 * |
|||
*******************************************************************************/ |
|||
cancmder->regCMD("app_dump_regs", "(mid)", 1, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
app_dump_reg(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_dump_reg", "(mid,regindex)", 2, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
app_dump_reg(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_scanmodule", "()", 0, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
do_scan_module(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_wait_for_module", "(mid,timeout)", -1, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
do_wait_for_module(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_scanmodule", "()", 0, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
do_scan_module(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_module_read_raw_str", "(mid,size)", 2, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
app_module_read_raw_str(paramN, paraV, ack); |
|||
}); |
|||
cancmder->regCMD("app_set_reg", "(regindex,mid,val)", 3, [this](int32_t paramN, const char* paraV[], ICmdParserACK* ack) { //
|
|||
app_set_reg(paramN, paraV, ack); |
|||
}); |
|||
deviceManager->regOnRegValChangeEvent([this](int32_t moduleid, int32_t regindex, int32_t oldval, int32_t toval) { //
|
|||
ZLOGI(TAG, "onRegValChangeEvent(moduleId[%d], reg[%d], %d->%d)", moduleid, regindex, oldval, toval); |
|||
}); |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_dump_regs(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
ack->ecode = 0; |
|||
uint16_t moduleId = atoi(paraV[0]); |
|||
ZLOGI(TAG, "app_dump_regs %s", paraV[0]); |
|||
app_dump_reg(moduleId, 0); |
|||
} |
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_dump_reg(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
ack->ecode = 0; |
|||
uint16_t moduleId = atoi(paraV[0]); |
|||
uint16_t regid = atoi(paraV[1]); |
|||
ZLOGI(TAG, "app_dump_regs %s", paraV[0], paraV[1]); |
|||
app_dump_reg(moduleId, regid); |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_set_reg(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
ack->ecode = 0; |
|||
uint16_t regid = iflytop::str_to_reg_index(paraV[0]); |
|||
uint16_t moduleId = atoi(paraV[1]); |
|||
uint16_t regval = atoi(paraV[2]); |
|||
ZLOGI(TAG, "module_set_reg %d %d %d", moduleId, regid, regval); |
|||
ack->ecode = m_deviceManager->module_set_reg(moduleId, regid, regval); |
|||
m_deviceManager->module_active_cfg(moduleId); |
|||
return; |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_module_read_raw_str(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
ack->ecode = 0; |
|||
uint16_t moduleId = atoi(paraV[0]); |
|||
uint16_t startadd = atoi(paraV[1]); |
|||
ack->rawlen = sizeof(ack->rawdata); |
|||
ack->ecode = m_deviceManager->module_read_raw(moduleId, startadd, ack->rawdata, &ack->rawlen); |
|||
ack->acktype = ICmdParserACK::kAckType_str; |
|||
return; |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_dump_reg(int moduleId, const char* configtag, int configid, dump_type_t type) { |
|||
int32_t configval = 0; |
|||
int32_t ecode = 0; |
|||
ecode = m_deviceManager->module_get_reg(moduleId, configid, &configval); |
|||
if (ecode == 0) { |
|||
if (type == kint) { |
|||
ZLOGI(TAG, "%s(%d) :%d", configtag, configid, configval); |
|||
} else if (type == kbit) { |
|||
ZLOGI(TAG, "%s(%d) :%s", configtag, configid, dumpbit(configval)); |
|||
} |
|||
} else if (ecode != err::kmodule_not_find_config_index) { |
|||
ZLOGI(TAG, "%s(%d) :read_error %s(%d)", configtag, configid, err::error2str(ecode), ecode); |
|||
} |
|||
} |
|||
/**
|
|||
* @brief |
|||
* |
|||
* @param moduleId |
|||
* @param regid 如果regid==0,则打印所有寄存器 |
|||
*/ |
|||
void MicroComputerModuleDeviceScriptCmderPaser::app_dump_reg(int32_t moduleId, int32_t regid) { |
|||
int32_t configval = 0; |
|||
int32_t ecode = 0; |
|||
|
|||
ZLOGI(TAG, "-------------------------REG LIST--------------------------") |
|||
|
|||
// reg_index_table_get
|
|||
|
|||
reg_index_table_iterm_t* iterms = nullptr; |
|||
int32_t num = 0; |
|||
|
|||
reg_index_table_get(&iterms, &num); |
|||
for (int32_t i = 0; i < num; i++) { |
|||
reg_index_table_iterm_t* iterm = &iterms[i]; |
|||
|
|||
if (regid != 0 && regid != iterm->index) { |
|||
continue; |
|||
} |
|||
|
|||
if (iterm->index == kreg_module_errorbitflag0 || //
|
|||
iterm->index == kreg_module_errorbitflag1 || //
|
|||
iterm->index == kreg_module_input_state || //
|
|||
iterm->index == kreg_module_output_state) { |
|||
app_dump_reg(moduleId, iterm->name, iterm->index, kbit); |
|||
} else { |
|||
app_dump_reg(moduleId, iterm->name, iterm->index, kint); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::do_wait_for_module(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
if (paramN < 1) { |
|||
ack->ecode = err::kcmd_param_num_error; |
|||
return; |
|||
} |
|||
if (paramN > 2) { |
|||
ack->ecode = err::kcmd_param_num_error; |
|||
return; |
|||
} |
|||
|
|||
int32_t moduleId = atoi(paraV[0]); |
|||
int32_t timeout = 0; |
|||
if (paramN == 2) { |
|||
timeout = atoi(paraV[1]); |
|||
} |
|||
return do_wait_for_module(moduleId, timeout, ack); |
|||
} |
|||
void MicroComputerModuleDeviceScriptCmderPaser::do_wait_for_module(int32_t moduleid, int32_t timeout, ICmdParserACK* ack) { |
|||
ThisThread thisThread; |
|||
int32_t remaining = timeout; |
|||
int32_t i = 0; |
|||
while (!thisThread.getExitFlag()) { |
|||
int32_t status = 0; |
|||
int32_t ecode = m_deviceManager->module_get_status(moduleid, &status); |
|||
if (ecode == 0 && status == 0) { |
|||
ZLOGI(TAG, "wait for module %d ok", moduleid); |
|||
ack->ecode = 0; |
|||
return; |
|||
} |
|||
|
|||
/**
|
|||
* @brief 超时退出 |
|||
*/ |
|||
if (timeout > 0) { |
|||
remaining -= 30; |
|||
if (remaining <= 0) { |
|||
ack->ecode = err::kovertime; |
|||
return; |
|||
} |
|||
} |
|||
/**
|
|||
* @brief |
|||
*/ |
|||
i++; |
|||
if (i % 10 == 0) { |
|||
if (ack->ecode == 0) { |
|||
ZLOGI(TAG, "wait for module %d %d", moduleid, status); |
|||
} else { |
|||
ZLOGI(TAG, "wait for module %d err: %s(%d)", moduleid, err::error2str(ack->ecode), ack->ecode); |
|||
} |
|||
} |
|||
thisThread.sleep(100); |
|||
} |
|||
} |
|||
|
|||
void MicroComputerModuleDeviceScriptCmderPaser::do_scan_module(int32_t paramN, const char* paraV[], ICmdParserACK* ack) { |
|||
m_deviceManager->for_each_module([this](int32_t id) { //
|
|||
// ZLOGI(TAG, "ping %d", id);
|
|||
int32_t ecode = m_deviceManager->module_ping(id); |
|||
if (ecode == 0) { |
|||
ZLOGI(TAG, "module %d : %s", id, ecode == 0 ? "online" : "offline"); |
|||
} |
|||
}); |
|||
ZLOGI(TAG, "scan module end..."); |
|||
} |
@ -1,33 +0,0 @@ |
|||
#pragma once
|
|||
#include "sdk\components\zprotocols\zcancmder_v2\zmodule_device_script_cmder_paser.hpp"
|
|||
namespace iflytop { |
|||
using namespace std; |
|||
|
|||
class MicroComputerModuleDeviceScriptCmderPaser : public ZModuleDeviceScriptCmderPaser { |
|||
ICmdParser* m_cmdParser = nullptr; |
|||
ZModuleDeviceManager* m_deviceManager; |
|||
|
|||
typedef enum { |
|||
kint, |
|||
kbit, |
|||
} dump_type_t; |
|||
|
|||
public: |
|||
void initialize(ICmdParser* cancmder, ZModuleDeviceManager* deviceManager); |
|||
|
|||
void app_dump_reg(int32_t moduleId, int32_t regid); |
|||
void do_wait_for_module(int32_t moduleid, int32_t timeout, ICmdParserACK* ack); |
|||
|
|||
private: |
|||
void do_scan_module(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
void do_wait_for_module(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
void app_dump_regs(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
void app_dump_reg(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
void app_module_read_raw_str(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
|
|||
void app_set_reg(int32_t paramN, const char* paraV[], ICmdParserACK* ack); |
|||
|
|||
void app_dump_reg(int moduleId, const char* configtag, int configid, dump_type_t type); |
|||
}; |
|||
|
|||
} // namespace iflytop
|
@ -1 +1 @@ |
|||
Subproject commit a7f08c437c511fee6176ebd704ae24464d23917f |
|||
Subproject commit 1de9d701ea909dd967426b1e728b896351c47d2a |
Write
Preview
Loading…
Cancel
Save
Reference in new issue