dmcan —— DM USB CAN/CAN FD 设备 Python SDK
libdmcan 的 Python 封装(纯 ctypes,无编译依赖):设备枚举与打开、通道与位定时、CAN / CAN FD 收发、
周期与批量发送、真 echo、硬件过滤表、USB2UART 透传、热插拔与日志订阅。
兼容性
| Python 包 | 需要的 libdmcan |
|---|---|
| 2.1.x | 2.1.0 |
- 构造
DmCanContext时会校验后端库:主版本必须一致、次版本不低于 2.1; 不配套会立刻报错(缺符号会点名是哪个),不会静默读到错位数据; - 版本对齐规则:包版本的 major.minor 跟随所绑定的 libdmcan(当前
2.1);仅 Python 侧的修正抬 PATCH 位(如2.1.0→2.1.1),不改变所支持的 ABI。
安装
要求 Python 3.9+(3.9 / 3.12 / 3.13 均已实测)。
pip install dmcan_sdk
wheel 是纯 Python 的:后端动态库(libdmcan)不在 PyPI 上,需要从 SDK 交付包获取
(版本要和上表匹配),然后按下一节的方式让 SDK 找到它。
后端动态库(libdmcan)怎么找
按顺序找,命中第一个就用:
- 环境变量
DMCAN_LIBRARY_PATH指向的完整路径; - 包内
dmcan/dlls/(libdmcan.dll/dmcan.dll/libdmcan.so/libdmcan.dylib); - 当前程序目录下的
dlls/; - 当前程序目录;
- 交给系统搜索路径。
Windows 上 libdmcan.dll 还依赖 libusb-1.0.dll、libstdc++-6.dll、libgcc_s_seh-1.dll、
libwinpthread-1.dll,要和它放在同一个目录:SDK 会把该目录加进 DLL 搜索路径。
快速上手
from dmcan import DmCanContext, dmcan_event_flag
with DmCanContext() as ctx: # 自动找库;不配套会在这里抛错
if ctx.find_devices() == 0:
raise SystemExit("没有找到设备")
dev = ctx.get_device(0)
print(dev.get_info()) # 型号 / VID / PID / 序列号
dev.open() # 注意:会独占设备的 UART COM 口(默认自动打开 UART)
print(dev.get_version()) # 例如 USB2CANFD_S V2.0.0 [efe47b5 2026-10-10 16:49:42]
sub = dev.subscribe(dmcan_event_flag.RX_FRAME, lambda d, e: print(e.frame))
dev.enable_channel(0, True)
dev.send_can(0, 0x123, b"\x01\x02\x03\x04", canfd=True, brs=True)
sub.cancel()
dev.close()
几条容易踩的:
- 失败一律抛
DmCanError(exc.status是dmcan_status错误码),不再返回False; open()默认会独占设备的 UART COM 口,此时串口助手 / 别的程序打不开;- 通道参数默认只改运行期,掉电就回:要保留得调
save_param(); get_channel_stats()在固件首条周期上报(1 Hz)到达前返回None,那是“还没有值”不是失败;- 看门狗使能后由 SDK 按超时的一半周期喂狗;老固件上“关狗”命令可能被拒,
此时会话结束后通道会被咬,重新
enable_channel()(或给设备断电)即可恢复; - 通道开 / 关(
enable_channel/disable_channel)要求固件回 2 字节{操作结果, 状态}应答: 老固件回 1 字节时这两个接口会返回 false(库会打 ERROR 日志提示升级固件)。
从 1.x 升级到 2.x(接口不兼容)
| 旧写法(1.0.x) | 新写法(2.x) |
|---|---|
后端库 libdm_device.dll |
libdmcan.dll(文件名变了) |
send_can(ch, id, dlen, payload, ...) |
send_can(ch, id, payload, ...)(长度由 payload 决定) |
usb_rx_frame / frame.head.dlc |
dmcan_rx_frame / frame.dlen(字节长度) |
device.print_version() |
device.get_version()(读固件信息并格式化) |
dmcan_channel_can_config |
dmcan_ch_baud_conf |
失败返回 False |
失败抛 DmCanError |
包内结构
dmcan/dmcan_def.py ABI 类型与常量(结构体 / 枚举 / 回调原型)
dmcan/dmcan_device.py 设备级接口(通道、波特率、收发、订阅、诊断、UART)
dmcan/dmcan_context.py 上下文、后端库查找与加载、设备枚举、日志与热插拔
示例与其它语言的 SDK(C/C++、C#、Rust)见发布仓:https://gitee.com/kit-miao/dm-device-sdk
许可证
本项目采用 Apache License 2.0:完整文本随发行包分发(wheel 里的
dmcan_sdk-<版本>.dist-info/licenses/LICENSE、sdist 根目录的 LICENSE)。
Metadata
Release files for dmcan-sdk 2.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dmcan_sdk-2.1.1.tar.gz | 36.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dmcan_sdk-2.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 72.5 kB
Release files / dmcan_sdk-2.1.1.tar.gz
| Download URL | dmcan_sdk-2.1.1.tar.gz |
|---|---|
| Size | 36.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
38d2a42e788f21ff3181e95aff4c9710739ede186890fed57104e03558ed5041
|
|
BLAKE2b-256 checksum How to use checksums |
738728fd0441a9071049525cf73b7ac88d59402b1908d646549ee16f581e9b48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|
Release files / dmcan_sdk-2.1.1-py3-none-any.whl
| Download URL | dmcan_sdk-2.1.1-py3-none-any.whl |
|---|---|
| Size | 36.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6dc5ed843a4d6c9e2187eaabcc76f580e69f52bb22d1f66f999ca9925a34e534
|
|
BLAKE2b-256 checksum How to use checksums |
46d1a74cb2676e2e565ca5b58c58a13bb114092d4e4e6b9f5fd6dc4f68089af7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.5
|