pCanBridge 扩展多通道支持:每通道独立TCP链路 + 上下行对称通道标注(m_sSrcAux)
pCanBridge: - 配置改为 channel = <通道名>,<IP>,<工作端口> 重复行(兼容旧 can_host/can_port 单通道回退), 每通道一条独立 CanEndpoint(TCP Client) + 接收线程,对应 CANET 的 CAN0=4001..CAN7=4008 - 上行 CAN_0x%08X 不变,m_sSrcAux=通道名区分来源通道 - 下行按 m_sSrcAux 路由到对应通道;回退规则:default_channel > 单通道 > 多通道告警丢弃 - buildReport 逐通道统计(连接/收发帧数/错误/重连) pCCU: - 新增 bcu_can_channel 配置(默认 CAN0),BCU 断路器下行 Post 前 SetSourceAux 指定目标通道, key 保持 CAN_TX_0x%08X(与上行通道标注对称,key 格式不变) 配置/文档:pCanBridge.moos、CanBridge_Info、pCCU.moos、missions/h100.moos、 test/pccu/pccu_it.moos 同步新格式。 验证:伪造 CANET Server 冒烟通过(多通道建链/上行解析发布/SQLite channel 列/ 下行通道路由与回退丢弃/srcAux 经 MOOSDB 往返); pccu 集成测试 PASSED(BCU 断路器下行 3 帧经新路由全部正确); pccuTest 183/183、PowerMangerTests 64/64 通过。
This commit is contained in:
+54
-21
@@ -6,14 +6,21 @@
|
||||
#include "CanEndpoint.h"
|
||||
#include "CanDbStore.h"
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace canbridge {
|
||||
|
||||
//============================================================================
|
||||
// CanBridge:CAN <-> MOOSDB 双向透传桥(MOOS 应用外壳)。
|
||||
// CanBridge:CAN <-> MOOSDB 多通道双向透传桥(MOOS 应用外壳)。
|
||||
//
|
||||
// 数据流(上行):
|
||||
// USBCAN-8E-U (TCP Server, 默认 192.168.0.222:4001 = CAN0)
|
||||
// 通道配置(.moos 中可重复多行):
|
||||
// channel = <通道名>,<转换器IP>,<工作端口>
|
||||
// 如 channel = CAN0,192.168.0.222,4001(CANET: CAN0=4001..CAN7=4008)
|
||||
// 每通道一条独立 TCP 连接 + 独立接收线程。
|
||||
//
|
||||
// 数据流(上行,每通道一条 TCP 连接):
|
||||
// CANET 工作端口 (TCP Server)
|
||||
// -> CanEndpoint(TCP Client,13 字节切帧)
|
||||
// -> handleFrame() 解析
|
||||
// -> Notify 到 MOOSDB
|
||||
@@ -21,16 +28,24 @@ namespace canbridge {
|
||||
// 数据流(下行,BCU 断路器/继电器控制等):
|
||||
// MOOS "CAN_TX_0x%08X"(二进制数据域,dlc<=8)
|
||||
// -> OnNewMail 解析 CAN ID 与数据
|
||||
// -> CanEndpoint::sendFrame(同一 TCP 连接写出 13 字节帧)
|
||||
// -> USBCAN -> CAN 总线
|
||||
// -> 按消息 m_sSrcAux(目标通道名)路由到对应通道的 CanEndpoint
|
||||
// -> CanEndpoint::sendFrame(该通道 TCP 连接写出 13 字节帧)
|
||||
// -> CANET -> CAN 总线
|
||||
//
|
||||
// MOOS 消息映射:
|
||||
// m_sKey = "CAN_0x%08X" CAN ID(完整 4 字节,标准/扩展帧同格式)
|
||||
// m_sVal = 二进制 data(dlc 字节,MOOS_BINARY_STRING)
|
||||
// m_sSrcAux = 通道名(默认 "CAN0",配置项 can_channel_name)
|
||||
// m_dfVal2 = 原始帧信息字节 byte0(bit7 FF / bit6 RTR / bit3~0 DLC)
|
||||
// MOOS 消息映射(上行/下行对称,通道一律走 m_sSrcAux):
|
||||
// 上行 m_sKey = "CAN_0x%08X" CAN ID(完整 4 字节,标准/扩展帧同格式)
|
||||
// 上行 m_sVal = 二进制 data(dlc 字节,MOOS_BINARY_STRING)
|
||||
// 上行 m_sSrcAux = 通道名(如 "CAN0")
|
||||
// 上行 m_dfVal2 = 原始帧信息字节 byte0(bit7 FF / bit6 RTR / bit3~0 DLC)
|
||||
// 下行 m_sKey = "CAN_TX_0x%08X",m_sVal = 二进制 data,m_sSrcAux = 目标通道名
|
||||
// m_nID 不使用(MOOS 内部消息序号)
|
||||
//
|
||||
// 下行通道回退规则(m_sSrcAux 为空时):
|
||||
// 1) 配置了 default_channel 且命中 -> 用该通道
|
||||
// 2) 仅配置了单通道 -> 用该通道
|
||||
// 3) 多通道且无 default_channel -> 告警丢弃
|
||||
// m_sSrcAux 非空但未命中任何通道 -> 告警丢弃
|
||||
//
|
||||
// 每帧(上行)同时落库 SQLite(can_frame 表,配置项 dbpath);
|
||||
// 下行帧仅日志记录(can_frame 表无方向列,保持旧库兼容)。
|
||||
//============================================================================
|
||||
@@ -49,23 +64,41 @@ protected:
|
||||
void registerVariables();
|
||||
|
||||
private:
|
||||
// 收帧回调(CanEndpoint 接收线程调用)
|
||||
void handleFrame(uint8_t frameInfo, uint32_t id, const uint8_t* data, int dlc);
|
||||
// 通道配置(.moos 重复行 channel = name,host,port)
|
||||
struct ChannelCfg {
|
||||
std::string name;
|
||||
std::string host;
|
||||
long port = 0;
|
||||
};
|
||||
|
||||
// 下行指令处理(OnNewMail 调用):CAN_TX_0x%08X -> CanEndpoint 发送
|
||||
// 运行中的通道(配置 + 独立 TCP 连接)
|
||||
struct Channel {
|
||||
ChannelCfg cfg;
|
||||
CanEndpoint* endpoint = nullptr;
|
||||
};
|
||||
|
||||
// 收帧回调(CanEndpoint 接收线程调用)
|
||||
void handleFrame(const std::string& channel, uint8_t frameInfo,
|
||||
uint32_t id, const uint8_t* data, int dlc);
|
||||
|
||||
// 下行指令处理(OnNewMail 调用):CAN_TX_0x%08X -> 按通道路由发送
|
||||
void handleTxMessage(CMOOSMsg& msg);
|
||||
|
||||
// 按通道名查找运行通道;未命中返回 nullptr
|
||||
Channel* findChannel(const std::string& name);
|
||||
|
||||
// 下行目标通道解析(含回退规则);返回通道指针,nullptr 表示丢弃
|
||||
Channel* resolveTxChannel(const std::string& srcAux);
|
||||
|
||||
// 配置
|
||||
std::string m_canHost = "192.168.0.222";
|
||||
long m_canPort = 4001;
|
||||
std::string m_channelName = "CAN0"; // 写入 m_sSrcAux
|
||||
std::string m_dbPath = "pCanBridge_data.db"; // SQLite 路径(moos 配置项 dbpath)
|
||||
std::vector<Channel> m_channels;
|
||||
std::string m_defaultChannel; // default_channel(可空)
|
||||
std::string m_dbPath = "pCanBridge_data.db"; // SQLite 路径(moos 配置项 dbpath)
|
||||
|
||||
// 组件
|
||||
CanEndpoint* m_endpoint = nullptr;
|
||||
CanDbStore* m_db = nullptr;
|
||||
std::atomic<unsigned long> m_notifyCount{0};
|
||||
std::atomic<unsigned long> m_txCount{0};
|
||||
CanDbStore* m_db = nullptr;
|
||||
std::atomic<unsigned long> m_txCount{0}; // MOOS 下行接收总数
|
||||
std::atomic<unsigned long> m_txDropCount{0}; // 下行因通道解析失败丢弃数
|
||||
};
|
||||
|
||||
} // namespace canbridge
|
||||
|
||||
Reference in New Issue
Block a user