Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

python-can-busmust

Alpha release: 0.1.0a1. Not yet validated on physical hardware. The software tests use simulated USB devices. APIs and firmware compatibility may change as real-adapter testing proceeds. This is an independent project, not an official BUSMUST release.

A native Python/PyUSB driver for BUSMUST USB CAN and CAN FD adapters. It talks directly to the device protocol described by the bmsocketcan reference; it does not load the BMAPI shared library or require SocketCAN.

The installed package registers interface="busmust" with python-can using its plugin interface. Standard can.Message, software filters, Notifier, logging, asynchronous listeners, ThreadSafeBus, and software periodic transmission are supported. Libraries accepting a can.BusABC, such as can-isotp and cantools, can use this bus directly. See the protocol analysis for implementation details and differences from the kernel driver.

Install

Python 3.9 or newer and a libusb backend are required:

# macOS
brew install libusb

# Debian/Ubuntu
sudo apt install libusb-1.0-0

# Install the alpha from PyPI, in your Python environment
python -m pip install --pre python-can-busmust

# Or pin this release
python -m pip install python-can-busmust==0.1.0a1

On Windows, install a libusb-compatible driver (usually WinUSB via Zadig) for the adapter's CAN interface 0 and make libusb available to PyUSB. For a composite device, keep the other interfaces intact. Switching to WinUSB may prevent the vendor application's driver from opening that interface. Consult the PyUSB installation guide for backend setup.

On Linux, grant your user access to the adapter, for example with a udev rule SUBSYSTEM=="usb", ATTR{idVendor}=="0810", MODE="0660", TAG+="uaccess". Reload udev rules and reconnect the adapter. Stop applications using its kernel CAN interfaces before opening it with detach_kernel_driver=True. The default refuses to detach an active kernel driver; an explicitly detached driver is reattached when the last bus on that adapter shuts down.

Send and receive

import can

with can.Bus(interface="busmust", channel=0, bitrate=500_000,
             fd=True, data_bitrate=2_000_000, termination=120) as bus:
    bus.send(can.Message(arbitration_id=0x123, is_extended_id=False,
                         data=[0xDE, 0xAD, 0xBE, 0xEF]), timeout=0.5)
    message = bus.recv(timeout=1.0)
    print(message)

Channels are zero-based. Set bitrates, sample points, and termination to match the physical bus. termination=None preserves the device setting; use 0 to disable or 120 to enable its resistor.

configs = can.detect_available_configs(interfaces=["busmust"])
print(configs)

# Select an adapter explicitly when more than one is attached.
bus = can.Bus(interface="busmust", channel=0, serial="YOUR_SERIAL",
              bitrate=500_000)
try:
    bus.set_filters([{"can_id": 0x700, "can_mask": 0x700, "extended": False}])
    print(bus.get_status())
finally:
    bus.shutdown()

Separate channels on the same adapter share a USB reader and have independent receive queues. Open each channel once per process; different processes cannot share the adapter. Closing one channel leaves the others running.

with can.Bus(interface="busmust", channel=0) as first, \
     can.Bus(interface="busmust", channel=1) as second:
    listener = can.BufferedReader()
    notifier = can.Notifier(second, [listener])
    try:
        task = first.send_periodic(
            can.Message(arbitration_id=0x123, is_extended_id=False, data=[1]),
            period=0.1,
        )
        print(listener.get_message(timeout=1.0))
        task.stop()
    finally:
        notifier.stop()

This example requires a two-channel adapter and a correctly wired bus between the channels. examples/loopback.py provides a single-channel firmware loopback smoke test. No hardware transmissions are needed to run the automated tests.

Options

Argument Default Meaning
channel 0 Zero-based physical CAN port; numeric strings accepted
bitrate 500_000 Arbitration bitrate in bit/s; whole kbit/s
fd False Enable CAN FD alongside Classical CAN
data_bitrate 2_000_000 CAN FD data bitrate in bit/s
sample_point 87.5 Arbitration sample point in percent
data_sample_point 80.0 Data sample point in percent
termination None Preserve, disable (0), or enable (120) termination
serial None Exact USB serial number
product_id None Integer USB product ID
usb_bus, usb_address None USB location selectors returned by discovery
listen_only False Receive without acknowledging; sending rejected
loopback False Internal firmware loopback
receive_own_messages False Request and deliver firmware TX echoes as is_rx=False
non_iso False Non-ISO CAN FD mode; requires fd=True
one_shot False Disable firmware automatic retransmission
can_filters None Standard python-can software filters
rx_queue_size 10_000 Maximum buffered frames per channel
detach_kernel_driver False Explicitly allow temporary USB interface detachment

The reference protocol encodes sample points as integer percentages, so 87.5 is sent as 87. Explicit can.BitTiming/BitTimingFd configuration is unsupported. Validation checks the wire format's range; firmware determines supported rates.

Supported device IDs

All use USB vendor ID 0810. These are the reference implementation's mappings; listing an ID is not a claim of hardware validation.

Generation Product Product ID CAN channels
2 X1 / X1 Pro F012 / F112 1
2 X2 / X4 / X8 Pi F122 / F142 / F182 2 / 4 / 8
2.5 X2R / X4R E122 / E142 2 / 4
3 X1 / X2 / X4 F013 / F023 / F043 1 / 2 / 4
3 XL2 / XL4 0043 / 0083 2 / 4

Behavior and limits

  • send() waits for USB submission, not a CAN-bus acknowledgment. timeout is in seconds; None uses a 1-second USB transfer timeout, and 0 uses a minimum 1 ms because libusb interprets zero as infinite. Partial writes are reported and never retried automatically. A timed-out transfer may have sent data; avoid blind retries for commands with side effects.
  • CAN FD payloads between legal DLC lengths are zero-padded to the next legal length. Receiving reports the on-wire length, e.g. 9 transmitted bytes become a 12-byte frame. RTR messages retain their requested DLC and have empty data.
  • Gen3 timestamp tails provide UTC microseconds. Older devices' wrapping microsecond clocks are anchored to host epoch time on the first received frame; absolute accuracy includes USB latency. Echoes do not advance the receive timestamp tracker. Clock reset requires reopening the adapter.
  • USB disconnects, malformed CAN envelopes, and queue overflow raise can.CanOperationError. Overflow fails the affected channel rather than silently dropping frames. Reopen failed channels; reconnect all channels after a USB session failure. Stop Notifier before shutting down its bus.
  • Status flags/counters are available through get_status() and bus.state. This driver does not synthesize SocketCAN error frames or implement the kernel driver's firmware-specific bus-off recovery procedures.
  • Hardware TX tasks, routes, offline logging/replay, persistent configuration, PTP synchronization, and hardware acceptance-filter optimization are outside this implementation. Periodic sending and filtering run in Python.
  • No physical adapter validation or throughput guarantees are claimed. Firmware echo behavior and cross-platform backend setup need hardware verification.

Development and hardware feedback

Clone the repository before running the development commands:

git clone https://github.com/madprogrammer/python-can-busmust.git
cd python-can-busmust
python -m pip install -e '.[test]'
python -m pytest
python -m build

Tests use the real python-can and PyUSB packages with a simulated USB device. They cover protocol vectors, shared-channel lifecycle, transfer failures, timestamps, plugin discovery, and python-can listener/periodic APIs.

For hardware reports, include the model/product ID, firmware version, OS, Python version, bitrate/sample-point settings, and a minimal reproduction in a GitHub issue. Start with python examples/loopback.py, then test a correctly terminated two-node bus. Internal loopback alone does not establish physical-bus operation.

License and provenance

GPL-2.0-or-later, see LICENSE. Protocol behavior was derived from the GPL-licensed bmsocketcan/src/bmcan_proto.c, bmcan_usb.c, bmcan_netdev.c, and inc/bmcan_core.h (BUSMUST, 2026), at upstream commit 70919fbc2a1be146498ca0df941d1d8a0a93c74b. A local reference clone may be kept in the ignored bmsocketcan/ directory. Its separately licensed vendor headers are not copied into or required by this Python distribution.

Metadata

Release files for python-can-busmust 0.1.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-can-busmust 0.1.0a1
File Size Uploaded
python_can_busmust-0.1.0a1.tar.gz 33.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-can-busmust 0.1.0a1
File Interpreter ABI Platform
python_can_busmust-0.1.0a1-py3-none-any.whl Python 3 none any Details

Total release size: 55.7 kB

Release files / python_can_busmust-0.1.0a1.tar.gz

Download URL python_can_busmust-0.1.0a1.tar.gz
Size 33.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4d1842de50472d1c544496e82cd2f97923de0c0190aa6ec6723afa99cbae2bca
BLAKE2b-256 checksum
How to use checksums
735e2822b58d721b6ab53105e8c4f4f5a3c73b06e6ea3908ae1288c584fd13bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / python_can_busmust-0.1.0a1-py3-none-any.whl

Download URL python_can_busmust-0.1.0a1-py3-none-any.whl
Size 21.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fbcafb1464fd74791bd85b10c5e004ed3fe1b8ef212d024153aaa0b0f68d4170
BLAKE2b-256 checksum
How to use checksums
ed15771a823924bb7281e86128a230b4c74cb9f9bd73d80256b11b5988d1417e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.1.0

2 release files

This release

0.1.0a1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page