Browse Source

删除部分不必要代码

master
zhaohe 1 year ago
parent
commit
6907918344
  1. 199
      components/cmdscheduler/cmd_scheduler_uart_dma.cpp
  2. 51
      components/cmdscheduler/cmd_scheduler_uart_dma.hpp
  3. 209
      components/cmdscheduler/cmd_scheduler_v2.cpp
  4. 114
      components/cmdscheduler/cmd_scheduler_v2.hpp
  5. 5
      components/modbus/modbus_client.hpp
  6. 7
      components/subcanmodule/dep.hpp
  7. 99
      components/subcanmodule/zcancmder_subboard_initer.cpp
  8. 47
      components/subcanmodule/zcancmder_subboard_initer.hpp
  9. 6
      components/zcancmder/zcanreceiver.cpp
  10. 8
      components/zcancmder/zcanreceiver.hpp
  11. 541
      components/zcancmder/zcanreceiver_master.cpp
  12. 113
      components/zcancmder/zcanreceiver_master.hpp
  13. 219
      components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.cpp
  14. 33
      components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.hpp
  15. 2
      components/zprotocols/zcancmder_v2

199
components/cmdscheduler/cmd_scheduler_uart_dma.cpp

@ -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

51
components/cmdscheduler/cmd_scheduler_uart_dma.hpp

@ -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

209
components/cmdscheduler/cmd_scheduler_v2.cpp

@ -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;
}
}
}

114
components/cmdscheduler/cmd_scheduler_v2.hpp

@ -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

5
components/modbus/modbus_client.hpp

@ -2,14 +2,9 @@
#include "modbus_processer.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\api\zi_uart_sender.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"
namespace iflytop {

7
components/subcanmodule/dep.hpp

@ -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"

99
components/subcanmodule/zcancmder_subboard_initer.cpp

@ -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

47
components/subcanmodule/zcancmder_subboard_initer.hpp

@ -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

6
components/zcancmder/zcanreceiver.cpp

@ -108,7 +108,7 @@ HAL_StatusTypeDef ZCanCmder::initializeFilter() {
return HAL_Status;
}
void ZCanCmder::registerListener(IZcanCmderListener *listener) { m_listenerList.push_back(listener); }
void ZCanCmder::registerListener(IZCanReceiverListener *listener) { m_listenerList.push_back(listener); }
void ZCanCmder::sendPacket(uint8_t *packet, size_t len) {
/**
* @brief
@ -148,10 +148,10 @@ void ZCanCmder::sendErrorAck(zcr_cmd_header_t *cmdheader, uint16_t id, uint32_t
zcr_cmd_header_t *txheader = (zcr_cmd_header_t *)txbuff;
memcpy(txheader, cmdheader, sizeof(zcr_cmd_header_t));
txheader->packetType = kptv2_error_ack;
zcan_cmder_error_ack_t *error_ack = (zcan_cmder_error_ack_t *)txheader->data;
zcanreceiver_error_ack_t *error_ack = (zcanreceiver_error_ack_t *)txheader->data;
error_ack->id = id;
error_ack->errorcode = errcode;
sendPacket(txbuff, sizeof(zcr_cmd_header_t) + sizeof(zcan_cmder_error_ack_t));
sendPacket(txbuff, sizeof(zcr_cmd_header_t) + sizeof(zcanreceiver_error_ack_t));
}
void ZCanCmder::sendExecStatusReport(zcr_cmd_header_t *rxcmdheader, uint8_t *data, size_t len) {

8
components/zcancmder/zcanreceiver.hpp

@ -17,9 +17,9 @@ class ZCanCmderListener {
};
#endif
typedef function<void(CanPacketRxBuffer *rxcmd)> zcan_cmder_listener_t;
typedef function<void(CanPacketRxBuffer *rxcmd)> zcanreceiver_listener_t;
class ZCanCmder : public ZCanIRQListener, public IZCanCmder {
class ZCanCmder : public ZCanIRQListener, public IZCanReceiver {
public:
class CFG {
public:
@ -48,7 +48,7 @@ class ZCanCmder : public ZCanIRQListener, public IZCanCmder {
uint32_t m_lastPacketTicket = 0; // 上一次接收到消息的时间,用于判断与主机是否断开连接
HAL_StatusTypeDef m_lastTransmitStatus; // 上次调用can发送方法的返回值
list<IZcanCmderListener *> m_listenerList;
list<IZCanReceiverListener *> m_listenerList;
CanPacketRxBuffer m_canPacketRxBuffer[1];
int txPacketInterval_ms = 0;
@ -71,7 +71,7 @@ class ZCanCmder : public ZCanIRQListener, public IZCanCmder {
uint8_t getDeviceId() { return m_config->deviceId; }
void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; }
virtual void registerListener(IZcanCmderListener *listener) override;
virtual void registerListener(IZCanReceiverListener *listener) override;
virtual int32_t sendBufAck(zcr_cmd_header_t *rx_cmd_header, uint8_t *data, int32_t len) override;
virtual int32_t sendAck(zcr_cmd_header_t *rx_cmd_header, int32_t *ackvar, int32_t nack) override;
virtual int32_t sendErrorAck(zcr_cmd_header_t *rx_cmd_header, int32_t errorcode) override;

541
components/zcancmder/zcanreceiver_master.cpp

@ -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

113
components/zcancmder/zcanreceiver_master.hpp

@ -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

219
components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.cpp

@ -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...");
}

33
components/zprotocol_helper/micro_computer_module_device_script_cmder_paser.hpp

@ -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

2
components/zprotocols/zcancmder_v2

@ -1 +1 @@
Subproject commit a7f08c437c511fee6176ebd704ae24464d23917f
Subproject commit 1de9d701ea909dd967426b1e728b896351c47d2a
Loading…
Cancel
Save