Files
hcanview/include/can/CanMessage.h
yemai 81bee50cd9 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
2025-09-11 17:56:26 +08:00

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