Files
H100PowerManger/src/pCanBridge/CanBridge.h
T
zjk 67e732045a 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 通过。
2026-09-01 21:23:52 +08:00

107 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef PCANBRIDGE_CAN_BRIDGE_H
#define PCANBRIDGE_CAN_BRIDGE_H
#define UNIX
#include "MOOS/libMOOS/Thirdparty/AppCasting/AppCastingMOOSApp.h"
#include "CanEndpoint.h"
#include "CanDbStore.h"
#include <atomic>
#include <string>
#include <vector>
namespace canbridge {
//============================================================================
// CanBridge:CAN <-> MOOSDB 多通道双向透传桥(MOOS 应用外壳)。
//
// 通道配置(.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
//
// 数据流(下行,BCU 断路器/继电器控制等):
// MOOS "CAN_TX_0x%08X"(二进制数据域,dlc<=8)
// -> OnNewMail 解析 CAN ID 与数据
// -> 按消息 m_sSrcAux(目标通道名)路由到对应通道的 CanEndpoint
// -> CanEndpoint::sendFrame(该通道 TCP 连接写出 13 字节帧)
// -> CANET -> CAN 总线
//
// 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 表无方向列,保持旧库兼容)。
//============================================================================
class CanBridge : public AppCastingMOOSApp {
public:
CanBridge();
~CanBridge();
protected:
bool OnNewMail(MOOSMSG_LIST &NewMail);
bool Iterate();
bool OnConnectToServer();
bool OnStartUp();
bool buildReport();
void registerVariables();
private:
// 通道配置(.moos 重复行 channel = name,host,port)
struct ChannelCfg {
std::string name;
std::string host;
long port = 0;
};
// 运行中的通道(配置 + 独立 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::vector<Channel> m_channels;
std::string m_defaultChannel; // default_channel(可空)
std::string m_dbPath = "pCanBridge_data.db"; // SQLite 路径(moos 配置项 dbpath)
// 组件
CanDbStore* m_db = nullptr;
std::atomic<unsigned long> m_txCount{0}; // MOOS 下行接收总数
std::atomic<unsigned long> m_txDropCount{0}; // 下行因通道解析失败丢弃数
};
} // namespace canbridge
#endif // PCANBRIDGE_CAN_BRIDGE_H