新增 pCanBridge:USBCAN-8E-U CAN->MOOSDB 透传桥 + SQLite 落库

新应用 src/pCanBridge(独立 MOOS App,单通道):
- CanEndpoint:TCP Client 连接 CANET/USBCAN-8E-U 工作端口
  (目标 IP/端口可配置,默认 192.168.0.222:4001=CAN0),
  接收线程流式缓冲按 13 字节切帧,过滤无效 DLC(>8),
  断线自动重连(非阻塞 connect+超时 / SO_RCVTIMEO 读超时)。
- 帧协议(CANET-8E-U 手册 8.1):byte0=帧信息(bit7 FF/bit6 RTR/
  bit3~0 DLC),byte1~4=ID 大端,byte5~12=数据。
- MOOS 映射:变量名 CAN_0x%08X=CAN ID(不缩减),m_sVal=二进制
  data(逐帧透传不限流),m_sSrcAux=通道名(can_channel_name),
  m_dfVal2=原始帧信息字节(用于区分标准/扩展、数据/远程帧)。
- CanDbStore:每帧落库 SQLite(can_frame 表:time/channel/
  frame_info/can_id/dlc/hex,含 time、can_id 索引),参考 pCCU
  DbStore:预处理语句 + WAL + synchronous=NORMAL,路径由 dbpath
  配置;复用 pPowerManger 的 sqlite3 amalgamation。
- AppCast 输出连接状态/收帧/发布/落库统计。

配套:
- missions/h100.moos 新增 pCanBridge 配置块(板卡 dbpath 指向
  data 目录)。
- build-board.sh / deploy.sh 支持 pCanBridge:产物部署 +
  pCanBridge.service 安装,服务列表加入第 5 个服务。
- .gitignore 忽略 bin/pCanBridge 与本机默认数据库。

已验证(板卡 192.168.0.223 实测):服务 active,连接设备正常,
~60 帧/s 透传,落库 9000+ 行 integrity ok、无丢帧。
This commit is contained in:
zjk
2026-08-31 19:14:59 +08:00
parent 7e4d08808a
commit b547772709
16 changed files with 1048 additions and 17 deletions
+62
View File
@@ -0,0 +1,62 @@
#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>
namespace canbridge {
//============================================================================
// CanBridge:CAN -> MOOSDB 透传桥(MOOS 应用外壳)。
//
// 数据流:
// USBCAN-8E-U (TCP Server, 默认 192.168.0.222:4001 = CAN0)
// -> CanEndpoint(TCP Client,13 字节切帧)
// -> handleFrame() 解析
// -> Notify 到 MOOSDB
//
// 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)
// m_nID 不使用(MOOS 内部消息序号)
//
// 每帧同时落库 SQLite(can_frame 表,配置项 dbpath)。
//============================================================================
class CanBridge : public AppCastingMOOSApp {
public:
CanBridge();
~CanBridge();
protected:
bool OnNewMail(MOOSMSG_LIST &NewMail);
bool Iterate();
bool OnConnectToServer();
bool OnStartUp();
bool buildReport();
void registerVariables();
private:
// 收帧回调(CanEndpoint 接收线程调用)
void handleFrame(uint8_t frameInfo, uint32_t id, const uint8_t* data, int dlc);
// 配置
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)
// 组件
CanEndpoint* m_endpoint = nullptr;
CanDbStore* m_db = nullptr;
std::atomic<unsigned long> m_notifyCount{0};
};
} // namespace canbridge
#endif // PCANBRIDGE_CAN_BRIDGE_H