CanKit
a cross-platform, multi-vendor unified C# high-performance CAN (Controller Area Network) library
Install / Use
/learn @pkuyo/CanKitREADME
CanKit
CanKit is an unified, cross-platform, multi-vendor, high-performance c# CAN communication library.
It supports opening buses via endpoint strings or strongly-typed helpers, and exposes common operations (send/receive, filters, periodic TX, error monitoring) across adapters.
- Adapters: PCAN-Basic (Peak CAN), CANlib(Kvaser), SocketCAN (Linux), ZLG
For Chinese readers, see: README_CN.md
Below is a quick CAN listener/sender demo using CanKit. With multi-vendor support, you can get hands-on with CanKit features in minutes. CanKit ToolKit

Features
- Performance and backpressure
- High-throughput pipeline with backpressure-aware async APIs
- Configurable buffering to avoid overload and drop
- Unified API surface
- Open by endpoint or typed helpers; enumerate endpoints
- Classic CAN 2.0 and CAN FD frames
- Sync and async I/O:
Transmit/Receive,TransmitAsync/ReceiveAsync, andGetFramesAsync(NET 8+) - Events:
FrameObserved,ErrorFrameReceived,BackgroundExceptionOccurred
- Timing and modes
- Classic and FD bit timing helpers; advanced segment-based timing via
CanBusTiming - Work modes: Normal / Listen-Only / Echo (loopback) when supported by device
- Classic and FD bit timing helpers; advanced segment-based timing via
- Filtering
- Configure mask or range filters via a unified API
- Software fallbacks when hardware filtering is limited
- Periodic transmit
- Hardware cyclic TX where available; otherwise software periodic TX
- Diagnostics and telemetry
- Error frames, bus state, error counters, bus usage (availability depends on adapter)
Install
Add the core package and one or more adapter packages as needed. Package IDs are indicative; use the actual published IDs for your feed.
dotnet add package CanKit.Core
// Pick adapters you need
dotnet add package CanKit.Adapter.PCAN
dotnet add package CanKit.Adapter.Kvaser
dotnet add package CanKit.Adapter.SocketCAN
dotnet add package CanKit.Adapter.ZLG
dotnet add package CanKit.Adapter.Virtual
Quick Start
Open a bus using an endpoint string, then send/receive frames. Examples:
- PCAN:
pcan://PCAN_USBBUS1 - Kvaser:
kvaser://0orkvaser://?ch=0 - SocketCAN (Linux):
socketcan://can0 - ZLG:
zlg://USBCANFD-200U?index=0#ch1 - Virtual:
virtual://alpha/0 - Vector:
vector://YourAppName/0 - ControlCAN:
controlcan://USBCAN2index=0#ch0
Send & Receive
using CanKit.Core;
using CanKit.Core.Definitions;
// Open via endpoint; tune bitrate and other options in the configurator
using var bus = CanBus.Open(
"socketcan://can0#netlink",
cfg => cfg.TimingClassic(500_000)); // 500 kbit/s for classic CAN
// Transmit a classic CAN frame (sync)
var frame = CanFrame.Classic(0x123, new byte[] { 0x11, 0x22, 0x33 });
var sentCount = bus.Transmit(frame);
// Transmit the same frame (async)
sentCount = await bus.TransmitAsync(frame);
// Receive up to 1 frame (blocking), timeout in milliseconds
var items = bus.Receive(1, timeOut: 100);
// Receive up to 10 frames (async batch) with timeout
var list = await bus.ReceiveAsync(10, timeOut: 500);
Event-driven RX + Batch TX
// Event-driven receive, pretty-print frames, and batch transmit
using CanKit.Core;
using CanKit.Core.Abstractions;
using CanKit.Core.Definitions;
using System;
// Open the bus; adjust timing/mode in the configurator as needed
using var bus = CanBus.Open(
"socketcan://can0#netlink",
cfg => cfg.Baud(500_000));
// Subscribe to frames (enable error/state frames in the configurator if you need them)
bus.FrameObserved += (_, rec) =>
{
var f = rec.CanFrame;
Console.WriteLine($"RX {f.FrameKind} ID=0x{f.ID:X} DLC={f.Dlc}");
};
// Single frame TX (sync + async)
var frame = CanFrame.Classic(0x123, new byte[] { 0x11, 0x22, 0x33 });
var sentCount = bus.Transmit(frame);
sentCount = await bus.TransmitAsync(frame);
// Batch TX (sync + async)
var frames = new[] { frame, frame, frame, frame };
sentCount = bus.Transmit(frames);
sentCount = await bus.TransmitAsync(frames);
// Optional: also pull frames on demand (sync/async) with timeouts
var one = bus.Receive(1, timeOut: 100);
var many = await bus.ReceiveAsync(10, timeOut: 500);
Prefer a strongly-typed helper? Available for some adapters:
using CanKit.Adapter.Kvaser;
var kvaser = Kvaser.Open(0, cfg => cfg.Fd(1_000_000, 2_000_000));
Endpoints & Enumeration
Enumerate discoverable endpoints:
using CanKit.Core.Endpoints;
foreach (var ep in BusEndpointEntry.Enumerate("pcan", "kvaser", "socketcan", "zlg", "virtual"))
{
Console.WriteLine($"{ep.Title ?? ep.Endpoint} -> {ep.Endpoint}");
}
Query Device Capabilities
using CanKit.Core;
var capability = CanBus.QueryCapabilities("kvaser://0");
Console.WriteLine($"support: {capability.Features}")
Error Handling & Monitoring
CanKit exposes events to handle critical failures, background loop exceptions, and CAN bus error frames.
// Triggered when the connection is broken or a fatal driver error occurs.
bus.FaultOccurred += (sender, exception) => {};
// Triggered when a non-fatal exception occurs in the receive/transmit loops.
bus.BackgroundExceptionOccurred += (sender, exception) => {};
// Triggered when the CAN controller detects physical bus errors (Bit, Stuff, CRC, etc.).
bus.ErrorFrameReceived += (sender, errorInfo) => {};
Getting Started
Read the step-by-step guide, including installing drivers/runtime libraries per adapter:
- English: getting-started
Adapter Notes (Quick)
- PCAN (Windows): install PCAN drivers and PCAN-Basic; the native PCANBasic.dll must be loadable (x86/x64 must match your process).
- Kvaser (Windows/Linux): install Kvaser Driver + CANlib; ensure canlib is loadable and channel accessible.
- SocketCAN (Linux): enable SocketCAN, configure the interface (ip link...), and install libsocketcan for netlink-based config (
#netlink). - ZLG (Windows): ensure zlgcan.dll is present and bitness matches your process.
- Virtual: no driver needed.
Behavior Differences (Heads-up)
Different adapters may handle timeouts, filters, error frames, and periodic TX differently:
- Timeouts: some adapters ignore TX timeouts (e.g., PCAN, Kvaser), others honor both TX/RX timeouts.
- Filters: mask vs. range support varies; software fallback can be enabled when hardware filtering is limited.
- Error Frames/Counters/Bus Usage: availability depends on adapter/driver.
- Periodic TX: hardware-backed on some adapters; otherwise use software periodic TX fallback.
See docs for detailed, adapter-specific notes.
Project Status
This library is under active development. Due to limited access to hardware, not every feature is fully validated across all device families and OS combinations. If you hit issues, please open an issue. Contributions (PRs), device-specific fixes, and test reports are very welcome!
License
This project is available under the LICENSE in this repository.
Related Skills
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
85.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
342.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
342.5kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
