Files
H100PowerManger/src/pCanBridge/CanDbStore.h
T
zjk b547772709 新增 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、无丢帧。
2026-08-31 19:14:59 +08:00

68 lines
2.1 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_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