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
201 lines
6.3 KiB
C++
201 lines
6.3 KiB
C++
/**
|
||
* @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
|