C.Can.Core 0.0.1

dotnet add package C.Can.Core --version 0.0.1
                    
NuGet\Install-Package C.Can.Core -Version 0.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="C.Can.Core" Version="0.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="C.Can.Core" Version="0.0.1" />
                    
Directory.Packages.props
<PackageReference Include="C.Can.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add C.Can.Core --version 0.0.1
                    
#r "nuget: C.Can.Core, 0.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package C.Can.Core@0.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=C.Can.Core&version=0.0.1
                    
Install as a Cake Addin
#tool nuget:?package=C.Can.Core&version=0.0.1
                    
Install as a Cake Tool

Can.Core - CAN总线通信库

CAN总线通信库,基于观察者模式设计,支持 .NET 8.0 和 .NET 10.0。

安装

NuGet

dotnet add package C.Can.Core

项目引用

<ProjectReference Include="..\Can.Core\Can.Core.csproj" />

核心概念

架构设计

Can.Core 使用观察者模式 (Observer Pattern) 实现 CAN 帧的接收和分发:

┌─────────────────┐      ┌─────────────────┐      ┌─────────────────┐
│   CanPortBase   │──────│   CanObserver   │──────│   业务逻辑      │
│  (被观察者)     │      │   (观察者)      │      │   (事件处理)    │
└─────────────────┘      └─────────────────┘      └─────────────────┘
        │                        │
        │  ProcessReceive()      │  OnReceive事件
        │───────────────────────>│

主要组件

组件 说明
CanFrame CAN数据帧,包含ID、数据缓冲区、是否扩展帧
CanGuid CAN端口唯一标识符(系统类型/系统编号/板卡ID/端口ID)
CanFilter CAN帧过滤器,支持ID过滤和帧类型过滤
ICanPort CAN端口接口
CanPortBase CAN端口抽象基类,管理观察者列表
CanObserver CAN观察者实现类,通过事件通知接收帧
CanPortManager CAN端口管理器(单例),管理所有端口

使用示例

1. 创建自定义CAN端口

using Can.Core;

// 继承 CanPortBase 实现自定义端口
public class UsbCanPort : CanPortBase
{
    private readonly UsbCanDevice _device;
    
    public UsbCanPort(int systemClassId, int systemId, int cardId, int portId)
    {
        PortGuid = new CanGuid(systemClassId, systemId, cardId, portId);
        Description = "USB-CAN Device";
        _device = new UsbCanDevice();
    }
    
    public override bool Open()
    {
        return _device.Open();
    }
    
    public override bool Close()
    {
        return _device.Close();
    }
    
    public override void Send(CanFrame frame)
    {
        _device.Send(frame.CanId, frame.Buf, frame.IsExFrame);
    }
    
    // 在接收到数据时调用 ProcessReceive
    private void OnDeviceReceive(int canId, byte[] data, bool isExFrame)
    {
        var frame = new CanFrame
        {
            CanId = canId,
            Buf = data,
            IsExFrame = isExFrame
        };
        ProcessReceive(frame);  // 分发给所有观察者
    }
}

2. 创建观察者接收数据

using Can.Core;

// 创建观察者
var observer = new CanObserver();

// 设置过滤器 - 只接收ID为0x123的标准帧
observer.CanFilter = new CanFilter
{
    ExframeFilterFlag = ExframeFilterFlag.Can20A,  // 只接收标准帧
    Mask = 0x7FF,   // 检查全部11位
    Filter = 0x123  // ID为0x123
};

// 注册接收事件
observer.OnReceive += (port, frame) =>
{
    Console.WriteLine($"收到CAN帧: ID={frame.CanId:X}, 数据={BitConverter.ToString(frame.Buf)}");
};

// 添加观察者到端口
port.AddObserver(observer);

3. 使用端口管理器

using Can.Core;

// 获取单例实例
var manager = CanPortManager.Instance;

// 创建并添加端口
var port1 = new UsbCanPort(0, 0, 0, 0);
var port2 = new UsbCanPort(0, 0, 0, 1);

manager.AddPort(port1);
manager.AddPort(port2);

// 通过名称获取端口
var foundPort = manager["Can0/0/0/0"];

// 获取所有端口
var allPorts = manager.GetPorts();

// 移除端口
manager.RemovePort(port1);

// 清空所有端口
manager.Clear();

4. 发送CAN帧

using Can.Core;

// 创建CAN帧
var frame = new CanFrame
{
    CanId = 0x123,
    IsExFrame = false,  // 标准帧
    Buf = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
};

// 发送
port.Send(frame);

过滤器详解

帧类型过滤

// 接收所有帧(默认)
filter.ExframeFilterFlag = ExframeFilterFlag.All;

// 只接收标准帧 (CAN 2.0A)
filter.ExframeFilterFlag = ExframeFilterFlag.Can20A;

// 只接收扩展帧 (CAN 2.0B)
filter.ExframeFilterFlag = ExframeFilterFlag.Can20B;

ID过滤原理

过滤器使用掩码+匹配值的方式:

// 公式: ((CanId ^ Filter) & Mask) == 0 表示匹配

// 示例1: 精确匹配ID=0x123
filter.Mask = 0x7FF;   // 检查全部11位
filter.Filter = 0x123; // 匹配值

// 示例2: 接收ID范围0x100-0x10F
filter.Mask = 0x7F0;   // 只检查高7位
filter.Filter = 0x100; // 高7位必须为0x10

// 示例3: 接收所有帧(不检查ID)
filter.Mask = 0;       // 不检查任何位
filter.Filter = 0;     // 匹配值(无意义)

多观察者不同过滤

// 观察者1: 只接收标准帧
var observer1 = new CanObserver();
observer1.CanFilter = new CanFilter { ExframeFilterFlag = ExframeFilterFlag.Can20A };
observer1.OnReceive += (p, f) => Console.WriteLine($"标准帧: {f.CanId:X}");

// 观察者2: 只接收扩展帧,ID范围0x100-0x1FF
var observer2 = new CanObserver();
observer2.CanFilter = new CanFilter
{
    ExframeFilterFlag = ExframeFilterFlag.Can20B,
    Mask = 0xF00,
    Filter = 0x100
};
observer2.OnReceive += (p, f) => Console.WriteLine($"扩展帧: {f.CanId:X}");

// 添加到同一端口
port.AddObserver(observer1);
port.AddObserver(observer2);

CanGuid 唯一标识

// 格式: Can{SystemClassId}/{SystemId}/{CardId}/{PortId}

// PC自带CAN口
var guid1 = new CanGuid(0, 0, 0, 0);  // "Can0/0/0/0"

// 第1台通信分机,第2块板卡,第3个端口
var guid2 = new CanGuid(1, 1, 2, 3);  // "Can1/1/2/3"

// 属性说明:
// - SystemClassId: 系统类型(PC=0, 通信分机=1)
// - SystemId: 系统编号
// - CardId: 板卡编号
// - PortId: 端口编号(可修改)

API 参考

CanFrame

属性 类型 说明
IsExFrame bool 是否扩展帧(默认false)
CanId int CAN标识符(默认0)
Buf byte[]? 数据缓冲区(默认null)

CanGuid

属性 类型 说明
SystemClassId int 系统类型ID(只读)
SystemId int 系统编号(只读)
CardId int 板卡ID(只读)
PortId int 端口编号(可写)

CanFilter

属性 类型 说明
ExframeFilterFlag enum 帧类型过滤标志(默认All)
Mask int 过滤掩码(默认0)
Filter int 匹配值(默认0)
方法 说明
IsValid(CanFrame) 检查帧是否匹配过滤条件

ICanPort

属性 说明
PortGuid 端口唯一标识
Description 端口描述信息
方法 说明
Send(CanFrame) 发送CAN帧
AddObserver(CanObserverBase) 添加观察者
RemoveObserver(CanObserverBase) 移除观察者
Open() 打开端口
Close() 关闭端口

CanObserver

属性 说明
CanFilter 帧过滤器
OnReceive 接收事件

CanPortManager (单例)

属性/方法 说明
Instance 单例实例
GetPorts() 获取所有端口列表
AddPort(ICanPort) 添加端口
RemovePort(ICanPort) 移除端口
this[string name] 通过名称获取端口
Clear() 清空所有端口

运行测试

# 运行所有测试
dotnet test

# 运行特定测试
dotnet test --filter "FullyQualifiedName~CanFilterTests"

项目结构

Can.Core/
├── src/                         # 源码目录
│   ├── Can.Core.csproj          # 主项目
│   ├── Models/                  # 数据模型
│   │   ├── CanFrame.cs          # CAN帧数据结构
│   │   └── CanGuid.cs           # 端口唯一标识
│   ├── Filtering/               # 过滤器
│   │   ├── CanFilter.cs         # 帧过滤器
│   │   └── ExframeFilterFlag.cs # 帧类型枚举
│   ├── Ports/                   # 端口
│   │   ├── ICanPort.cs          # CAN端口接口
│   │   ├── CanPortBase.cs       # CAN端口基类
│   │   └── CanPortManager.cs    # 端口管理器
│   └── Observers/               # 观察者
│       ├── CanObserverBase.cs   # 观察者基类
│       └── CanObserver.cs       # 观察者实现
├── tests/                       # 测试目录
│   └── Can.Core.Tests/          # 单元测试项目
│       ├── Can.Core.Tests.csproj
│       ├── CanFilterTests.cs
│       ├── CanGuidTests.cs
│       ├── CanPortBaseTests.cs
│       └── CanPortManagerTests.cs
├── docs/                        # 文档目录
│   └── 需求.md                   # 需求文档
└── README.md                    # 使用文档

版本历史

  • 1.0.0: 初始版本,从 CanSharp 移植,支持 .NET 8.0/10.0

许可证

MIT License

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.1 84 5/11/2026