macOS Apple Silicon Native

zlgcan

在 Mac 上直接使用周立功 USBCANFD-100U-mini 分析仪,无需 Windows、无需虚拟机,纯 Python 原生驱动。

pip install zlgcan
🔌

即插即用

插上 USBCANFD-100U-mini,运行 zlgcan monitor,直接看数据。无需安装驱动、无需配置。

🚀

CAN FD 5Mbps

完整支持 CAN FD 协议,仲裁域 1Mbps + 数据域 5Mbps,BRS 加速,64 字节数据帧。

🍎

Apple Silicon 原生

专为 Mac M1/M2/M3/M4/M5 芯片设计,纯 Python 实现,无需 x86 模拟,零延迟。

🔓

逆向工程驱动

通过深度逆向 ZLG 闭源协议实现,包含 AES 认证、UCFD 命令协议、CRC16 校验。

30 秒上手

安装、插入设备、运行 — 就这么简单。

Terminal
# 安装依赖
$ brew install libusb
$ pip install zlgcan

# 实时监听 CAN FD 数据
$ zlgcan monitor
设备: USBCANFD-100U-mini  SN: 7C798CEF50B20BB461A0  FW: V2.38
波特率: 1m_5m  通道: 0

  FD BRS  0x082  [24]  D7 FE FF FF 00 00 00 00 3B 02 00 00 ...
  FD BRS  0x07F  [24]  FF FF FF FF FF FF FF FF FF FF FF FF ...
  FD BRS  0x5FE  [24]  B4 00 00 00 00 00 00 00 D1 FF FF FF ...
  FD BRS  0x087  [ 5]  45 C9 00 00 00

# 发送 CANFD 帧
$ zlgcan send 0x7F 0102030405060708

# candump 兼容格式
$ zlgcan monitor -f candump
  can0  082#B   [24]  D8 FE FF FF 00 00 00 00 49 02 00 00 ...
  can0  07F#B   [24]  FF FF FF FF FF FF FF FF FF FF FF FF ...

# 过滤特定 ID
$ zlgcan monitor --filter 0x7F

工作原理

通过逆向工程实现的完整 USB 协议栈

1

USB 枚举

自动发现 VID:3068 PID:0009 设备并 claim 接口

2

AES 认证

AES-128-ECB 挑战-响应握手,激活设备固件

3

CAN 初始化

配置波特率、终端电阻、启动 CAN 控制器

4

实时数据流

EP83 持续接收 CANFD 帧,解析并输出

协议架构

┌──────────────────────────────────┐
│         Mac (Python + pyusb)     │
│                                  │
│  zlgcan CLI                      │
│    ├── AES-128 认证              │
│    ├── UCFD_CMD 协议             │
│    │    EP01 OUT ──→ 命令        │
│    │    EP81 IN  ←── 响应        │
│    └── CAN 数据流                │
│         EP83 IN  ←── CANFD 帧    │
│                                  │
│  USB (libusb)                    │
└──────────┬───────────────────────┘
           │
    USBCANFD-100U-mini
           │
       CAN FD 总线

Python API

也可以作为库直接调用

from zlgcan import USBCANFD

# 打开设备并初始化
with USBCANFD() as can:
    can.start("1m_5m")  # 1Mbps 仲裁 + 5Mbps 数据

    # 接收帧
    frames = can.read_frames(timeout=1000)
    for f in frames:
        print(f"ID=0x{f.can_id:03X} DLC={f.dlc} DATA={f.data.hex()}")

    # 发送帧
    can.send_frame(0x7F, b"\x01\x02\x03", brs=True)