Browse Source

1021 | 修复zcan接收代码 丢包问题

master
zhaohe 4 months ago
parent
commit
f4906a3f64
  1. 8
      sdk/components/modbus/modbus_client.hpp
  2. 0
      sdk/components/zcan_board_module/zcan_board_module.cpp
  3. 6
      sdk/components/zcan_board_module/zcan_board_module.hpp
  4. 24
      sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp
  5. 12
      sdk/components/zcan_protocol_parser/zcan_protocol_parser.hpp
  6. 0
      sdk/components/zcancmder/basic.cpp
  7. 7
      sdk/components/zcancmder/basic.hpp
  8. 1
      sdk/components/zcancmder/protocol_event_bus_sender.hpp
  9. 24
      sdk/components/zcancmder/type/zcan_rx_frame.hpp
  10. 40
      sdk/components/zcancmder/type/zcan_rx_frame_pool.hpp
  11. 31
      sdk/components/zcancmder/type/zcan_rx_frame_queue.hpp
  12. 90
      sdk/components/zcancmder/zcanreceiver.cpp
  13. 41
      sdk/components/zcancmder/zcanreceiver.hpp
  14. 2
      usrc/public_service/gservice.hpp
  15. 2
      usrc/version.h

8
sdk/components/modbus/modbus_client.hpp

@ -1,10 +1,10 @@
#pragma once
#include "modbus_processer.hpp"
#include "sdk/components/api/zi_uart_sender.hpp"
#include "sdk/components/hardware/uart/zuart_dma_receiver.hpp"
#include "sdk/components/zcan_board_module/zcan_board_module.hpp"
#include "sdk/components/zcancmder/zcanreceiver.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\api\zi_uart_sender.hpp"
#include "sdk\components\hardware\uart\zuart_dma_receiver.hpp"
#include "sdk\components\zcancmder\zcan_board_module.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
namespace iflytop {

0
sdk/components/zcancmder/zcan_board_module.cpp → sdk/components/zcan_board_module/zcan_board_module.cpp

6
sdk/components/zcancmder/zcan_board_module.hpp → sdk/components/zcan_board_module/zcan_board_module.hpp

@ -5,11 +5,11 @@
#pragma once
#include "sdk/os/zos.hpp"
//
#include "a8000_protocol\protocol.hpp"
#include "a8000_protocol/protocol.hpp"
#include "sdk/chip/api/zi_adc.hpp"
#include "sdk/chip/api/zi_api.hpp"
#include "sdk/chip/api/zi_temperature.hpp"
#include "sdk\chip\api\zi_adc.hpp"
#include "sdk\components\api\zi_module.hpp"
#include "sdk/components/api/zi_module.hpp"
/**
* @brief

24
sdk/components/zcancmder/zcan_protocol_parser.cpp → sdk/components/zcan_protocol_parser/zcan_protocol_parser.cpp

@ -178,19 +178,23 @@ void ZCanProtocolParser::registerModule(ZIModule* module) {
_registerModule(id, module);
}
void ZCanProtocolParser::onRceivePacket(zcr_cmd_header_t* rxcmd, int32_t len) {
// printf("onRceivePacket cmdid:%d moduleid:%d\n", rxcmd->cmdid, rxcmd->moduleId);
void ZCanProtocolParser::processRxPacket(ZcanRxframe* rxframe) {
// printf("processRxPacket cmdid:%d moduleid:%d\n", rxcmd->cmdid, rxcmd->moduleId);
if (rxframe->cxt) _processRxPacket((ZIModule*)rxframe->cxt, (zcr_cmd_header_t*)rxframe->rxdata, rxframe->rxdataLen);
}
bool ZCanProtocolParser::filterPacket(ZcanRxframe* rxframe) {
zcr_cmd_header_t* rxcmd = (zcr_cmd_header_t*)rxframe->rxdata;
int32_t len = rxframe->rxdataLen;
uint16_t moduleid = rxcmd->moduleId;
auto it = m_modulers.find(moduleid);
if (it == m_modulers.end()) {
return;
rxframe->cxt = nullptr;
return false;
}
// ZLOGI(TAG, "rx(index:%d) cmdid:%d moduleid:%d", rxcmd->index,rxcmd->cmdid, moduleid);
ZIModule* module = it->second;
int32_t cmdid = rxcmd->cmdid;
_onRceivePacket(module, rxcmd, len);
rxframe->cxt = it->second;
return true;
}
void ZCanProtocolParser::regCmdFn(int32_t cmdid, cmdcb_t cb) {
@ -228,7 +232,7 @@ static bool checkpacket(const zcr_cmd_header_t* header, int len) {
return true;
}
void ZCanProtocolParser::_onRceivePacket(ZIModule* module, zcr_cmd_header_t* rxcmd, int32_t len) {
void ZCanProtocolParser::_processRxPacket(ZIModule* module, zcr_cmd_header_t* rxcmd, int32_t len) {
int paramNum = (len) / sizeof(int32_t);
int32_t* ack = (int32_t*)&ackbuf[0];

12
sdk/components/zcancmder/zcan_protocol_parser.hpp → sdk/components/zcan_protocol_parser/zcan_protocol_parser.hpp

@ -2,14 +2,14 @@
#include <map>
#include "a8000_protocol\protocol.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#include "sdk\components\api\zi_module.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#define CMDFN(name) static int32_t name(cmdcontxt_t* cxt)
#define CMDFN_IMPL(name) int32_t ZCanProtocolParser::name(cmdcontxt_t* cxt)
namespace iflytop {
class ZCanProtocolParser : public IZCanReceiverListener {
class ZCanProtocolParser : public IZCanRxProcesser {
public:
typedef struct {
ZIModule* module;
@ -30,7 +30,7 @@ class ZCanProtocolParser : public IZCanReceiverListener {
} cmdfn_t;
private:
ZCanReceiver* m_cancmder = nullptr;
ZCanReceiver* m_cancmder = nullptr;
map<uint16_t, ZIModule*> m_modulers;
uint8_t ackbuf[ZCANCMD_PACKET_MAX_LEN + 10];
@ -41,13 +41,14 @@ class ZCanProtocolParser : public IZCanReceiverListener {
public:
void initialize(ZCanReceiver* cancmder);
virtual void onRceivePacket(zcr_cmd_header_t* rxcmd, int32_t len);
virtual bool filterPacket(ZcanRxframe* rxframe);
virtual void processRxPacket(ZcanRxframe* rxframe);
void registerModule(ZIModule* module);
ZIModule* getModule(int id) { return m_modulers[id]; }
private:
void _registerModule(uint16_t id, ZIModule* module);
void _onRceivePacket(ZIModule* module, zcr_cmd_header_t* rxcmd, int32_t len);
void _processRxPacket(ZIModule* module, zcr_cmd_header_t* rxcmd, int32_t len);
void regCmdFn(int32_t cmdid, cmdcb_t cb);
cmdfn_t* findcmdfn(int32_t cmdid);
@ -62,7 +63,6 @@ class ZCanProtocolParser : public IZCanReceiverListener {
CMDFN(module_active_cfg);
CMDFN(module_reset_reg);
CMDFN(step_motor_enable);
CMDFN(step_motor_stop);
CMDFN(step_motor_read_pos);

0
sdk/components/zcancmder/basic.cpp

7
sdk/components/zcancmder/basic.hpp

@ -1,7 +0,0 @@
//
// Created by zwsd
//
#pragma once
#include "a8000_protocol\protocol.hpp"
#include "sdk/os/zos.hpp"

1
sdk/components/zcancmder/protocol_event_bus_sender.hpp

@ -1,7 +1,6 @@
#pragma once
#include "a8000_protocol\protocol.hpp"
#include "basic.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\zcancmder\zcanreceiver.hpp"
#include "sdk\components\api\zi_module.hpp"

24
sdk/components/zcancmder/type/zcan_rx_frame.hpp

@ -0,0 +1,24 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/os/zos.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZcanRxframe {
public:
uint8_t rxdata[128];
int rxdataLen = 0;
uint8_t canPacketNum = 0;
uint8_t npacket = 0;
void* cxt = nullptr;
bool isUsed = false;
};
} // namespace iflytop
#endif

40
sdk/components/zcancmder/type/zcan_rx_frame_pool.hpp

@ -0,0 +1,40 @@
//
// Created by zwsd
//
#pragma once
#include "zcan_rx_frame.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZcanRxframePool {
public:
ZcanRxframe buf[3];
void init() {}
ZcanRxframe* alloc() {
for (int i = 0; i < 3; i++) {
if (!buf[i].isUsed) {
buf[i].isUsed = true;
return &buf[i];
}
}
return NULL;
}
void free(ZcanRxframe** ppframe) {
ZcanRxframe* frame = *ppframe;
if (frame == NULL) return;
frame->isUsed = false;
frame->rxdataLen = 0;
frame->canPacketNum = 0;
frame->npacket = 0;
frame->cxt = NULL;
*ppframe = NULL;
}
};
} // namespace iflytop
#endif

31
sdk/components/zcancmder/type/zcan_rx_frame_queue.hpp

@ -0,0 +1,31 @@
//
// Created by zwsd
//
#pragma once
#include "sdk/os/zos.hpp"
#include "zcan_rx_frame.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
class ZcanRxframeQueue {
uint8_t queueStorage[4 * sizeof(void*)] = {0};
QueueHandle_t handler = nullptr;
StaticQueue_t xQueueBuffer;
public:
void init() { handler = xQueueCreateStatic(4, sizeof(void*), queueStorage, &xQueueBuffer); }
void sendIRQ(ZcanRxframe* frame) { xQueueSendFromISR(handler, &frame, NULL); }
ZcanRxframe* receive() {
ZcanRxframe* frame = NULL;
xQueueReceive(handler, &frame, 0);
return frame;
}
};
} // namespace iflytop
#endif

90
sdk/components/zcancmder/zcanreceiver.cpp

@ -9,7 +9,8 @@ using namespace zcr;
#define TAG "ZCanCmder"
#define OVER_TIME_MS 5
#define OVER_TIME_MS 5
#define MAIN_DEVICE_CAN_ID 0
static void assign_packet_checksum(uint8_t *packet, int len) {
uint8_t checksum = 0;
@ -38,16 +39,8 @@ void ZCanReceiver::initialize(CFG *cfg) {
m_config = cfg;
m_lock.init();
/**
* @brief CAN
*/
/**
* @brief buf
*/
m_rxFrameBuffer.dataIsReady = false;
m_rxFrameBuffer.id = 0; // 只接收来自主机的消息
m_rxFrameBuffer.canPacketNum = 0;
m_rxFramePool.init();
m_pendingMsgQueue.init();
/**
* @brief
@ -96,8 +89,7 @@ HAL_StatusTypeDef ZCanReceiver::initializeFilter() {
/*******************************************************************************
* *
*******************************************************************************/
filterId = (0); //
mask = (0); //
filterId = (MAIN_DEVICE_CAN_ID); //
mask = (0xffffffff); //
sFilterConfig.FilterBank = m_config->canFilterIndex0; //
sFilterConfig.FilterMaskIdLow = mask & 0xffff; //
@ -113,7 +105,7 @@ HAL_StatusTypeDef ZCanReceiver::initializeFilter() {
return HAL_Status;
}
void ZCanReceiver::registerListener(IZCanReceiverListener *listener) { m_listenerList.push_back(listener); }
void ZCanReceiver::registerListener(IZCanRxProcesser *listener) { rxprocesser = listener; }
// static inline const char *dumphex(uint8_t *packet, size_t len) {
// static char buf[1024];
@ -307,9 +299,6 @@ void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandl
if (pHeader.RTR != CAN_RTR_DATA || pHeader.IDE != CAN_ID_STD) continue;
if (pHeader.DLC == 0) continue;
// 上次接收到的消息还没有来的急处理
if (m_rxFrameBuffer.dataIsReady) continue;
/**
* @brief
*/
@ -319,29 +308,39 @@ void ZCanReceiver::STM32_HAL_onCAN_RxFifo0MsgPending(CAN_HandleTypeDef *canHandl
uint8_t frameoff = (aData[0] & 0x0F);
// 只接收来自主机的消息
if (from != m_rxFrameBuffer.id) continue;
if (from != MAIN_DEVICE_CAN_ID) continue;
// 当frameoff==0,重置接收缓存
if (frameoff == 0) {
m_rxFrameBuffer.canPacketNum = 0;
if (curRxBuf != nullptr) {
m_rxFramePool.free(&curRxBuf);
}
curRxBuf = m_rxFramePool.alloc();
}
if (!curRxBuf) return; // 分配内存失败
// 当接收到非期望frameoff的数据时,说明发生了丢包,重置接收缓存
if (m_rxFrameBuffer.canPacketNum != frameoff) {
m_rxFrameBuffer.canPacketNum = 0;
if (curRxBuf->canPacketNum != frameoff) {
m_rxFramePool.free(&curRxBuf);
continue;
}
// 接收到有效包
if (m_rxFrameBuffer.canPacketNum < ZARRAY_SIZE(m_rxFrameBuffer.canPacket)) {
m_rxFrameBuffer.canPacket[m_rxFrameBuffer.canPacketNum].dlc = pHeader.DLC;
memcpy(m_rxFrameBuffer.canPacket[m_rxFrameBuffer.canPacketNum].aData, aData, 8);
m_rxFrameBuffer.canPacketNum++;
if (curRxBuf->rxdataLen + pHeader.DLC - 1 < sizeof(curRxBuf->rxdata)) {
memcpy(&curRxBuf->rxdata[curRxBuf->rxdataLen], &aData[1], pHeader.DLC - 1);
curRxBuf->canPacketNum++;
curRxBuf->rxdataLen += pHeader.DLC - 1;
}
if (nframe == frameoff + 1) {
m_rxFrameBuffer.npacket = nframe;
m_rxFrameBuffer.dataIsReady = true;
curRxBuf->npacket = nframe;
bool pass = rxprocesser->filterPacket(curRxBuf);
if (pass) {
m_pendingMsgQueue.sendIRQ(curRxBuf);
} else {
m_rxFramePool.free(&curRxBuf);
}
}
}
@ -355,39 +354,10 @@ void ZCanReceiver::STM32_HAL_onCAN_Error(CAN_HandleTypeDef *canHandle) {
}
void ZCanReceiver::processRx() {
auto *rxbuf = &m_rxFrameBuffer;
if (!rxbuf->dataIsReady) return;
if (rxbuf->canPacketNum != rxbuf->npacket) {
ZLOGE(TAG, "lost packet");
rxbuf->canPacketNum = 0;
rxbuf->npacket = 0;
rxbuf->dataIsReady = false;
return;
}
//
// !处理接收到的数据!
//
// 拷贝接收到的数据到processbuf中
uint8_t *processbuf = m_rxPacketProcessBuf;
int32_t processlen = 0;
for (size_t i = 0; i < rxbuf->canPacketNum; i++) {
if (rxbuf->canPacket[i].dlc == 0) continue;
memcpy(processbuf + processlen, rxbuf->canPacket[i].aData + 1, rxbuf->canPacket[i].dlc - 1);
processlen += rxbuf->canPacket[i].dlc - 1;
}
// 重新开始接收CAN总线上的数据
rxbuf->dataIsReady = false;
rxbuf->canPacketNum = 0;
rxbuf->npacket = 0;
// 处理接收到的数据
for (auto &var : m_listenerList) {
if (var) var->onRceivePacket((zcr_cmd_header_t *)processbuf, processlen);
auto *rx = m_pendingMsgQueue.receive();
if (rx) {
// !处理接收到的数据!
if (rxprocesser) rxprocesser->processRxPacket(rx);
}
}

41
sdk/components/zcancmder/zcanreceiver.hpp

@ -3,18 +3,21 @@
//
#pragma once
#include "a8000_protocol\protocol.hpp"
#include "basic.hpp"
#include "a8000_protocol/protocol.hpp"
#include "sdk/components/api/zi_module.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\api\zi_module.hpp"
#include "type/zcan_rx_frame.hpp"
#include "type/zcan_rx_frame_pool.hpp"
#include "type/zcan_rx_frame_queue.hpp"
#ifdef HAL_CAN_MODULE_ENABLED
namespace iflytop {
using namespace zcr;
class IZCanReceiverListener {
class IZCanRxProcesser {
public:
virtual void onRceivePacket(zcr_cmd_header_t *rxcmd, int32_t len) = 0;
virtual bool filterPacket(ZcanRxframe *rx) = 0;
virtual void processRxPacket(ZcanRxframe *rx) = 0;
};
class ZCanReceiver : public ZCanIRQListener {
@ -32,22 +35,6 @@ class ZCanReceiver : public ZCanIRQListener {
int packetRxOvertime_ms; //
};
class RXFrameBuffer {
typedef struct {
uint8_t dlc;
uint8_t aData[8]; /*8byte table*/
} CANPacket;
public:
uint16_t id = 0;
CANPacket canPacket[16] = {0}; // 最多16(2^4)帧数据
uint8_t canPacketNum = 0;
uint8_t npacket = 0;
bool dataIsReady = false;
};
uint8_t txbuff[128];
public:
class LoopJobContext {
public:
@ -60,9 +47,13 @@ class ZCanReceiver : public ZCanIRQListener {
uint32_t m_lastPacketTicket = 0; // 上一次接收到消息的时间,用于判断与主机是否断开连接
HAL_StatusTypeDef m_lastTransmitStatus; // 上次调用can发送方法的返回值
list<IZCanReceiverListener *> m_listenerList;
RXFrameBuffer m_rxFrameBuffer;
uint8_t m_rxPacketProcessBuf[128]; // 单包数据最大包长 112(7 * 2^4)
uint8_t txbuff[128];
IZCanRxProcesser *rxprocesser;
ZcanRxframePool m_rxFramePool; // 接收数据池
ZcanRxframeQueue m_pendingMsgQueue; // 接收数据队列
ZcanRxframe *curRxBuf = nullptr; // 当前接收数据
int txPacketInterval_ms = 0;
zmutex m_lock;
@ -77,7 +68,7 @@ class ZCanReceiver : public ZCanIRQListener {
uint8_t getDeviceId() { return m_config->deviceId; }
void setTxPacketInterval(int interval_ms) { txPacketInterval_ms = interval_ms; }
virtual void registerListener(IZCanReceiverListener *listener);
virtual void registerListener(IZCanRxProcesser *listener);
virtual int32_t sendBufAck(zcr_cmd_header_t *rx_cmd_header, uint8_t *data, int32_t len);
virtual int32_t sendAck(zcr_cmd_header_t *rx_cmd_header, int32_t *ackvar, int32_t nack);
virtual int32_t sendErrorAck(zcr_cmd_header_t *rx_cmd_header, int32_t errorcode);

2
usrc/public_service/gservice.hpp

@ -2,7 +2,7 @@
#include <stdio.h>
#include "sdk/chip/chip.hpp"
#include "sdk/components/zcancmder/zcan_protocol_parser.hpp"
#include "sdk/components/zcan_protocol_parser/zcan_protocol_parser.hpp"
#include "sdk/components/zcancmder/zcanreceiver.hpp"
#include "sdk/os/zos.hpp"
#include "sdk\components\zcancmder\protocol_event_bus_sender.hpp"

2
usrc/version.h

@ -1,2 +1,2 @@
#pragma once
#define PC_VERSION 1020
#define PC_VERSION 1021
Loading…
Cancel
Save