Initial commit: Complete USB2CAN cross-platform framework

Features:
- Cross-platform support (Windows/Linux/macOS)
- CAN and CANFD protocol support
- USB communication (WinUSB/libusb)
- Device management and configuration
- Message transmission and reception
- Filter configuration
- CMake build system
- Comprehensive examples and tests
This commit is contained in:
2025-09-11 17:56:26 +08:00
commit 81bee50cd9
37 changed files with 5536 additions and 0 deletions

265
include/api/Usb2Can.h Normal file
View File

@@ -0,0 +1,265 @@
/**
* @file Usb2Can.h
* @brief USB2CAN应用接口定义
*/
#ifndef USB2CAN_API_H
#define USB2CAN_API_H
#include "../device/DeviceManager.h"
#include "../device/Usb2CanDevice.h"
#include "../can/CanMessage.h"
#include "../platform/Platform.h"
#include <memory>
#include <vector>
namespace usb2can {
/**
* @brief USB2CAN主类提供简化的API接口
*/
class Usb2Can {
public:
/**
* @brief 构造函数
*/
Usb2Can();
/**
* @brief 析构函数
*/
~Usb2Can();
/**
* @brief 初始化USB2CAN框架
* @return 初始化成功返回true否则返回false
*/
bool initialize();
/**
* @brief 扫描USB2CAN设备
* @return 设备数量
*/
int scanDevices();
/**
* @brief 获取设备数量
* @return 设备数量
*/
int getDeviceCount() const;
/**
* @brief 获取设备类型
* @param deviceIndex 设备索引
* @return 设备类型0表示常规CAN1表示CANFD失败返回-1
*/
int getDeviceType(int deviceIndex) const;
/**
* @brief 获取设备主频
* @param deviceIndex 设备索引
* @return 设备主频失败返回0
*/
uint32_t getDeviceClockFrequency(int deviceIndex) const;
/**
* @brief 打开设备
* @param deviceIndex 设备索引
* @return 打开成功返回true否则返回false
*/
bool openDevice(int deviceIndex);
/**
* @brief 关闭设备
* @param deviceIndex 设备索引
* @return 关闭成功返回true否则返回false
*/
bool closeDevice(int deviceIndex);
/**
* @brief 读取设备信息
* @param deviceIndex 设备索引
* @param[out] info 设备信息
* @return 读取成功返回true否则返回false
*/
bool readDeviceInfo(int deviceIndex, device::Usb2CanDeviceInfo& info);
/**
* @brief 设置CAN过滤器
* @param deviceIndex 设备索引
* @param filterId 过滤器ID
* @param type 过滤器类型
* @param id 过滤ID
* @param mask 过滤掩码
* @param enable 是否启用过滤器
* @return 设置成功返回true否则返回false
*/
bool setFilter(int deviceIndex, uint8_t filterId, uint8_t type, uint32_t id, uint32_t mask, bool enable);
/**
* @brief 复位设备
* @param deviceIndex 设备索引
* @return 复位成功返回true否则返回false
*/
bool reset(int deviceIndex);
/**
* @brief 获取设备状态
* @param deviceIndex 设备索引
* @param[out] status 设备状态
* @return 获取成功返回true否则返回false
*/
bool getStatus(int deviceIndex, can::CanStatus& status);
/**
* @brief 初始化CAN控制器
* @param deviceIndex 设备索引
* @param config CAN配置
* @return 初始化成功返回true否则返回false
*/
bool initCan(int deviceIndex, const can::CanConfig& config);
/**
* @brief 发送CAN消息
* @param deviceIndex 设备索引
* @param message CAN消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool transmit(int deviceIndex, const can::CanMessage& message, int timeout = 1000);
/**
* @brief 批量发送CAN消息
* @param deviceIndex 设备索引
* @param messages CAN消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
int transmit(int deviceIndex, const can::CanMessage* messages, int count, int timeout = 1000);
/**
* @brief 定时发送CAN消息
* @param deviceIndex 设备索引
* @param messages CAN消息列表
* @param count 消息数量
* @param[out] txItems 实际发送的消息数量
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool transmitRt(int deviceIndex, const can::CanMessage* messages, int count, unsigned int* txItems, int timeout = 1000);
/**
* @brief 获取CAN接收缓冲区中的消息数量
* @param deviceIndex 设备索引
* @return 接收缓冲区中的消息数量,失败返回-1
*/
int getReceiveNum(int deviceIndex);
/**
* @brief 接收CAN消息
* @param deviceIndex 设备索引
* @param[out] message CAN消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
bool receive(int deviceIndex, can::CanMessage& message, int timeout = 1000);
/**
* @brief 批量接收CAN消息
* @param deviceIndex 设备索引
* @param[out] messages CAN消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
int receive(int deviceIndex, can::CanMessage* messages, int count, int timeout = 1000);
/**
* @brief 初始化CANFD控制器
* @param deviceIndex 设备索引
* @param config CANFD配置
* @return 初始化成功返回true否则返回false
*/
bool initCanFd(int deviceIndex, const can::CanFdConfig& config);
/**
* @brief 发送CANFD消息
* @param deviceIndex 设备索引
* @param message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool transmitFd(int deviceIndex, const can::CanFdMessage& message, int timeout = 1000);
/**
* @brief 批量发送CANFD消息
* @param deviceIndex 设备索引
* @param messages CANFD消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
int transmitFd(int deviceIndex, const can::CanFdMessage* messages, int count, int timeout = 1000);
/**
* @brief 定时发送CANFD消息
* @param deviceIndex 设备索引
* @param messages CANFD消息列表
* @param count 消息数量
* @param[out] txItems 实际发送的消息数量
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool transmitFdRt(int deviceIndex, const can::CanFdMessage* messages, int count, unsigned int* txItems, int timeout = 1000);
/**
* @brief 获取CANFD接收缓冲区中的消息数量
* @param deviceIndex 设备索引
* @return 接收缓冲区中的消息数量,失败返回-1
*/
int getFdReceiveNum(int deviceIndex);
/**
* @brief 接收CANFD消息
* @param deviceIndex 设备索引
* @param[out] message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
bool receiveFd(int deviceIndex, can::CanFdMessage& message, int timeout = 1000);
/**
* @brief 批量接收CANFD消息
* @param deviceIndex 设备索引
* @param[out] messages CANFD消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
int receiveFd(int deviceIndex, can::CanFdMessage* messages, int count, int timeout = 1000);
/**
* @brief 注册热插拔回调函数
* @param callback 回调函数
* @return 注册成功返回true否则返回false
*/
bool registerHotplugCallback(void (*callback)(void));
/**
* @brief 注销热插拔回调函数
* @return 注销成功返回true否则返回false
*/
bool unregisterHotplugCallback();
private:
std::unique_ptr<platform::Platform> platform_; ///< 平台实例
std::unique_ptr<device::DeviceManager> deviceManager_; ///< 设备管理器
std::vector<std::unique_ptr<device::Usb2CanDevice>> openedDevices_; ///< 已打开的设备列表
bool isInitialized_; ///< 框架是否已初始化
};
} // namespace usb2can
#endif // USB2CAN_API_H

131
include/can/CanController.h Normal file
View File

@@ -0,0 +1,131 @@
/**
* @file CanController.h
* @brief CAN控制器接口定义
*/
#ifndef USB2CAN_CAN_CONTROLLER_H
#define USB2CAN_CAN_CONTROLLER_H
#include "CanMessage.h"
#include "../usb/UsbDevice.h"
#include <vector>
namespace usb2can {
namespace can {
/**
* @brief CAN控制器接口类
*/
class CanController {
public:
virtual ~CanController() = default;
/**
* @brief 初始化CAN控制器
* @param usbDevice USB设备
* @param config CAN配置
* @return 初始化成功返回true否则返回false
*/
virtual bool initialize(usb::UsbDevice* usbDevice, const CanConfig& config) = 0;
/**
* @brief 关闭CAN控制器
*/
virtual void shutdown() = 0;
/**
* @brief 检查CAN控制器是否已初始化
* @return 已初始化返回true否则返回false
*/
virtual bool isInitialized() const = 0;
/**
* @brief 发送CAN消息
* @param message CAN消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
virtual bool sendMessage(const CanMessage& message, int timeout = 1000) = 0;
/**
* @brief 接收CAN消息
* @param[out] message CAN消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
virtual bool receiveMessage(CanMessage& message, int timeout = 1000) = 0;
/**
* @brief 批量发送CAN消息
* @param messages CAN消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
virtual int sendMessages(const CanMessage* messages, int count, int timeout = 1000) = 0;
/**
* @brief 批量接收CAN消息
* @param[out] messages CAN消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
virtual int receiveMessages(CanMessage* messages, int count, int timeout = 1000) = 0;
/**
* @brief 获取接收缓冲区中的消息数量
* @return 接收缓冲区中的消息数量,失败返回-1
*/
virtual int getReceiveQueueCount() = 0;
/**
* @brief 设置CAN过滤器
* @param filterId 过滤器ID
* @param type 过滤器类型
* @param id 过滤ID
* @param mask 过滤掩码
* @param enable 是否启用过滤器
* @return 设置成功返回true否则返回false
*/
virtual bool setFilter(uint8_t filterId, uint8_t type, uint32_t id, uint32_t mask, bool enable) = 0;
/**
* @brief 复位CAN控制器
* @return 复位成功返回true否则返回false
*/
virtual bool reset() = 0;
/**
* @brief 获取CAN控制器状态
* @param[out] status CAN状态
* @return 获取成功返回true否则返回false
*/
virtual bool getStatus(CanStatus& status) = 0;
/**
* @brief 获取CAN控制器配置
* @param[out] config CAN配置
* @return 获取成功返回true否则返回false
*/
virtual bool getConfig(CanConfig& config) = 0;
/**
* @brief 设置CAN控制器配置
* @param config CAN配置
* @return 设置成功返回true否则返回false
*/
virtual bool setConfig(const CanConfig& config) = 0;
/**
* @brief 创建CAN控制器实例
* @return CAN控制器实例
*/
static CanController* createCanController();
};
} // namespace can
} // namespace usb2can
#endif // USB2CAN_CAN_CONTROLLER_H

View File

@@ -0,0 +1,131 @@
/**
* @file CanFdController.h
* @brief CANFD控制器接口定义
*/
#ifndef USB2CAN_CAN_FD_CONTROLLER_H
#define USB2CAN_CAN_FD_CONTROLLER_H
#include "CanMessage.h"
#include "../usb/UsbDevice.h"
#include <vector>
namespace usb2can {
namespace can {
/**
* @brief CANFD控制器接口类
*/
class CanFdController {
public:
virtual ~CanFdController() = default;
/**
* @brief 初始化CANFD控制器
* @param usbDevice USB设备
* @param config CANFD配置
* @return 初始化成功返回true否则返回false
*/
virtual bool initialize(usb::UsbDevice* usbDevice, const CanFdConfig& config) = 0;
/**
* @brief 关闭CANFD控制器
*/
virtual void shutdown() = 0;
/**
* @brief 检查CANFD控制器是否已初始化
* @return 已初始化返回true否则返回false
*/
virtual bool isInitialized() const = 0;
/**
* @brief 发送CANFD消息
* @param message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
virtual bool sendMessage(const CanFdMessage& message, int timeout = 1000) = 0;
/**
* @brief 接收CANFD消息
* @param[out] message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
virtual bool receiveMessage(CanFdMessage& message, int timeout = 1000) = 0;
/**
* @brief 批量发送CANFD消息
* @param messages CANFD消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
virtual int sendMessages(const CanFdMessage* messages, int count, int timeout = 1000) = 0;
/**
* @brief 批量接收CANFD消息
* @param[out] messages CANFD消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
virtual int receiveMessages(CanFdMessage* messages, int count, int timeout = 1000) = 0;
/**
* @brief 获取接收缓冲区中的消息数量
* @return 接收缓冲区中的消息数量,失败返回-1
*/
virtual int getReceiveQueueCount() = 0;
/**
* @brief 设置CANFD过滤器
* @param filterId 过滤器ID
* @param type 过滤器类型
* @param id 过滤ID
* @param mask 过滤掩码
* @param enable 是否启用过滤器
* @return 设置成功返回true否则返回false
*/
virtual bool setFilter(uint8_t filterId, uint8_t type, uint32_t id, uint32_t mask, bool enable) = 0;
/**
* @brief 复位CANFD控制器
* @return 复位成功返回true否则返回false
*/
virtual bool reset() = 0;
/**
* @brief 获取CANFD控制器状态
* @param[out] status CAN状态
* @return 获取成功返回true否则返回false
*/
virtual bool getStatus(CanStatus& status) = 0;
/**
* @brief 获取CANFD控制器配置
* @param[out] config CANFD配置
* @return 获取成功返回true否则返回false
*/
virtual bool getConfig(CanFdConfig& config) = 0;
/**
* @brief 设置CANFD控制器配置
* @param config CANFD配置
* @return 设置成功返回true否则返回false
*/
virtual bool setConfig(const CanFdConfig& config) = 0;
/**
* @brief 创建CANFD控制器实例
* @return CANFD控制器实例
*/
static CanFdController* createCanFdController();
};
} // namespace can
} // namespace usb2can
#endif // USB2CAN_CAN_FD_CONTROLLER_H

201
include/can/CanMessage.h Normal file
View File

@@ -0,0 +1,201 @@
/**
* @file CanMessage.h
* @brief CAN消息结构定义
*/
#ifndef USB2CAN_CAN_MESSAGE_H
#define USB2CAN_CAN_MESSAGE_H
#include <cstdint>
#include <cstring>
namespace usb2can {
namespace can {
/**
* @brief CAN帧类型枚举
*/
enum class CanFrameType {
STANDARD = 0, ///< 标准帧
EXTENDED = 1, ///< 扩展帧
REMOTE = 2 ///< 远程帧
};
/**
* @brief CAN工作模式枚举
*/
enum class CanMode {
NORMAL = 0, ///< 正常模式
LOOPBACK = 1, ///< 环回模式
SILENT = 2, ///< 静默模式
SILENT_LOOPBACK = 3 ///< 静默环回模式
};
/**
* @brief CAN配置结构体
*/
struct CanConfig {
uint32_t baudrate; ///< 波特率
uint16_t prescaler; ///< 预分频器
uint8_t tseg1; ///< 时间段1
uint8_t tseg2; ///< 时间段2
uint8_t sjw; ///< 同步跳转宽度
uint8_t config; ///< 配置信息0x01接通内部电阻 0x02离线唤醒 0x04自动重传
CanMode mode; ///< 工作模式
uint8_t reserved; ///< 保留
/**
* @brief 构造函数
*/
CanConfig() : baudrate(500000), prescaler(0), tseg1(0), tseg2(0), sjw(0),
config(0), mode(CanMode::NORMAL), reserved(0) {}
};
/**
* @brief CAN消息结构体
*/
struct CanMessage {
uint32_t id; ///< 报文ID
uint32_t timestamp; ///< 微秒级时间戳
CanFrameType frameType; ///< 帧类型
uint8_t dataLength; ///< 有效字节数
uint8_t data[8]; ///< 报文数据
bool isExtended; ///< 扩展帧标识false标准帧, true扩展帧
bool isRemote; ///< 远程帧标识false数据帧, true远程帧
uint8_t busStatus; ///< 总线状态
uint8_t errorStatus; ///< 错误状态
uint8_t txErrorCounter; ///< 发送错误计数
uint8_t rxErrorCounter; ///< 接收错误计数
/**
* @brief 构造函数
*/
CanMessage() : id(0), timestamp(0), frameType(CanFrameType::STANDARD),
dataLength(0), isExtended(false), isRemote(false),
busStatus(0), errorStatus(0), txErrorCounter(0), rxErrorCounter(0) {
memset(data, 0, sizeof(data));
}
/**
* @brief 设置数据
* @param data 数据缓冲区
* @param length 数据长度
*/
void setData(const uint8_t* data, uint8_t length) {
dataLength = (length > 8) ? 8 : length;
memcpy(this->data, data, dataLength);
}
/**
* @brief 获取数据长度码DLC
* @return 数据长度码
*/
uint8_t getDlc() const {
return dataLength;
}
};
/**
* @brief CANFD配置结构体
*/
struct CanFdConfig {
uint32_t nominalBaudrate; ///< 常规波特率
uint32_t dataBaudrate; ///< 数据波特率
uint16_t nominalPrescaler; ///< 常规波特率预分频器
uint8_t nominalTseg1; ///< 常规波特率时间段1
uint8_t nominalTseg2; ///< 常规波特率时间段2
uint8_t nominalSjw; ///< 常规波特率同步跳转宽度
uint8_t dataPrescaler; ///< 数据波特率预分频器
uint8_t dataTseg1; ///< 数据波特率时间段1
uint8_t dataTseg2; ///< 数据波特率时间段2
uint8_t dataSjw; ///< 数据波特率同步跳转宽度
uint8_t config; ///< 配置信息0x01接通内部电阻 0x02离线唤醒 0x04自动重传
CanMode mode; ///< 工作模式
uint8_t canType; ///< CAN模式0 CAN, 1 ISO CANFD, 2 Non-ISO CANFD
/**
* @brief 构造函数
*/
CanFdConfig() : nominalBaudrate(500000), dataBaudrate(2000000),
nominalPrescaler(0), nominalTseg1(0), nominalTseg2(0), nominalSjw(0),
dataPrescaler(0), dataTseg1(0), dataTseg2(0), dataSjw(0),
config(0), mode(CanMode::NORMAL), canType(1) {}
};
/**
* @brief CANFD消息结构体
*/
struct CanFdMessage {
uint32_t id; ///< 报文ID
uint32_t timestamp; ///< 微秒级时间戳
CanFrameType frameType; ///< 帧类型
uint8_t dlc; ///< 数据长度码DLC
uint8_t dataLength; ///< 实际数据长度
uint8_t data[64]; ///< 报文数据
bool isExtended; ///< 扩展帧标识false标准帧, true扩展帧
bool isRemote; ///< 远程帧标识false数据帧, true远程帧
uint8_t busStatus; ///< 总线状态
uint8_t errorStatus; ///< 错误状态
uint8_t txErrorCounter; ///< 发送错误计数
uint8_t rxErrorCounter; ///< 接收错误计数
/**
* @brief 构造函数
*/
CanFdMessage() : id(0), timestamp(0), frameType(CanFrameType::STANDARD),
dlc(0), dataLength(0), isExtended(false), isRemote(false),
busStatus(0), errorStatus(0), txErrorCounter(0), rxErrorCounter(0) {
memset(data, 0, sizeof(data));
}
/**
* @brief 设置数据
* @param data 数据缓冲区
* @param length 数据长度
*/
void setData(const uint8_t* data, uint8_t length) {
dataLength = (length > 64) ? 64 : length;
memcpy(this->data, data, dataLength);
// 根据数据长度设置DLC
if (dataLength <= 8) {
dlc = dataLength;
} else if (dataLength <= 12) {
dlc = 9;
} else if (dataLength <= 16) {
dlc = 10;
} else if (dataLength <= 20) {
dlc = 11;
} else if (dataLength <= 24) {
dlc = 12;
} else if (dataLength <= 32) {
dlc = 13;
} else if (dataLength <= 48) {
dlc = 14;
} else {
dlc = 15;
}
}
};
/**
* @brief CAN状态结构体
*/
struct CanStatus {
uint8_t busStatus; ///< 总线状态
uint8_t errorStatus; ///< 错误状态
uint8_t txErrorCounter; ///< 发送错误计数
uint8_t rxErrorCounter; ///< 接收错误计数
uint32_t timestamp; ///< 产生状态时的时间戳
/**
* @brief 构造函数
*/
CanStatus() : busStatus(0), errorStatus(0), txErrorCounter(0),
rxErrorCounter(0), timestamp(0) {}
};
} // namespace can
} // namespace usb2can
#endif // USB2CAN_CAN_MESSAGE_H

View File

@@ -0,0 +1,107 @@
/**
* @file DeviceManager.h
* @brief 设备管理器类定义
*/
#ifndef USB2CAN_DEVICE_MANAGER_H
#define USB2CAN_DEVICE_MANAGER_H
#include "Usb2CanDevice.h"
#include "../platform/Platform.h"
#include <vector>
#include <memory>
namespace usb2can {
namespace device {
/**
* @brief 设备管理器类
*/
class DeviceManager {
public:
/**
* @brief 构造函数
* @param platform 平台实例
*/
explicit DeviceManager(platform::Platform* platform);
/**
* @brief 析构函数
*/
~DeviceManager();
/**
* @brief 扫描USB2CAN设备
* @return 设备数量
*/
int scanDevices();
/**
* @brief 获取设备数量
* @return 设备数量
*/
int getDeviceCount() const;
/**
* @brief 获取设备信息
* @param deviceIndex 设备索引
* @param[out] info 设备信息
* @return 获取成功返回true否则返回false
*/
bool getDeviceInfo(int deviceIndex, Usb2CanDeviceInfo& info);
/**
* @brief 打开设备
* @param deviceIndex 设备索引
* @return 设备实例失败返回nullptr
*/
Usb2CanDevice* openDevice(int deviceIndex);
/**
* @brief 关闭设备
* @param device 设备实例
*/
void closeDevice(Usb2CanDevice* device);
/**
* @brief 获取所有设备信息
* @return 设备信息列表
*/
std::vector<Usb2CanDeviceInfo> getAllDevicesInfo() const;
/**
* @brief 注册热插拔回调函数
* @param callback 回调函数
* @return 注册成功返回true否则返回false
*/
bool registerHotplugCallback(void (*callback)(void));
/**
* @brief 注销热插拔回调函数
* @return 注销成功返回true否则返回false
*/
bool unregisterHotplugCallback();
private:
platform::Platform* platform_; ///< 平台实例
std::vector<Usb2CanDeviceInfo> deviceInfos_; ///< 设备信息列表
std::vector<std::unique_ptr<Usb2CanDevice>> openedDevices_; ///< 已打开的设备列表
void (*hotplugCallback_)(void); ///< 热插拔回调函数
bool hotplugCallbackRegistered_; ///< 热插拔回调是否已注册
/**
* @brief 热插拔事件处理函数
*/
static void hotplugEventHandler(void* context);
/**
* @brief 更新设备列表
*/
void updateDeviceList();
};
} // namespace device
} // namespace usb2can
#endif // USB2CAN_DEVICE_MANAGER_H

View File

@@ -0,0 +1,268 @@
/**
* @file Usb2CanDevice.h
* @brief USB2CAN设备类定义
*/
#ifndef USB2CAN_USB2CAN_DEVICE_H
#define USB2CAN_USB2CAN_DEVICE_H
#include "../usb/UsbDevice.h"
#include "../can/CanController.h"
#include "../can/CanFdController.h"
#include "../can/CanMessage.h"
#include "../platform/Platform.h"
#include <string>
#include <memory>
namespace usb2can {
namespace device {
/**
* @brief USB2CAN设备类型枚举
*/
enum class DeviceType {
CAN, ///< 常规CAN设备
CANFD ///< CANFD设备
};
/**
* @brief USB2CAN设备信息结构体
*/
struct Usb2CanDeviceInfo {
DeviceType type; ///< 设备类型
uint16_t vendorId; ///< 供应商ID
uint16_t productId; ///< 产品ID
std::string manufacturer; ///< 制造商
std::string productName; ///< 产品名称
std::string serialNumber; ///< 序列号
std::string hwVersion; ///< 硬件版本
std::string fwVersion; ///< 软件版本
std::string manufactureDate; ///< 生产日期
std::string devicePath; ///< 设备路径
uint32_t clockFrequency; ///< 主频
int deviceIndex; ///< 设备索引
};
/**
* @brief USB2CAN设备类
*/
class Usb2CanDevice {
public:
/**
* @brief 构造函数
* @param platform 平台实例
* @param deviceIndex 设备索引
*/
Usb2CanDevice(platform::Platform* platform, int deviceIndex);
/**
* @brief 析构函数
*/
~Usb2CanDevice();
/**
* @brief 打开设备
* @return 打开成功返回true否则返回false
*/
bool open();
/**
* @brief 关闭设备
*/
void close();
/**
* @brief 检查设备是否已打开
* @return 设备已打开返回true否则返回false
*/
bool isOpen() const;
/**
* @brief 获取设备信息
* @param[out] info 设备信息
* @return 获取成功返回true否则返回false
*/
bool getDeviceInfo(Usb2CanDeviceInfo& info);
/**
* @brief 获取设备类型
* @return 设备类型
*/
DeviceType getDeviceType() const;
/**
* @brief 获取设备索引
* @return 设备索引
*/
int getDeviceIndex() const;
/**
* @brief 获取设备路径
* @return 设备路径
*/
std::string getDevicePath() const;
/**
* @brief 初始化CAN控制器
* @param config CAN配置
* @return 初始化成功返回true否则返回false
*/
bool initCan(const can::CanConfig& config);
/**
* @brief 初始化CANFD控制器
* @param config CANFD配置
* @return 初始化成功返回true否则返回false
*/
bool initCanFd(const can::CanFdConfig& config);
/**
* @brief 发送CAN消息
* @param message CAN消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool sendCanMessage(const can::CanMessage& message, int timeout = 1000);
/**
* @brief 接收CAN消息
* @param[out] message CAN消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
bool receiveCanMessage(can::CanMessage& message, int timeout = 1000);
/**
* @brief 批量发送CAN消息
* @param messages CAN消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
int sendCanMessages(const can::CanMessage* messages, int count, int timeout = 1000);
/**
* @brief 批量接收CAN消息
* @param[out] messages CAN消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
int receiveCanMessages(can::CanMessage* messages, int count, int timeout = 1000);
/**
* @brief 发送CANFD消息
* @param message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 发送成功返回true否则返回false
*/
bool sendCanFdMessage(const can::CanFdMessage& message, int timeout = 1000);
/**
* @brief 接收CANFD消息
* @param[out] message CANFD消息
* @param timeout 超时时间(毫秒)
* @return 接收成功返回true否则返回false
*/
bool receiveCanFdMessage(can::CanFdMessage& message, int timeout = 1000);
/**
* @brief 批量发送CANFD消息
* @param messages CANFD消息列表
* @param count 消息数量
* @param timeout 超时时间(毫秒)
* @return 实际发送的消息数量,失败返回-1
*/
int sendCanFdMessages(const can::CanFdMessage* messages, int count, int timeout = 1000);
/**
* @brief 批量接收CANFD消息
* @param[out] messages CANFD消息列表
* @param count 最大接收消息数量
* @param timeout 超时时间(毫秒)
* @return 实际接收的消息数量,失败返回-1
*/
int receiveCanFdMessages(can::CanFdMessage* messages, int count, int timeout = 1000);
/**
* @brief 获取CAN接收缓冲区中的消息数量
* @return 接收缓冲区中的消息数量,失败返回-1
*/
int getCanReceiveQueueCount();
/**
* @brief 获取CANFD接收缓冲区中的消息数量
* @return 接收缓冲区中的消息数量,失败返回-1
*/
int getCanFdReceiveQueueCount();
/**
* @brief 设置CAN过滤器
* @param filterId 过滤器ID
* @param type 过滤器类型
* @param id 过滤ID
* @param mask 过滤掩码
* @param enable 是否启用过滤器
* @return 设置成功返回true否则返回false
*/
bool setCanFilter(uint8_t filterId, uint8_t type, uint32_t id, uint32_t mask, bool enable);
/**
* @brief 设置CANFD过滤器
* @param filterId 过滤器ID
* @param type 过滤器类型
* @param id 过滤ID
* @param mask 过滤掩码
* @param enable 是否启用过滤器
* @return 设置成功返回true否则返回false
*/
bool setCanFdFilter(uint8_t filterId, uint8_t type, uint32_t id, uint32_t mask, bool enable);
/**
* @brief 复位CAN控制器
* @return 复位成功返回true否则返回false
*/
bool resetCan();
/**
* @brief 复位CANFD控制器
* @return 复位成功返回true否则返回false
*/
bool resetCanFd();
/**
* @brief 获取CAN控制器状态
* @param[out] status CAN状态
* @return 获取成功返回true否则返回false
*/
bool getCanStatus(can::CanStatus& status);
/**
* @brief 获取CANFD控制器状态
* @param[out] status CAN状态
* @return 获取成功返回true否则返回false
*/
bool getCanFdStatus(can::CanStatus& status);
private:
platform::Platform* platform_; ///< 平台实例
int deviceIndex_; ///< 设备索引
std::unique_ptr<usb::UsbDevice> usbDevice_; ///< USB设备
std::unique_ptr<can::CanController> canController_; ///< CAN控制器
std::unique_ptr<can::CanFdController> canFdController_; ///< CANFD控制器
Usb2CanDeviceInfo deviceInfo_; ///< 设备信息
bool isOpen_; ///< 设备是否已打开
DeviceType deviceType_; ///< 设备类型
/**
* @brief 初始化设备信息
* @return 初始化成功返回true否则返回false
*/
bool initDeviceInfo();
};
} // namespace device
} // namespace usb2can
#endif // USB2CAN_USB2CAN_DEVICE_H

View File

@@ -0,0 +1,77 @@
/**
* @file LinuxPlatform.h
* @brief Linux平台实现
*/
#ifndef USB2CAN_LINUX_PLATFORM_H
#define USB2CAN_LINUX_PLATFORM_H
#include "Platform.h"
#if defined(__linux__) || defined(__APPLE__)
#include <libusb.h>
#endif
namespace usb2can {
namespace platform {
/**
* @brief Linux平台实现类
*/
class LinuxPlatform : public Platform {
public:
LinuxPlatform();
~LinuxPlatform() override;
PlatformType getType() const override;
bool initialize() override;
std::vector<std::string> scanUsbDevices(uint16_t vendorId, uint16_t productId) override;
void* openUsbDevice(const std::string& devicePath) override;
bool closeUsbDevice(void* deviceHandle) override;
int writeUsbData(void* deviceHandle, const uint8_t* data, size_t size, int timeout) override;
int readUsbData(void* deviceHandle, uint8_t* data, size_t size, int timeout) override;
bool getDeviceInfo(void* deviceHandle, DeviceInfo& info) override;
private:
/**
* @brief Linux设备句柄结构体
*/
struct LinuxDeviceHandle {
libusb_device_handle* usbHandle; ///< USB设备句柄
std::string devicePath; ///< 设备路径
uint8_t inEndpoint; ///< 输入端点
uint8_t outEndpoint; ///< 输出端点
};
libusb_context* usbContext; ///< USB上下文
/**
* @brief 获取USB设备描述符
* @param usbHandle USB设备句柄
* @param descriptor 设备描述符
* @return 操作成功返回true否则返回false
*/
bool getUsbDeviceDescriptor(libusb_device_handle* usbHandle, libusb_device_descriptor& descriptor);
/**
* @brief 获取USB设备字符串描述符
* @param usbHandle USB设备句柄
* @param descIndex 描述符索引
* @return 字符串描述符内容
*/
std::string getUsbStringDescriptor(libusb_device_handle* usbHandle, uint8_t descIndex);
/**
* @brief 查找USB设备的端点
* @param usbHandle USB设备句柄
* @param inEndpoint 输入端点
* @param outEndpoint 输出端点
* @return 操作成功返回true否则返回false
*/
bool findUsbEndpoints(libusb_device_handle* usbHandle, uint8_t& inEndpoint, uint8_t& outEndpoint);
};
} // namespace platform
} // namespace usb2can
#endif // USB2CAN_LINUX_PLATFORM_H

113
include/platform/Platform.h Normal file
View File

@@ -0,0 +1,113 @@
/**
* @file Platform.h
* @brief 平台抽象层接口定义
*/
#ifndef USB2CAN_PLATFORM_H
#define USB2CAN_PLATFORM_H
#include <string>
#include <vector>
namespace usb2can {
namespace platform {
/**
* @brief 平台类型枚举
*/
enum class PlatformType {
WINDOWS, ///< Windows平台
LINUX ///< Linux平台
};
/**
* @brief 设备信息结构体
*/
struct DeviceInfo {
std::string hwType; ///< 设备型号
std::string serialNumber; ///< 设备序列号
std::string hwVersion; ///< 硬件版本
std::string fwVersion; ///< 软件版本
std::string manufactureDate; ///< 生产日期
};
/**
* @brief 平台抽象接口类
*/
class Platform {
public:
virtual ~Platform() = default;
/**
* @brief 获取平台类型
* @return 平台类型
*/
virtual PlatformType getType() const = 0;
/**
* @brief 初始化平台
* @return 初始化成功返回true否则返回false
*/
virtual bool initialize() = 0;
/**
* @brief 扫描USB设备
* @param vendorId 供应商ID
* @param productId 产品ID
* @return 设备路径列表
*/
virtual std::vector<std::string> scanUsbDevices(uint16_t vendorId, uint16_t productId) = 0;
/**
* @brief 打开USB设备
* @param devicePath 设备路径
* @return 设备句柄失败返回nullptr
*/
virtual void* openUsbDevice(const std::string& devicePath) = 0;
/**
* @brief 关闭USB设备
* @param deviceHandle 设备句柄
* @return 操作成功返回true否则返回false
*/
virtual bool closeUsbDevice(void* deviceHandle) = 0;
/**
* @brief 写入USB数据
* @param deviceHandle 设备句柄
* @param data 数据缓冲区
* @param size 数据大小
* @param timeout 超时时间(毫秒)
* @return 实际写入的字节数,失败返回-1
*/
virtual int writeUsbData(void* deviceHandle, const uint8_t* data, size_t size, int timeout) = 0;
/**
* @brief 读取USB数据
* @param deviceHandle 设备句柄
* @param data 数据缓冲区
* @param size 数据大小
* @param timeout 超时时间(毫秒)
* @return 实际读取的字节数,失败返回-1
*/
virtual int readUsbData(void* deviceHandle, uint8_t* data, size_t size, int timeout) = 0;
/**
* @brief 获取设备信息
* @param deviceHandle 设备句柄
* @param[out] info 设备信息
* @return 操作成功返回true否则返回false
*/
virtual bool getDeviceInfo(void* deviceHandle, DeviceInfo& info) = 0;
/**
* @brief 创建平台实例
* @return 平台实例
*/
static Platform* createPlatform();
};
} // namespace platform
} // namespace usb2can
#endif // USB2CAN_PLATFORM_H

View File

@@ -0,0 +1,83 @@
/**
* @file WindowsPlatform.h
* @brief Windows平台实现
*/
#ifndef USB2CAN_WINDOWS_PLATFORM_H
#define USB2CAN_WINDOWS_PLATFORM_H
#include "Platform.h"
#ifdef _WIN32
#include <windows.h>
#include <setupapi.h>
#include <winusb.h>
#endif
namespace usb2can {
namespace platform {
/**
* @brief Windows平台实现类
*/
class WindowsPlatform : public Platform {
public:
WindowsPlatform();
~WindowsPlatform() override;
PlatformType getType() const override;
bool initialize() override;
std::vector<std::string> scanUsbDevices(uint16_t vendorId, uint16_t productId) override;
void* openUsbDevice(const std::string& devicePath) override;
bool closeUsbDevice(void* deviceHandle) override;
int writeUsbData(void* deviceHandle, const uint8_t* data, size_t size, int timeout) override;
int readUsbData(void* deviceHandle, uint8_t* data, size_t size, int timeout) override;
bool getDeviceInfo(void* deviceHandle, DeviceInfo& info) override;
private:
/**
* @brief Windows设备句柄结构体
*/
struct WindowsDeviceHandle {
HANDLE deviceHandle; ///< 设备句柄
WINUSB_INTERFACE_HANDLE winUsbHandle; ///< WinUSB接口句柄
std::string devicePath; ///< 设备路径
};
/**
* @brief 获取设备接口路径
* @param deviceInfoSet 设备信息集
* @param deviceInfoData 设备信息数据
* @return 设备接口路径
*/
std::string getDeviceInterfacePath(HDEVINFO deviceInfoSet, SP_DEVINFO_DATA deviceInfoData);
/**
* @brief 打开WinUSB设备
* @param devicePath 设备路径
* @return WinUSB设备句柄
*/
WindowsDeviceHandle* openWinUsbDevice(const std::string& devicePath);
/**
* @brief 获取WinUSB设备描述符
* @param winUsbHandle WinUSB接口句柄
* @param descriptor 设备描述符
* @return 操作成功返回true否则返回false
*/
bool getWinUsbDescriptor(WINUSB_INTERFACE_HANDLE winUsbHandle, USB_DEVICE_DESCRIPTOR& descriptor);
/**
* @brief 获取WinUSB管道信息
* @param winUsbHandle WinUSB接口句柄
* @param pipeId 管道ID
* @param pipeInfo 管道信息
* @return 操作成功返回true否则返回false
*/
bool getWinUsbPipeInfo(WINUSB_INTERFACE_HANDLE winUsbHandle, UCHAR pipeId, WINUSB_PIPE_INFORMATION& pipeInfo);
};
} // namespace platform
} // namespace usb2can
#endif // USB2CAN_WINDOWS_PLATFORM_H

View File

@@ -0,0 +1,86 @@
/**
* @file LinuxUsbDevice.h
* @brief Linux平台USB设备实现
*/
#ifndef USB2CAN_LINUX_USB_DEVICE_H
#define USB2CAN_LINUX_USB_DEVICE_H
#include "UsbDevice.h"
#if defined(__linux__) || defined(__APPLE__)
#include <libusb.h>
#endif
namespace usb2can {
namespace usb {
/**
* @brief Linux平台USB设备实现类
*/
class LinuxUsbDevice : public UsbDevice {
public:
LinuxUsbDevice(platform::Platform* platform);
~LinuxUsbDevice() override;
bool open(const std::string& devicePath) override;
void close() override;
bool isOpen() const override;
int write(const uint8_t* data, size_t size, int timeout = 1000) override;
int read(uint8_t* data, size_t size, int timeout = 1000) override;
bool getDeviceInfo(UsbDeviceInfo& info) override;
std::string getDevicePath() const override;
private:
platform::Platform* platform_; ///< 平台实例
void* deviceHandle_; ///< 设备句柄
std::string devicePath_; ///< 设备路径
bool isOpen_; ///< 设备是否已打开
UsbDeviceInfo deviceInfo_; ///< 设备信息
uint8_t inEndpoint_; ///< 输入端点
uint8_t outEndpoint_; ///< 输出端点
#if defined(__linux__) || defined(__APPLE__)
libusb_context* ctx_; ///< libusb上下文
std::vector<libusb_endpoint_descriptor> endpoints_; ///< 端点描述符列表
#endif
/**
* @brief 初始化libusb
* @return 操作成功返回true否则返回false
*/
bool initializeLibUsb();
/**
* @brief 获取libusb设备句柄
* @return libusb设备句柄
*/
libusb_device_handle* getLibusbHandle() const;
/**
* @brief 获取USB设备描述符
* @param descriptor 设备描述符
* @return 操作成功返回true否则返回false
*/
bool getDeviceDescriptor(libusb_device_descriptor& descriptor);
/**
* @brief 获取USB字符串描述符
* @param descIndex 描述符索引
* @return 字符串描述符内容
*/
std::string getStringDescriptor(uint8_t descIndex);
/**
* @brief 查找USB设备的端点
* @param inEndpoint 输入端点
* @param outEndpoint 输出端点
* @return 操作成功返回true否则返回false
*/
bool findEndpoints(uint8_t& inEndpoint, uint8_t& outEndpoint);
};
} // namespace usb
} // namespace usb2can
#endif // USB2CAN_LINUX_USB_DEVICE_H

139
include/usb/UsbDevice.h Normal file
View File

@@ -0,0 +1,139 @@
/**
* @file UsbDevice.h
* @brief USB设备抽象接口定义
*/
#ifndef USB2CAN_USB_DEVICE_H
#define USB2CAN_USB_DEVICE_H
#include <string>
#include <vector>
#include <cstdint>
#include "../platform/Platform.h"
namespace usb2can {
namespace usb {
/**
* @brief USB设备信息结构体
*/
struct UsbDeviceInfo {
uint16_t vendorId; ///< 供应商ID
uint16_t productId; ///< 产品ID
std::string manufacturer; ///< 制造商
std::string productName; ///< 产品名称
std::string serialNumber; ///< 序列号
std::string devicePath; ///< 设备路径
};
/**
* @brief USB设备抽象接口类
*/
class UsbDevice {
public:
virtual ~UsbDevice() = default;
/**
* @brief 打开USB设备
* @param devicePath 设备路径
* @return 操作成功返回true否则返回false
*/
virtual bool open(const std::string& devicePath) = 0;
/**
* @brief 关闭USB设备
*/
virtual void close() = 0;
/**
* @brief 检查设备是否已打开
* @return 设备已打开返回true否则返回false
*/
virtual bool isOpen() const = 0;
/**
* @brief 写入数据
* @param data 数据缓冲区
* @param size 数据大小
* @param timeout 超时时间(毫秒)
* @return 实际写入的字节数,失败返回-1
*/
virtual int write(const uint8_t* data, size_t size, int timeout = 1000) = 0;
/**
* @brief 读取数据
* @param data 数据缓冲区
* @param size 数据大小
* @param timeout 超时时间(毫秒)
* @return 实际读取的字节数,失败返回-1
*/
virtual int read(uint8_t* data, size_t size, int timeout = 1000) = 0;
/**
* @brief 获取设备信息
* @param[out] info 设备信息
* @return 操作成功返回true否则返回false
*/
virtual bool getDeviceInfo(UsbDeviceInfo& info) = 0;
/**
* @brief 获取设备路径
* @return 设备路径
*/
virtual std::string getDevicePath() const = 0;
/**
* @brief 创建USB设备实例
* @param platform 平台实例
* @return USB设备实例
*/
static UsbDevice* createUsbDevice(platform::Platform* platform);
};
/**
* @brief USB设备管理器类
*/
class UsbDeviceManager {
public:
/**
* @brief 构造函数
* @param platform 平台实例
*/
explicit UsbDeviceManager(platform::Platform* platform);
/**
* @brief 析构函数
*/
~UsbDeviceManager();
/**
* @brief 扫描USB设备
* @param vendorId 供应商ID0表示匹配所有供应商
* @param productId 产品ID0表示匹配所有产品
* @return USB设备信息列表
*/
std::vector<UsbDeviceInfo> scanDevices(uint16_t vendorId = 0, uint16_t productId = 0);
/**
* @brief 打开USB设备
* @param devicePath 设备路径
* @return USB设备实例失败返回nullptr
*/
UsbDevice* openDevice(const std::string& devicePath);
/**
* @brief 关闭USB设备
* @param device USB设备实例
*/
void closeDevice(UsbDevice* device);
private:
platform::Platform* platform_; ///< 平台实例
std::vector<UsbDevice*> devices_; ///< 已打开的设备列表
};
} // namespace usb
} // namespace usb2can
#endif // USB2CAN_USB_DEVICE_H

View File

@@ -0,0 +1,81 @@
/**
* @file WinUsbDevice.h
* @brief Windows平台USB设备实现
*/
#ifndef USB2CAN_WIN_USB_DEVICE_H
#define USB2CAN_WIN_USB_DEVICE_H
#include "UsbDevice.h"
#ifdef _WIN32
#include <windows.h>
#include <setupapi.h>
#include <winusb.h>
#endif
namespace usb2can {
namespace usb {
/**
* @brief Windows平台USB设备实现类
*/
class WinUsbDevice : public UsbDevice {
public:
WinUsbDevice(platform::Platform* platform);
~WinUsbDevice() override;
bool open(const std::string& devicePath) override;
void close() override;
bool isOpen() const override;
int write(const uint8_t* data, size_t size, int timeout = 1000) override;
int read(uint8_t* data, size_t size, int timeout = 1000) override;
bool getDeviceInfo(UsbDeviceInfo& info) override;
std::string getDevicePath() const override;
private:
platform::Platform* platform_; ///< 平台实例
void* deviceHandle_; ///< 设备句柄
std::string devicePath_; ///< 设备路径
bool isOpen_; ///< 设备是否已打开
UsbDeviceInfo deviceInfo_; ///< 设备信息
/**
* @brief 获取WinUSB设备句柄
* @return WinUSB设备句柄
*/
WINUSB_INTERFACE_HANDLE getWinUsbHandle() const;
/**
* @brief 获取Windows设备句柄
* @return Windows设备句柄
*/
HANDLE getWindowsHandle() const;
/**
* @brief 获取USB管道信息
* @param pipeId 管道ID
* @param pipeInfo 管道信息
* @return 操作成功返回true否则返回false
*/
bool getPipeInfo(UCHAR pipeId, WINUSB_PIPE_INFORMATION& pipeInfo);
/**
* @brief 获取USB设备描述符
* @param descriptor 设备描述符
* @return 操作成功返回true否则返回false
*/
bool getDeviceDescriptor(USB_DEVICE_DESCRIPTOR& descriptor);
/**
* @brief 获取USB字符串描述符
* @param descIndex 描述符索引
* @return 字符串描述符内容
*/
std::string getStringDescriptor(uint8_t descIndex);
};
} // namespace usb
} // namespace usb2can
#endif // USB2CAN_WIN_USB_DEVICE_H