新增 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:
@@ -0,0 +1,67 @@
|
||||
#ifndef PCANBRIDGE_CAN_DB_STORE_H
|
||||
#define PCANBRIDGE_CAN_DB_STORE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
struct sqlite3;
|
||||
struct sqlite3_stmt;
|
||||
|
||||
namespace canbridge {
|
||||
|
||||
//============================================================================
|
||||
// CanDbStore:CAN 帧 SQLite 存储。
|
||||
//
|
||||
// 设计参考 src/pCCU/store/DbStore(原始帧日志模式):
|
||||
// - 收到的每个 CAN 帧逐条落库(can_frame 表),
|
||||
// 存原始帧信息/ID/DLC/十六进制数据,语义解析交给下游。
|
||||
// - 预处理语句 + WAL + synchronous=NORMAL,满足 ~60 帧/秒持续写入。
|
||||
// - 内部互斥锁:接收线程写入,Iterate 线程查询/统计。
|
||||
// 复用仓库内 src/pPowerManger/sqlit3/sqlite3.c 与 sqlite3.h。
|
||||
//============================================================================
|
||||
|
||||
struct CanFrameRow {
|
||||
long long id;
|
||||
double time; // unix 时间(含小数秒)
|
||||
std::string channel; // 通道名(CAN0~CAN7)
|
||||
int frameInfo; // 原始帧信息字节 byte0(bit7 FF / bit6 RTR / bit3~0 DLC)
|
||||
uint32_t canId; // CAN ID
|
||||
int dlc;
|
||||
std::string hex; // 数据十六进制
|
||||
};
|
||||
|
||||
class CanDbStore {
|
||||
public:
|
||||
explicit CanDbStore(const std::string& dbPath);
|
||||
~CanDbStore();
|
||||
|
||||
bool open();
|
||||
void close();
|
||||
bool isOpen() const { return m_db != nullptr; }
|
||||
std::string lastError() const { return m_lastError; }
|
||||
|
||||
// 收帧落库(CanEndpoint 接收线程调用,内部加锁)
|
||||
void onFrame(const std::string& channel, uint8_t frameInfo,
|
||||
uint32_t canId, const uint8_t* data, int dlc);
|
||||
|
||||
// 查询最近 N 条(canId=0 表示不过滤;limit<=0 表示默认 100)
|
||||
std::vector<CanFrameRow> queryRecent(uint32_t canId, int limit);
|
||||
|
||||
long long count() const;
|
||||
|
||||
private:
|
||||
bool exec(const char* sql);
|
||||
bool prepareInsert();
|
||||
|
||||
std::string m_dbPath;
|
||||
sqlite3* m_db = nullptr;
|
||||
sqlite3_stmt* m_stmtInsert = nullptr;
|
||||
mutable std::mutex m_mutex;
|
||||
std::string m_lastError;
|
||||
};
|
||||
|
||||
} // namespace canbridge
|
||||
|
||||
#endif // PCANBRIDGE_CAN_DB_STORE_H
|
||||
Reference in New Issue
Block a user