# 核心库(必须)dotnet add package CanKit.Core# 适配器包(按需选择)dotnet add package CanKit.Adapter.Vectordotnet add package CanKit.Adapter.PCANdotnet add package CanKit.Adapter.Kvaserdotnet add package CanKit.Adapter.SocketCANdotnet add package CanKit.Adapter.ZLGdotnet add package CanKit.Adapter.ControlCANdotnet add package CanKit.Adapter.Virtual注意:各厂商的底层驱动或运行库(如 PCAN-Basic、Kvaser CANlib、ZLGCAN.dll 等)需单独安装,并确保其版本与应用程序架构(x86/x64)匹配。具体要求请参考各适配器的官方说明。
项目特性
高性能与背压控制
背压友好的异步接口(基于 ValueTask 和 Channel<t>)
统一 API
支持通过 Endpoint 字符串(如 pcan://PCAN_USBBUS1)或 强类型入口(如 Kvaser.Open(0))打开总线
提供 BusEndpointEntry.Enumerate() 方法枚举可用设备
兼容 经典 CAN 2.0 与 CAN FD 帧类型
Transmit() / Receive()
TransmitAsync() / ReceiveAsync()
.NET 8+ 支持 GetFramesAsync() 批量拉取
事件驱动支持
FrameReceived
ErrorFrameReceived
BackgroundExceptionOccurred
定时与工作模式
支持经典 CAN 与 CAN FD 的位时序参数配置(Tseg1、Tseg2、Brp、SJW 等)
工作模式可选:正常模式、只听模式(Listen Only)、回环模式(Loopback),具体取决于硬件能力
过滤器
当硬件不支持指定过滤类型时,自动启用 软件回退机制
周期发送
优先使用设备支持的 硬件周期发送(如 Kvaser、Vector)
诊断与监控
实时获取 错误帧、总线状态(Active/Passive/BusOff)
支持读取 错误计数器(TEC/REC)
部分适配器可查询 总线利用率(依赖驱动实现)
运行时选项
可动态配置
异步接收缓冲区大小
接收循环延迟与停止策略
发送重试策略(单次发送 / 自动重试)
是否启用错误帧与诊断信息上报
项目使用
1、Endpoint 示例
CanKit 使用统一的 Endpoint 字符串标识不同厂商设备,常见格式如下:
Vector: vector://AppName/0
PCAN: pcan://PCAN_USBBUS1
Kvaser: kvaser://0 或 kvaser://?ch=0
SocketCAN (Linux): socketcan://can0netlink ZLG: zlg://USBCANFD-200U?index=0ch1 ControlCAN: controlcan://USBCAN2?index=0ch1 Virtual(虚拟总线): virtual://alpha/0
2、发送与接收(基础用法)
using CanKit.Core;using CanKit.Core.Definitions;// 打开总线并配置经典 CAN 比特率(500 kbps)usingvar bus = CanBus.Open( "socketcan://can0netlink", cfg => cfg.TimingClassic(500_000));// 创建一帧经典 CAN 数据var frame = CanFrame.Classic(0x123, newbyte[] { 0x11, 0x22, 0x33 });// 同步发送var sentCount = bus.Transmit(frame);// 异步发送sentCount = await bus.TransmitAsync(frame);// 同步接收(最多 2 帧,超时 100ms)var items = bus.Receive(2, timeOut: 100);// 异步批量接收(最多 10 帧,超时 500ms)var list = await bus.ReceiveAsync(10, timeOut: 500);3、事件驱动接收 + 批量发送
using CanKit.Core;using CanKit.Core.Abstractions;using CanKit.Core.Definitions;using System;// 打开总线usingvar bus = CanBus.Open( "socketcan://can0netlink", cfg => cfg.TimingClassic(500_000));// 订阅帧接收事件bus.FrameReceived += (_, rec) =>{ var f = rec.CanFrame; Console.WriteLine($"RX {f.FrameKind} ID=0x{f.ID:X} DLC={f.Dlc}");};var frame = CanFrame.Classic(0x123, newbyte[] { 0x11, 0x22, 0x33 });var frames = new[] { frame, frame, frame, frame };// 批量同步发送var sentCount = bus.Transmit(frames);// 批量异步发送sentCount = await bus.TransmitAsync(frames);// 按需拉取数据(可选)var one = bus.Receive(1, timeOut: 100);var many = await bus.ReceiveAsync(10, timeOut: 500);注:如需接收错误帧或状态帧,请在 CanBus.Open 的配置中启用对应选项。
4、强类型入口(可选)
若偏好强类型 API,可直接使用适配器类:
using CanKit.Adapter.Kvaser;var bus = Kvaser.Open(0, cfg => cfg.TimingFd(1_000_000, 2_000_000)); // CAN FD 配置5、枚举可用设备
using CanKit.Core.Endpoints;// 枚举指定类型的可用 Endpointforeach (var ep in BusEndpointEntry.Enumerate("pcan", "kvaser", "socketcan", "virtual")){ Console.WriteLine($"{ep.Title ?? ep.Endpoint} -> {ep.Endpoint}");}6、查询设备能力
using CanKit.Core;var capability = CanBus.QueryCapabilities("kvaser://0");Console.WriteLine($"支持的功能: {capability.Features}");适配器说明(驱动依赖)
厂商 | 平台 | 依赖说明 |
| Vector | Windows/Linux | 安装 XL Driver Library,并在 Vector Hardware Manager 中配置 App 映射 |
| PCAN | Windows | 安装 PCAN 驱动与 PCAN-Basic;确保 PCANBasic.dll 可加载(注意 x86/x64 匹配) |
| Kvaser | Windows/Linux | 安装 Kvaser Driver + CANlib;确保通道可访问 |
| SocketCAN | Linux | 启用内核 SocketCAN 支持,通过 ip link 配置接口;建议安装 libsocketcan |
| ZLG | Windows | 确保 zlgcan.dll 在程序路径中,且位数匹配。建议编译为 x86,部分老设备(如 USBCAN-1/2)在 x64 下无法正常开启 |
| ControlCAN | Windows | 确保 ControlCAN.dll 在加载路径,且与进程架构一致 |
| Virtual | 跨平台 | 无需驱动,纯内存模拟 |
行为差异说明
超时语义
SocketCAN 支持 发送(TX)和接收(RX)超时;
其他适配器仅支持 接收超时。
过滤器支持:各厂商对掩码/范围过滤的支持程度不同;CanKit 在硬件不支持时自动启用 软件过滤回退。
诊断信息
错误帧、错误计数、总线利用率等功能 依赖适配器与驱动实现。
例如:
Kvaser 需主动查询才能获取总线利用率;
Vector 的错误计数需通过特定 API 请求。
周期发送
若设备支持(如 Kvaser、Vector),优先使用 硬件周期发送;否则自动切换为高精度 软件周期发送。
项目效果
下面是一个使用CanKit开发的CAN通信Demo,支持多厂商发送接收,查询连接设备,设置滤波等功能。
项目源码
为了防止丢失,后台回复关键字「设备通信」,即可获取完整源码地址。
总结
项目不追求大而全,而是聚焦于解决"多硬件兼容"这一真实痛点。工业软件日益强调可移植性与维护效率,这样的中间件价值尤为突出。不管是做汽车 HIL 测试、电池管理系统,还是自动化产线监控,CanKit 都能让大家把精力集中在业务逻辑上,而不是反复折腾不同 CAN 卡的驱动细节。
关键词
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
作者:小码编匠
出处:gitee.com/smallcore/DotNetCore
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!
方便大家交流、资源共享和共同成长
纯技术交流群,需要加入的小伙伴请扫码,并备注【加群】
推荐阅读
觉得有收获?不妨分享让更多人受益
关注「DotNet技术匠」,共同提升技术实力
</t>
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!