18 changed files with 294 additions and 263 deletions
-
2CMakeLists.txt
-
6resources/iflytoptdcan.service
-
2resources/install_service.sh
-
19src/app.cpp
-
4src/app.hpp
-
1src/components/linuxsocket/unix_socket.hpp
-
38src/components/zcanreceiver/tdcan_protocol.hpp
-
151src/components/zcanreceiver/tdcanreceiverhost.cpp
-
15src/components/zcanreceiver/tdcanreceiverhost.hpp
-
127src/components/zcanreceiver/zcanreceiverhost.cpp
-
2src/configs/version.hpp
-
4src/main.cpp
-
30test/config.ini
-
2tools/build.sh
-
14tools/deply.sh
-
8tools/packet.sh
@ -1,15 +1,15 @@ |
|||||
[Unit] |
[Unit] |
||||
# 服务名称,可自定义 |
# 服务名称,可自定义 |
||||
Description = iflytopzexcand |
|
||||
|
Description = iflytoptdcan |
||||
After = network.target |
After = network.target |
||||
Wants = network.target |
Wants = network.target |
||||
|
|
||||
[Service] |
[Service] |
||||
Type = simple |
Type = simple |
||||
ExecStart = /iflytopd/iflytopzexcand/iflytopzexcand |
|
||||
|
ExecStart = /iflytopd/iflytoptdcan/iflytoptdcan |
||||
Restart=always |
Restart=always |
||||
RestartSec=0 |
RestartSec=0 |
||||
WorkingDirectory=/iflytopd/iflytopzexcand/ |
|
||||
|
WorkingDirectory=/iflytopd/iflytoptdcan/ |
||||
|
|
||||
[Install] |
[Install] |
||||
WantedBy = multi-user.target |
WantedBy = multi-user.target |
@ -0,0 +1,2 @@ |
|||||
|
#/!/bin/bash |
||||
|
cp iflytoptdcan.service /usr/lib/systemd/system/ |
@ -0,0 +1,38 @@ |
|||||
|
#pragma once
|
||||
|
#include <fstream>
|
||||
|
#include <functional>
|
||||
|
#include <iostream>
|
||||
|
#include <list>
|
||||
|
#include <map>
|
||||
|
#include <memory>
|
||||
|
#include <set>
|
||||
|
#include <sstream>
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
namespace iflytop { |
||||
|
using namespace std; |
||||
|
|
||||
|
typedef struct { |
||||
|
struct { |
||||
|
uint8_t fid : 4; // frame ID
|
||||
|
uint8_t fnum : 4; // frame number
|
||||
|
} frameinfo; |
||||
|
uint8_t to; |
||||
|
uint8_t from; |
||||
|
uint8_t pad; |
||||
|
} tdcan_id_t; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
typedef struct { |
||||
|
uint8_t from; |
||||
|
uint8_t to; |
||||
|
uint8_t ptype; |
||||
|
uint8_t index; |
||||
|
uint16_t fnid; |
||||
|
uint8_t params[]; // parameters
|
||||
|
} tdcan_frame_t; |
||||
|
|
||||
|
|
||||
|
} // namespace iflytop
|
@ -0,0 +1,151 @@ |
|||||
|
#include "tdcanreceiverhost.hpp"
|
||||
|
|
||||
|
#include <stdio.h>
|
||||
|
#include <stdlib.h>
|
||||
|
#include <string.h>
|
||||
|
|
||||
|
#include "utils/stringutils.hpp"
|
||||
|
using namespace iflytop; |
||||
|
|
||||
|
#define TAG "TDCanReceiverHost"
|
||||
|
|
||||
|
#define OVER_TIME_MS 20
|
||||
|
#define ZARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
|
||||
|
using namespace iflytop; |
||||
|
|
||||
|
TDCanReceiverHost::TDCanReceiverHost() {} |
||||
|
|
||||
|
void TDCanReceiverHost::initialize(string can_if_name, int baudrate) { |
||||
|
// m_iflytopCanProtocolStack.reset(new IflytopCanProtocolStack());
|
||||
|
m_can_if_name = can_if_name; |
||||
|
m_baudrate = baudrate; |
||||
|
m_enablLoopback = false; |
||||
|
|
||||
|
auto socketCanConfig = make_shared<SocketCanConfig>(); |
||||
|
socketCanConfig->enablLoopback = m_enablLoopback; // 根据 SocketCan::dumpCanDriverInfo() 的输出,确定该标志位是false还是true
|
||||
|
socketCanConfig->m_canName = m_can_if_name; |
||||
|
socketCanConfig->m_canBaudrate = m_baudrate; |
||||
|
socketCanConfig->m_canfilters = {}; |
||||
|
|
||||
|
logger->info("initialize() m_canName:{} {}", socketCanConfig->m_canName, socketCanConfig->m_canBaudrate); |
||||
|
|
||||
|
m_socketCan.reset(new SocketCan()); |
||||
|
m_socketCan->initialize(socketCanConfig); |
||||
|
m_socketCan->onSocketCanFrame.connect([this](shared_ptr<SocketCanFrame> canframe) { //
|
||||
|
static_assert(sizeof(tdcan_id_t) == 4, "tdcan_id_t must be 4 bytes"); |
||||
|
|
||||
|
int32_t canid = canframe->getId(); |
||||
|
tdcan_id_t id = *((tdcan_id_t *)(&(canid))); |
||||
|
|
||||
|
// id 1 是本机发出去的消息,理论上会被过滤掉不上报
|
||||
|
if (id.from == 1) { |
||||
|
logger->info("|-->TX RAW: {} SUC", canframe->toString()); |
||||
|
return; |
||||
|
} |
||||
|
processRx(canframe); |
||||
|
}); |
||||
|
} |
||||
|
void TDCanReceiverHost::registerListener(onpacket_t onpacket) { m_onpacket = onpacket; } |
||||
|
|
||||
|
void TDCanReceiverHost::sendPacket(uint8_t *packet, size_t len) { |
||||
|
tdcan_frame_t *tdcan_frame = (tdcan_frame_t *)packet; |
||||
|
|
||||
|
uint8_t *data = &(tdcan_frame->ptype); |
||||
|
int32_t datalen = len - sizeof(tdcan_frame->from) - sizeof(tdcan_frame->to); |
||||
|
int32_t paramlen = len - sizeof(*tdcan_frame); |
||||
|
|
||||
|
tdcan_id_t id; |
||||
|
id.from = tdcan_frame->from; |
||||
|
id.to = tdcan_frame->to; |
||||
|
id.frameinfo.fid = 0; |
||||
|
id.frameinfo.fnum = datalen / 8 + (datalen % 8 == 0 ? 0 : 1); |
||||
|
id.pad = 0; |
||||
|
|
||||
|
int finalpacketlen = datalen % 8 == 0 ? 8 : datalen % 8; |
||||
|
|
||||
|
logger->info("|TX:[index:{},to:{},fnid:{},params:{}({})]", tdcan_frame->index, tdcan_frame->to, tdcan_frame->fnid, |
||||
|
StringUtils().bytesToString(tdcan_frame->params, paramlen), paramlen); |
||||
|
|
||||
|
for (uint8_t i = 0; i < id.frameinfo.fnum; i++) { |
||||
|
id.frameinfo.fid = i; |
||||
|
int32_t canid = *((int32_t *)(&id)); |
||||
|
if (i == id.frameinfo.fnum - 1) { |
||||
|
sendPacketSub(canid, data + i * 8, finalpacketlen); |
||||
|
} else { |
||||
|
sendPacketSub(canid, data + i * 8, 8); |
||||
|
} |
||||
|
} |
||||
|
logger->info("-"); |
||||
|
} |
||||
|
|
||||
|
bool TDCanReceiverHost::sendPacketSub(int32_t canid, uint8_t *packet, size_t len) { |
||||
|
shared_ptr<SocketCanFrame> frame = SocketCanFrame::createExtDataFrame(canid, packet, len); |
||||
|
logger->info("|-->TX RAW :{}", frame->toString()); |
||||
|
m_socketCan->sendFrame(frame, 0); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void TDCanReceiverHost::processRx(shared_ptr<SocketCanFrame> canframe) { |
||||
|
// uint8_t from = (frame->getId() >> 16 & 0xFF);
|
||||
|
// uint8_t nframe = (frame->getId() & 0xFF00) >> 8;
|
||||
|
// uint8_t frameId = (frame->getId() & 0x00FF);
|
||||
|
|
||||
|
/**
|
||||
|
* @brief 消息格式 |
||||
|
* |
||||
|
* [2] [3bit] [8bit] [8bit] [8bit] |
||||
|
* , from frameNum frameId |
||||
|
*/ |
||||
|
|
||||
|
int32_t rawcanid = canframe->getId(); |
||||
|
tdcan_id_t *canid = (tdcan_id_t *)&rawcanid; |
||||
|
|
||||
|
uint8_t from = canid->from; |
||||
|
uint8_t to = canid->to; |
||||
|
uint8_t nframe = canid->frameinfo.fnum; |
||||
|
uint8_t frameId = canid->frameinfo.fid; |
||||
|
|
||||
|
logger->info("|RX [from:{} fram:{}/{}] {}", canid->from, frameId + 1, nframe, canframe->toString()); |
||||
|
if (from == 0 || from >= 255) { |
||||
|
logger->error("Invalid from board id: {}", from); |
||||
|
return; |
||||
|
} |
||||
|
static_assert(ZARRAY_SIZE(m_canPacketRxBuffer) >= 255); |
||||
|
CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[from]; |
||||
|
|
||||
|
if (frameId == 0) { |
||||
|
rxbuf->m_canPacketNum = 0; |
||||
|
rxbuf->from = from; |
||||
|
rxbuf->to = to; |
||||
|
|
||||
|
rxbuf->m_rxdata[0] = from; |
||||
|
rxbuf->m_rxdata[1] = to; |
||||
|
rxbuf->m_rxdataLen = 2; |
||||
|
} |
||||
|
|
||||
|
if (rxbuf->m_canPacketNum != frameId) { |
||||
|
logger->error("|lost subpacket from {}", from); |
||||
|
rxbuf->m_rxdataLen = 0; |
||||
|
rxbuf->m_canPacketNum = 0; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
memcpy(rxbuf->m_rxdata + rxbuf->m_rxdataLen, canframe->getData(), canframe->getDlc()); |
||||
|
rxbuf->m_rxdataLen += canframe->getDlc(); |
||||
|
rxbuf->m_canPacketNum++; |
||||
|
|
||||
|
if (nframe == frameId + 1) { |
||||
|
tdcan_frame_t *tdcan_frame = (tdcan_frame_t *)rxbuf->m_rxdata; |
||||
|
int32_t paramLen = rxbuf->m_rxdataLen - sizeof(tdcan_frame_t); |
||||
|
logger->info("|-->RX:[index:{},to:{},fnid:{},params:{}({})]", tdcan_frame->index, tdcan_frame->to, tdcan_frame->fnid, |
||||
|
StringUtils().bytesToString(tdcan_frame->params, paramLen), paramLen); |
||||
|
logger->info("-"); |
||||
|
|
||||
|
if (m_onpacket) { |
||||
|
m_onpacket(rxbuf->m_rxdata, rxbuf->m_rxdataLen); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TDCanReceiverHost::restartCanInterface() { m_socketCan->reStartCanInterface(); } |
@ -1,127 +0,0 @@ |
|||||
#include "zcanreceiverhost.hpp"
|
|
||||
|
|
||||
#include <stdio.h>
|
|
||||
#include <stdlib.h>
|
|
||||
#include <string.h>
|
|
||||
|
|
||||
#include "utils/stringutils.hpp"
|
|
||||
using namespace iflytop; |
|
||||
|
|
||||
#define TAG "ZCanReceiver"
|
|
||||
|
|
||||
#define OVER_TIME_MS 20
|
|
||||
|
|
||||
using namespace iflytop; |
|
||||
|
|
||||
ZCanReceiverHost::ZCanReceiverHost() {} |
|
||||
|
|
||||
void ZCanReceiverHost::initialize(string can_if_name, int baudrate) { |
|
||||
// m_iflytopCanProtocolStack.reset(new IflytopCanProtocolStack());
|
|
||||
m_can_if_name = can_if_name; |
|
||||
m_baudrate = baudrate; |
|
||||
m_enablLoopback = false; |
|
||||
|
|
||||
auto socketCanConfig = make_shared<SocketCanConfig>(); |
|
||||
socketCanConfig->enablLoopback = m_enablLoopback; // 根据 SocketCan::dumpCanDriverInfo() 的输出,确定该标志位是false还是true
|
|
||||
socketCanConfig->m_canName = m_can_if_name; |
|
||||
socketCanConfig->m_canBaudrate = m_baudrate; |
|
||||
socketCanConfig->m_canfilters = {}; |
|
||||
|
|
||||
logger->info("initialize() m_canName:{} {}", socketCanConfig->m_canName, socketCanConfig->m_canBaudrate); |
|
||||
|
|
||||
m_socketCan.reset(new SocketCan()); |
|
||||
m_socketCan->initialize(socketCanConfig); |
|
||||
m_socketCan->onSocketCanFrame.connect([this](shared_ptr<SocketCanFrame> canframe) { //
|
|
||||
if (canframe->getId() == m_hostId) { |
|
||||
logger->info("TX RAW: {} SUC", canframe->toString()); |
|
||||
return; |
|
||||
} |
|
||||
logger->info("RX RAW: {}", canframe->toString()); |
|
||||
processRx(canframe); |
|
||||
}); |
|
||||
} |
|
||||
void ZCanReceiverHost::registerListener(onpacket_t onpacket) { m_onpacket = onpacket; } |
|
||||
|
|
||||
void ZCanReceiverHost::sendPacket(uint8_t *packet, size_t len) { |
|
||||
logger->info("TX: {}", StringUtils().bytesToString(packet, len)); |
|
||||
int npacket = len / 7 + (len % 7 == 0 ? 0 : 1); |
|
||||
if (npacket > 255) { |
|
||||
return; |
|
||||
} |
|
||||
int finalpacketlen = len % 7 == 0 ? 7 : len % 7; |
|
||||
for (uint8_t i = 0; i < npacket; i++) { |
|
||||
bool suc = false; |
|
||||
if (i == npacket - 1) { |
|
||||
suc = sendPacketSub(npacket, i, packet + i * 7, finalpacketlen, OVER_TIME_MS); |
|
||||
} else { |
|
||||
suc = sendPacketSub(npacket, i, packet + i * 7, 7, OVER_TIME_MS); |
|
||||
} |
|
||||
if (!suc) { |
|
||||
logger->warn("sendPacket fail, packet(%d:%d)\n", npacket, i); |
|
||||
return; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
bool ZCanReceiverHost::sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems) { |
|
||||
uint32_t id = m_hostId; |
|
||||
uint8_t txdata[8] = {0}; |
|
||||
txdata[0] = npacket << 4 | packetIndex; |
|
||||
memcpy(txdata + 1, packet, len); |
|
||||
// m_comcan.sendframe(CANUSB_FRAME_EXTENDED, id, packet, len);
|
|
||||
// printf("sendPacketSub(%d:%d) ", npacket, packetIndex);
|
|
||||
// for (size_t i = 0; i < len; i++) {
|
|
||||
// printf("%02x ", packet[i]);
|
|
||||
// }
|
|
||||
// printf("\n");
|
|
||||
|
|
||||
shared_ptr<SocketCanFrame> frame = SocketCanFrame::createStdDataFrame(id, txdata, len + 1); |
|
||||
logger->info("TX RAW :{}", frame->toString()); |
|
||||
m_socketCan->sendFrame(frame, overtimems); |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
void ZCanReceiverHost::processOnePacket(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len) { //
|
|
||||
if (m_onpacket) m_onpacket(rxbuf->id, packet, len); |
|
||||
} |
|
||||
|
|
||||
void ZCanReceiverHost::processRx(shared_ptr<SocketCanFrame> frame) { |
|
||||
// uint8_t from = (frame->getId() >> 16 & 0xFF);
|
|
||||
// uint8_t nframe = (frame->getId() & 0xFF00) >> 8;
|
|
||||
// uint8_t frameId = (frame->getId() & 0x00FF);
|
|
||||
|
|
||||
uint8_t from = (frame->getId() & 0xFF); |
|
||||
uint8_t nframe = ((frame->getData()[0] >> 4) & 0x0F); |
|
||||
uint8_t frameId = (frame->getData()[0] & 0x0F); |
|
||||
|
|
||||
CanPacketRxBuffer *rxbuf = &m_canPacketRxBuffer[from]; |
|
||||
rxbuf->id = from; |
|
||||
|
|
||||
if (frameId == 0) { |
|
||||
rxbuf->m_canPacketNum = 0; |
|
||||
rxbuf->m_rxdataLen = 0; |
|
||||
} |
|
||||
|
|
||||
if (frameId != rxbuf->m_canPacketNum) { |
|
||||
rxbuf->m_canPacketNum = 0; |
|
||||
rxbuf->m_rxdataLen = 0; |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (rxbuf->m_canPacketNum < 255) { |
|
||||
rxbuf->m_canPacket[rxbuf->m_canPacketNum] = frame; |
|
||||
rxbuf->m_canPacketNum++; |
|
||||
memcpy(rxbuf->m_rxdata + rxbuf->m_rxdataLen, frame->getData() + 1, frame->getDlc() - 1); |
|
||||
rxbuf->m_rxdataLen += frame->getDlc() - 1; |
|
||||
} |
|
||||
|
|
||||
if (nframe == frameId + 1) { |
|
||||
/**
|
|
||||
* @brief 接收到最后一包数据 |
|
||||
*/ |
|
||||
logger->info("RX: {}", StringUtils().bytesToString(rxbuf->m_rxdata, rxbuf->m_rxdataLen)); |
|
||||
processOnePacket(rxbuf, rxbuf->m_rxdata, rxbuf->m_rxdataLen); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void ZCanReceiverHost::restartCanInterface() { m_socketCan->reStartCanInterface(); } |
|
@ -1,2 +1,2 @@ |
|||||
#pragma once
|
#pragma once
|
||||
#define VERSION "1.4"
|
|
||||
|
#define VERSION "1.0"
|
@ -1,30 +0,0 @@ |
|||||
[server] |
|
||||
cmdport=19004 |
|
||||
wsport=19005 |
|
||||
|
|
||||
[[channels]] |
|
||||
type="zexcan" |
|
||||
name="zcan" |
|
||||
ifname="can0" |
|
||||
baudrate=500000 |
|
||||
enable=true |
|
||||
|
|
||||
[[channels]] |
|
||||
type="uart" |
|
||||
name="printer" |
|
||||
ifname="/dev/ttyS1" |
|
||||
baudrate=115200 |
|
||||
enable=true |
|
||||
|
|
||||
[[channels]] |
|
||||
type="inputkey" |
|
||||
name="emergency-key" |
|
||||
pinnum="GPIO2-A3" |
|
||||
enable=true |
|
||||
|
|
||||
[[channels]] |
|
||||
type="uart" |
|
||||
name="lis" |
|
||||
ifname="/dev/ttyS2" |
|
||||
baudrate=115200 |
|
||||
enable=true |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue