diff --git a/CMakeLists.txt b/CMakeLists.txt index f069acb..96b1ec7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ file(GLOB_RECURSE VAR_APP_SOURCE # message("VAR_APP_SOURCE: ${VAR_APP_SOURCE}") zadd_executable( TARGET - iflytopzexcand # + iflytoptdcan # INSTALL ./app/ # diff --git a/resources/iflytopzexcand.service b/resources/iflytoptdcan.service similarity index 58% rename from resources/iflytopzexcand.service rename to resources/iflytoptdcan.service index 8563a6d..7cd960a 100644 --- a/resources/iflytopzexcand.service +++ b/resources/iflytoptdcan.service @@ -1,15 +1,15 @@ [Unit] # 服务名称,可自定义 -Description = iflytopzexcand +Description = iflytoptdcan After = network.target Wants = network.target [Service] Type = simple -ExecStart = /iflytopd/iflytopzexcand/iflytopzexcand +ExecStart = /iflytopd/iflytoptdcan/iflytoptdcan Restart=always RestartSec=0 -WorkingDirectory=/iflytopd/iflytopzexcand/ +WorkingDirectory=/iflytopd/iflytoptdcan/ [Install] WantedBy = multi-user.target diff --git a/resources/install_service.sh b/resources/install_service.sh new file mode 100755 index 0000000..4f0668b --- /dev/null +++ b/resources/install_service.sh @@ -0,0 +1,2 @@ +#/!/bin/bash +cp iflytoptdcan.service /usr/lib/systemd/system/ \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index 31e995c..6b666b3 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -14,28 +14,23 @@ void App::initialize() { string ifname = config["basic"]["ifname"].value_or("can0"); int baudrate = config["basic"]["baudrate"].value_or(500000); - m_zcanreceiverhost.reset(new ZCanReceiverHost()); - m_zcanreceiverhost->initialize(ifname, baudrate); + m_tdcanreceiverhost.reset(new TDCanReceiverHost()); + m_tdcanreceiverhost->initialize(ifname, baudrate); } catch (const toml::parse_error& err) { logger->error("parse config error, {}", err); exit(1); } - m_unixsocket.reset(new UnixScoket(UnixScoket::Server, "zexcan")); + m_unixsocket.reset(new UnixScoket(UnixScoket::Server, "tdcan")); m_unixsocket->start(); - m_zcanreceiverhost->registerListener([this](uint8_t fromboardid, uint8_t* packet, size_t packetlen) { - string hexStr = StringUtils().bytesToString((uint8_t*)packet, packetlen); - logger->info("RX_FROM_CAN:<- {}({})", hexStr, hexStr.size()); - - // Tx to Unix socket + m_tdcanreceiverhost->registerListener([this](uint8_t* packet, size_t packetlen) { + logger->info("tx"); m_unixsocket->sendPacket(packet, packetlen); }); m_unixsocket->onPacket.connect([this](const uint8_t* packet, size_t packetlen) { - logger->info("RX_FROM_UNIX_SOCKET:-> {}", StringUtils().bytesToString((uint8_t*)packet, packetlen)); - - // Tx to CAN - m_zcanreceiverhost->sendPacket((uint8_t*)packet, packetlen); + logger->info("rx"); + m_tdcanreceiverhost->sendPacket((uint8_t*)packet, packetlen); }); } \ No newline at end of file diff --git a/src/app.hpp b/src/app.hpp index 01be2e4..d5073db 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -8,7 +8,7 @@ #include "components/linuxsocket//unix_socket.hpp" #include "components/thread/thread.hpp" -#include "components/zcanreceiver/zcanreceiverhost.hpp" +#include "components/zcanreceiver/tdcanreceiverhost.hpp" #include "thirdlib/nod/nod.hpp" #include "thirdlib/spdlogfactory/logger_factory.hpp" @@ -21,8 +21,8 @@ class App { ENABLE_LOGGER(App); private: - unique_ptr m_zcanreceiverhost; - unique_ptr m_unixsocket; + unique_ptr m_tdcanreceiverhost; + unique_ptr m_unixsocket; public: App() {} diff --git a/src/components/linuxsocket/unix_socket.hpp b/src/components/linuxsocket/unix_socket.hpp index 40ee0af..c9aec20 100644 --- a/src/components/linuxsocket/unix_socket.hpp +++ b/src/components/linuxsocket/unix_socket.hpp @@ -59,11 +59,10 @@ class UnixScoket { memset(&tx_addr, 0, sizeof(tx_addr)); tx_addr.sun_family = AF_UNIX; strncpy(tx_addr.sun_path, m_opposite_path.c_str(), sizeof(tx_addr.sun_path) - 1); - } void start(); void sendPacket(uint8_t* data, size_t len); - int initRxSocket(); + int initRxSocket(); }; } // namespace iflytop \ No newline at end of file diff --git a/src/components/zcanreceiver/tdcan_protocol.hpp b/src/components/zcanreceiver/tdcan_protocol.hpp new file mode 100644 index 0000000..e4bf3d4 --- /dev/null +++ b/src/components/zcanreceiver/tdcan_protocol.hpp @@ -0,0 +1,38 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +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 \ No newline at end of file diff --git a/src/components/zcanreceiver/tdcanreceiverhost.cpp b/src/components/zcanreceiver/tdcanreceiverhost.cpp new file mode 100644 index 0000000..94b3a09 --- /dev/null +++ b/src/components/zcanreceiver/tdcanreceiverhost.cpp @@ -0,0 +1,151 @@ +#include "tdcanreceiverhost.hpp" + +#include +#include +#include + +#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->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 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 frame = SocketCanFrame::createExtDataFrame(canid, packet, len); + logger->info("|-->TX RAW :{}", frame->toString()); + m_socketCan->sendFrame(frame, 0); + return true; +} + +void TDCanReceiverHost::processRx(shared_ptr 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(); } diff --git a/src/components/zcanreceiver/zcanreceiverhost.hpp b/src/components/zcanreceiver/tdcanreceiverhost.hpp similarity index 66% rename from src/components/zcanreceiver/zcanreceiverhost.hpp rename to src/components/zcanreceiver/tdcanreceiverhost.hpp index c0d62a2..5f32213 100644 --- a/src/components/zcanreceiver/zcanreceiverhost.hpp +++ b/src/components/zcanreceiver/tdcanreceiverhost.hpp @@ -6,6 +6,7 @@ #include #include "socket_can/socket_can.hpp" +#include "tdcan_protocol.hpp" // #include "thirdlib/spdlogfactory/logger_factory.hpp" @@ -14,8 +15,8 @@ namespace iflytop { using namespace std; using namespace core; -class ZCanReceiverHost { - ENABLE_LOGGER(ZCanReceiverHost); +class TDCanReceiverHost { + ENABLE_LOGGER(TDCanReceiverHost); public: class CanPacketRxBuffer { @@ -25,9 +26,11 @@ class ZCanReceiverHost { uint8_t m_rxdata[255 * 8]; uint8_t m_canPacketNum = 0; uint8_t m_rxdataLen = 0; + uint8_t to = 0; // 接收数据的目标ID + uint8_t from = 0; // 接收数据的来源ID }; - typedef function onpacket_t; + typedef function onpacket_t; public: uint8_t m_hostId = 0; @@ -36,22 +39,22 @@ class ZCanReceiverHost { shared_ptr m_socketCan; - string m_can_if_name; - int m_baudrate; - bool m_enablLoopback; + string m_can_if_name; + int m_baudrate; + bool m_enablLoopback; + int32_t hostid = -1; public: - ZCanReceiverHost(); + TDCanReceiverHost(); void initialize(string can_if_name, int baudrate); void sendPacket(uint8_t *packet, size_t len); void registerListener(onpacket_t onpacket); void restartCanInterface(); private: - bool sendPacketSub(int npacket, int packetIndex, uint8_t *packet, size_t len, int overtimems); + bool sendPacketSub(int32_t canid, uint8_t *packet, size_t len); void processRx(shared_ptr frame); - void processOnePacket(CanPacketRxBuffer *rxbuf, uint8_t *packet, size_t len); void sendcmd(uint16_t packetindex, uint16_t cmdid, uint8_t subcmdid, uint8_t *data, size_t len); }; diff --git a/src/components/zcanreceiver/zcanreceiverhost.cpp b/src/components/zcanreceiver/zcanreceiverhost.cpp deleted file mode 100644 index 4bba4d5..0000000 --- a/src/components/zcanreceiver/zcanreceiverhost.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include "zcanreceiverhost.hpp" - -#include -#include -#include - -#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->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 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 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 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(); } diff --git a/src/configs/version.hpp b/src/configs/version.hpp index cae227f..8820105 100644 --- a/src/configs/version.hpp +++ b/src/configs/version.hpp @@ -1,2 +1,2 @@ #pragma once -#define VERSION "1.4" \ No newline at end of file +#define VERSION "1.0" \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e54f0f0..6877ecd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,7 +35,7 @@ int main(int argc, char* argv[]) { } // unique_ptr server; - // server.reset(new UnixScoket(UnixScoket::Server, "zexcan")); + // server.reset(new UnixScoket(UnixScoket::Server, "tdcan")); // server->start(); // server->onPacket.connect([mainLogger](uint8_t* data, size_t len) { // if (len > 0) { @@ -44,7 +44,7 @@ int main(int argc, char* argv[]) { // }); // unique_ptr client; - // client.reset(new UnixScoket(UnixScoket::Client, "zexcan")); + // client.reset(new UnixScoket(UnixScoket::Client, "tdcan")); // client->start(); // while (true) { diff --git a/test/config.ini b/test/config.ini deleted file mode 100644 index 2e83de4..0000000 --- a/test/config.ini +++ /dev/null @@ -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 diff --git a/tools/build.sh b/tools/build.sh index fa12f84..362ae62 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -6,4 +6,4 @@ cmake .. \ make -j8 make install -aarch64-linux-gnu-strip ./build/app/iflytopzexcand \ No newline at end of file +aarch64-linux-gnu-strip ./app/iflytoptdcan \ No newline at end of file diff --git a/tools/deply.sh b/tools/deply.sh index 61899ef..354739f 100755 --- a/tools/deply.sh +++ b/tools/deply.sh @@ -8,10 +8,10 @@ if [ $# -ne 1 ]; then fi server=$1 -ssh $server 'mkdir -p /iflytopd/iflytopzexcand/' -ssh $server 'systemctl stop iflytopzexcand' -scp ./build/app/iflytopzexcand $server:/iflytopd/iflytopzexcand/ -# scp ./resources/iflytopzexcand.service $server:/lib/systemd/system/ -# scp ./resources/config.ini $server:/iflytopd/iflytopzexcand/ -scp ./resources/spd_logger_cfg.json $server:/iflytopd/iflytopzexcand/ -ssh $server 'systemctl start iflytopzexcand' \ No newline at end of file +ssh $server 'mkdir -p /iflytopd/iflytoptdcan/' +ssh $server 'systemctl stop iflytoptdcan' +scp ./build/app/iflytoptdcan $server:/iflytopd/iflytoptdcan/ +# scp ./resources/iflytoptdcan.service $server:/lib/systemd/system/ +# scp ./resources/config.ini $server:/iflytopd/iflytoptdcan/ +scp ./resources/spd_logger_cfg.json $server:/iflytopd/iflytoptdcan/ +ssh $server 'systemctl start iflytoptdcan' \ No newline at end of file diff --git a/tools/packet.sh b/tools/packet.sh index 8933293..f2961a4 100755 --- a/tools/packet.sh +++ b/tools/packet.sh @@ -10,18 +10,18 @@ if [ $# -ne 1 ]; then fi version=$1 -packetname=iflytopzexcand +packetname=iflytoptdcan workdir=$(pwd) echo "workdir: $workdir" mkdir -p /tmp/$packetname -aarch64-linux-gnu-strip ./build/app/iflytopzexcand -cp -r ./build/app/iflytopzexcand /tmp/$packetname/ +aarch64-linux-gnu-strip ./build/app/iflytoptdcan +cp -r ./build/app/iflytoptdcan /tmp/$packetname/ cp -r ./resources/spd_logger_cfg.json /tmp/$packetname/ cp -r ./resources/*.ini /tmp/$packetname/ -cp -r ./resources/iflytopzexcand.service /tmp/$packetname/ +cp -r ./resources/iflytoptdcan.service /tmp/$packetname/ echo "Version: $version" > /tmp/$packetname/version