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:
265
include/api/Usb2Can.h
Normal file
265
include/api/Usb2Can.h
Normal 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表示常规CAN,1表示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
131
include/can/CanController.h
Normal 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
|
||||
131
include/can/CanFdController.h
Normal file
131
include/can/CanFdController.h
Normal 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
201
include/can/CanMessage.h
Normal 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
|
||||
107
include/device/DeviceManager.h
Normal file
107
include/device/DeviceManager.h
Normal 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
|
||||
268
include/device/Usb2CanDevice.h
Normal file
268
include/device/Usb2CanDevice.h
Normal 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
|
||||
77
include/platform/LinuxPlatform.h
Normal file
77
include/platform/LinuxPlatform.h
Normal 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
113
include/platform/Platform.h
Normal 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
|
||||
83
include/platform/WindowsPlatform.h
Normal file
83
include/platform/WindowsPlatform.h
Normal 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
|
||||
86
include/usb/LinuxUsbDevice.h
Normal file
86
include/usb/LinuxUsbDevice.h
Normal 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
139
include/usb/UsbDevice.h
Normal 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 供应商ID,0表示匹配所有供应商
|
||||
* @param productId 产品ID,0表示匹配所有产品
|
||||
* @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
|
||||
81
include/usb/WinUsbDevice.h
Normal file
81
include/usb/WinUsbDevice.h
Normal 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
|
||||
Reference in New Issue
Block a user