Go语言实现的CAN总线通信库,基于Linux SocketCAN,提供完整的CAN/CAN FD通信功能。
- 完整的SocketCAN支持: 基于Linux内核SocketCAN实现
- CAN FD支持: 支持CAN FD协议,包括BRS和ESI标志
- 高精度时间戳: 支持软件和硬件时间戳
- 智能过滤器: 内核级CAN帧过滤,支持精确匹配、范围匹配、掩码匹配
- 设备管理: 完整的CAN设备配置和管理功能
- 命令行工具: 兼容can-utils的命令行工具
- 高性能: 基于系统调用,性能优异
- 错误处理: 完整的错误帧解析和处理
- Linux系统 (内核支持SocketCAN)
go get github.com/wmem/go-cango-can/
├── pkg/ # 核心库
│ ├── raw/ # SocketCAN原始接口
│ │ ├── socket.go # CAN socket实现
│ │ ├── frame.go # CAN帧处理
│ │ ├── filter.go # CAN过滤器
│ │ ├── error.go # 错误帧解析
│ │ └── const.go # 常量定义
│ └── candevice/ # CAN设备管理
│ ├── device.go # 设备配置
│ ├── param.go # 参数管理
│ └── control.go # 设备控制
├── cmd/ # 命令行工具
│ ├── candevice/ # 设备配置工具
│ ├── cansend/ # 报文发送工具
│ └── candump/ # 报文接收工具
├── examples/ # 使用示例
└── docs/ # 文档
package main
import (
"fmt"
"log"
"github.com/wmem/go-can/pkg/raw"
)
func main() {
// 创建CAN socket
socket, err := raw.New("can0")
if err != nil {
log.Fatal(err)
}
defer raw.Free(socket)
// 发送CAN帧
frame := raw.RawFrameSend{
ID: 0x123,
Data: []byte{0x01, 0x02, 0x03, 0x04},
IsExtended: false,
IsRemote: false,
}
err = socket.SendFrame(frame)
if err != nil {
log.Fatal(err)
}
// 接收CAN帧
recvFrame, err := socket.RecvFrame()
if err != nil {
log.Fatal(err)
}
fmt.Printf("接收到CAN帧: ID=0x%X, 数据=%v\n", recvFrame.ID, recvFrame.Data)
}// 发送CAN FD帧
fdFrame := raw.RawFrameSend{
ID: 0x123,
Data: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
IsFD: true,
IsBRS: true, // 位率切换
HasESI: false, // 错误状态指示
}
err = socket.SendFrame(fdFrame)// 精确匹配过滤器
filters := raw.NewExactFilter(0x123)
socket.SetFilter([]raw.CanFilter{filters})
// 范围过滤器 - 自动拆分为多个2^n对齐的子块
rangeFilters := raw.NewRangeFilter(0x100, 0x130)
socket.SetFilter(rangeFilters)
// 多个过滤器组合
filters := []raw.CanFilter{
raw.NewExactFilter(0x123),
raw.NewMaskFilter(0x200, 0xFF00), // 匹配0x200-0x2FF
}
socket.SetFilter(filters)frame, err := socket.RecvFrame()
if err == nil {
// 软件时间戳
if frame.SoftTime > 0 {
fmt.Printf("软件时间戳: %.9f秒\n", float64(frame.SoftTime)/1e9)
}
// 硬件时间戳
if frame.HardTime > 0 {
fmt.Printf("硬件时间戳: %.9f秒\n", float64(frame.HardTime)/1e9)
}
}package main
import (
"github.com/wmem/go-can/pkg/candevice"
)
func main() {
// 创建设备实例
device, err := candevice.DeviceFromName("can0")
if err != nil {
log.Fatal(err)
}
// 配置CAN参数
params := candevice.DeviceParam{
"bitrate": 500000,
"sample-point": 0.875,
"loopback": false,
"listen-only": false,
}
err = device.SetParam(params)
if err != nil {
log.Fatal(err)
}
// 启动接口
err = device.SetUp()
if err != nil {
log.Fatal(err)
}
}# 显示can0接口信息
candevice -i can0 -show
# 设置can0为500kbps并启动
candevice -i can0 -bitrate 500000 -up
# 设置CAN FD模式
candevice -i can0 -bitrate 500000 -dbitrate 2000000 -fd on -up
# 关闭接口
candevice -i can0 -down# 发送标准帧
cansend can0 123#01020304
# 发送扩展帧
cansend can0 1FFFFFFF#01020304
# 发送CAN FD帧
cansend can0 123##0102030405060708090A
# 发送远程帧
cansend can0 123#R# 接收所有报文
candump can0
# 接收100个报文并显示时间戳
candump -t -n 100 can0
# 仅显示错误帧
candump -e can0
# 彩色输出
candump -c can0// CAN帧发送结构
type RawFrameSend struct {
ID uint32 // CAN ID
Data []byte // 数据
IsRemote bool // 远程帧
IsExtended bool // 扩展帧
IsFD bool // CAN FD帧
HasESI bool // 错误状态指示
IsBRS bool // 位率切换
}
// CAN帧接收结构
type RawFrameRecv struct {
ID uint32 // CAN ID
Data []byte // 数据
IsRemote bool // 远程帧
IsExtended bool // 扩展帧
IsFD bool // CAN FD帧
HasESI bool // 错误状态指示
IsBRS bool // 位率切换
IsError bool // 错误帧
IsTx bool // 发送帧(回环)
SoftTime uint64 // 软件时间戳(纳秒)
HardTime uint64 // 硬件时间戳(纳秒)
}
// CAN过滤器
type CanFilter struct {
ID uint32 // 过滤ID
Mask uint32 // 过滤掩码
}// 创建CAN socket
func New(ifName string) (*SocketRaw, error)
// 释放CAN socket
func Free(s *SocketRaw)
// 发送CAN帧
func (s *SocketRaw) SendFrame(msg RawFrameSend) error
// 接收CAN帧
func (s *SocketRaw) RecvFrame() (RawFrameRecv, error)
// 设置过滤器
func (s *SocketRaw) SetFilter(filters []CanFilter) error
// 设置超时
func (s *SocketRaw) SetTimeout(ms uint)
// 过滤器创建函数
func NewExactFilter(id uint32) CanFilter
func NewRangeFilter(startID, endID uint32) []CanFilter
func NewMaskFilter(id, mask uint32) CanFilter
func NewAcceptAllFilter() CanFilter- Raw SocketCAN: 基础CAN通信功能
- CAN FD: CAN FD协议支持
- 过滤器: 智能CAN帧过滤
- 时间戳: 高精度时间戳支持
- 设备管理: CAN设备配置管理
- 命令行工具: can-utils兼容工具
- CAN TP: ISO-TP (ISO 14229-2) 传输协议
- J1939: SAE J1939 车载网络协议
- 诊断协议: UDS (ISO 14229) 统一诊断服务
- 更多协议: CANopen, DeviceNet等
欢迎贡献代码!请遵循以下步骤:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 开启 Pull Request
本项目采用 MIT 许可证。
- Linux SocketCAN - 底层CAN支持
- can-utils - 命令行工具参考
- Go 社区的支持和贡献
如有问题或建议,请通过以下方式联系:
- 提交 Issue
- 发起 Discussion
注意: 本库目前仅支持Linux系统。