CanHub.Adapter.Zlg 1.0.1

dotnet add package CanHub.Adapter.Zlg --version 1.0.1
                    
NuGet\Install-Package CanHub.Adapter.Zlg -Version 1.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="CanHub.Adapter.Zlg" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CanHub.Adapter.Zlg" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="CanHub.Adapter.Zlg" />
                    
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 CanHub.Adapter.Zlg --version 1.0.1
                    
#r "nuget: CanHub.Adapter.Zlg, 1.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 CanHub.Adapter.Zlg@1.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=CanHub.Adapter.Zlg&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=CanHub.Adapter.Zlg&version=1.0.1
                    
Install as a Cake Tool

CanHub.Adapter.Zlg

简体中文

NuGet .NET 10 License: Apache-2.0

CanHub.Adapter.Zlg connects CanHub to ZLG USBCANFD devices through the ZLG CAN runtime. It provides endpoint parsing, native asset loading, bus lifecycle management, CAN/CAN FD transmission, and hardware diagnostics.

Install

dotnet add package CanHub.Core
dotnet add package CanHub.Adapter.Zlg

The package targets Windows and includes adapter native assets for supported runtime identifiers. The ZLG device driver must be installed according to ZLG's documentation.

Native Runtime Layout

When this package is consumed, the ZLG runtime is copied under the application output directory as:

canhub/zlg/x64/zlgcan.dll
canhub/zlg/x64/kerneldlls/...
canhub/zlg/x86/zlgcan.dll
canhub/zlg/x86/kerneldlls/...

Package builds select the process/runtime architecture and copy only x64 or x86 for consumer projects. The package stores the payload under buildTransitive/native instead of NuGet runtimes/*/native so RID builds do not also place zlgcan.dll in the output root.

ZlgNativeLoader prefers canhub/zlg/<arch>/zlgcan.dll, registers that directory plus kerneldlls subdirectories with AddDllDirectory, and does not mutate PATH. To override the bundled runtime manually, replace the files in the corresponding canhub/zlg/<arch> directory while preserving the zlgcan.dll + sibling kerneldlls layout.

Register

using CanHub;
using CanHub.Adapter.Zlg;

var registry = CanHubRegistry.CreateDefault()
    .AddZlgAdapter();

Endpoint Format

zlg://{deviceType}?deviceIndex={index}&channelIndex={channelIndex}

Example:

zlg://USBCANFD_200U?deviceIndex=0&channelIndex=0

Prefer ZlgEndpoint when opening a fixed device from configuration:

CanEndpoint endpoint = ZlgEndpoint.UsbCanFd200U(deviceIndex: 0, channelIndex: 0);

The first supported device family is USBCANFD_200U. The adapter accepts legacy channel as a compatibility alias for channelIndex. Device index and channel numbering follow the ZLG runtime. If the channel came from ScanAsync, prefer the scanned CanChannelInfo.Endpoint or CanChannelInfo.CanonicalEndpoint instead of rebuilding it manually.

Usage

var scan = await registry.ScanAsync(new ScanOptions(), CancellationToken.None);

await using var bus = await registry.OpenAsync(
    ZlgEndpoint.UsbCanFd200U(deviceIndex: 0, channelIndex: 0),
    new CanOpenOptions { BusParameters = CanBusParameters.Classic500k },
    CancellationToken.None);

Use CanOpenOptions.BusParameters for CAN FD when the target channel is configured for CAN FD, for example CanBusParameters.Fd500k2M.

Diagnostics

Use ZlgDiagnostics.CheckRuntimeAsync before opening a channel when you want to verify the Windows platform, native runtime files, DLL loading, and device scan path:

var report = await ZlgDiagnostics.CheckRuntimeAsync(ct: CancellationToken.None);

if (!report.IsReady)
{
    foreach (var diagnostic in report.Diagnostics)
        Console.WriteLine($"{diagnostic.Category}: {diagnostic.Message} {diagnostic.Hint}");
}

The diagnostic check loads the ZLG native runtime and scans devices, but it does not open a specific channel. report.HasOpenableChannel indicates whether scanning found at least one channel that CanHub can try to open.

Recovery

ZLG recovery is opt-in through CanOpenOptions.Recovery. The default is CanRecoveryOptions.Disabled, which reports bus/native errors without closing or reopening the channel.

When enabled, the adapter reuses the original open configuration and performs channel-level close/reopen recovery:

await using var bus = await registry.OpenAsync(
    "zlg://USBCANFD_200U?deviceIndex=0&channelIndex=0",
    new CanOpenOptions
    {
        BusParameters = CanBusParameters.Classic500k,
        Recovery = ZlgRecoveryProfiles.BusFaultBackoff
    });

ZlgRecoveryProfiles.Disabled is the default no-reopen policy. ZlgRecoveryProfiles.BusFaultBackoff covers common ZLG bus/native receive/transmit faults with a 500ms initial delay and three attempts. ZlgRecoveryProfiles.ConservativeBench waits longer and allows more attempts for bench setups. You can still use CanRecoveryOptions.ResetOnFault or CanRecoveryOptions.ReopenWithBackoff directly when you need custom triggers or delays.

Observed on USBCANFD_200U: after error injection or fast close/reopen cycles, the native driver can keep transient state briefly after ZCAN_ResetCAN/ZCAN_CloseDevice has returned. Direct test runs may hit ZCAN_StartCAN Error (0), while debugger-paced runs or added delay avoid it. The ZLG adapter therefore keeps a 500ms native-close settle window before automatic recovery reopen: caller-provided RestartDelay values above 500ms are honored, while smaller values, including TimeSpan.Zero, are raised to 500ms. If ZCAN_StartCAN returns Error (0), the adapter resets the channel, waits 500ms, and retries the start up to six attempts; if that handle still cannot start, it resets the handle and retries the full channel initialization up to three times. This covers both initial open and recovery reopen.

Hardware Tests

Hardware tests are skipped unless explicitly enabled:

$env:CANHUB_TEST_ZLG = "1"
$env:CANHUB_TEST_ZLG_DEVICE0 = "0"
$env:CANHUB_TEST_ZLG_DEVICE1 = "1"
$env:CANHUB_TEST_ZLG_BUS1_CHANNEL = "0"
$env:CANHUB_TEST_ZLG_BUS2_CHANNEL = "1"
dotnet test tests/CanHub.Adapter.Zlg.Tests/CanHub.Adapter.Zlg.Tests.csproj -c Release

Keep this variable disabled in normal CI unless the runner has a supported ZLG device and driver installed.

The recovery hardware tests assume two USBCANFD_200U devices and two buses: one terminated bus for normal traffic and single-node No ACK recovery, and one unterminated bus for stable bit/native bus error recovery.

Vector interop hardware tests additionally require CANHUB_TEST_VECTOR=1. By default they use VN5610A device index 0, channel 2, and assume that Vector channel is connected to Bus1; override with CANHUB_TEST_VECTOR_DEVICE, CANHUB_TEST_VECTOR_DEVICE_INDEX, and CANHUB_TEST_VECTOR_CHANNEL_INDEX. To run the Bus2 unterminated Vector recovery test, also set CANHUB_TEST_VECTOR_BUS2=1 and connect the Vector channel to Bus2.

ZLG open-order diagnostics additionally require CANHUB_TEST_ZLG_OPEN_DIAGNOSTICS=1. This diagnostic only opens and closes the two ZLG devices on Bus1 without transmitting frames; set CANHUB_TEST_ZLG_OPEN_DIAG_ITERATIONS to change the repeat count when investigating whether simultaneously opened device channels affect each other.

When direct runs fail but debugger runs pass, use CANHUB_TEST_ZLG_OPEN_DIAG_STEP_DELAY_MS to add an operation delay that simulates debugger pacing. For finer control, CANHUB_TEST_ZLG_OPEN_DIAG_INTER_OPEN_DELAY_MS waits after opening the first channel and before opening the second channel, while CANHUB_TEST_ZLG_OPEN_DIAG_AFTER_CLOSE_DELAY_MS waits after each channel close. In this hardware round, before the StartCAN retry was added, open-order diagnostics after bus-error injection could still reproduce ZCAN_StartCAN Error (0) for deviceIndex=1&channelIndex=0 with 500ms, 2000ms, and even 5000ms post-close delays. After adding the StartCAN retry, both the unpaced diagnostic and the 2000ms post-close paced diagnostic passed. This diagnostic covers repeated manual close/open cycles across different ZLG devices, so it is recorded separately from the automatic same-channel recovery path.

You can also use the checked-in diagnostics settings file instead of setting environment variables manually:

dotnet test tests/CanHub.Adapter.Zlg.Tests/CanHub.Adapter.Zlg.Tests.csproj `
  --settings tests/zlg-open-diagnostics.runsettings `
  --filter "FullyQualifiedName~ZlgOpenDiagnosticsHardwareTests" `
  --logger "console;verbosity=detailed"

To compare against debugger-like pacing, run the settings file that waits 2000ms after each channel close:

dotnet test tests/CanHub.Adapter.Zlg.Tests/CanHub.Adapter.Zlg.Tests.csproj `
  --settings tests/zlg-open-diagnostics-paced.runsettings `
  --filter "FullyQualifiedName~ZlgOpenDiagnosticsHardwareTests" `
  --logger "console;verbosity=detailed"

Third-Party Runtime

This package may include or load ZLG runtime files needed by the adapter. Installing or using ZLG drivers may require accepting ZLG's own license terms.

License

This package is licensed under the Apache License 2.0.

Product Compatible and additional computed target framework versions.
.NET 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.

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
1.0.1 95 6/1/2026
1.0.0-preview.8 56 5/25/2026
1.0.0-preview.7 56 5/23/2026
1.0.0-preview.6 52 5/21/2026
1.0.0-preview.5 45 5/21/2026
1.0.0-preview.4 51 5/21/2026
1.0.0-preview.3 53 5/20/2026
1.0.0-preview.2 55 5/19/2026
1.0.0-preview.1 51 5/15/2026

CAN/CAN FD access via zlgcan.dll.