8 releases

0.1.7 Mar 3, 2024
0.1.6 Feb 2, 2024
0.1.5 Jan 31, 2024
0.1.3 Dec 27, 2023
0.1.0 Oct 8, 2023

#136 in Hardware support

Download history 9/week @ 2023-12-22 11/week @ 2023-12-29 128/week @ 2024-01-05 406/week @ 2024-01-12 453/week @ 2024-01-19 416/week @ 2024-01-26 419/week @ 2024-02-02 381/week @ 2024-02-09 539/week @ 2024-02-16 809/week @ 2024-02-23 933/week @ 2024-03-01 970/week @ 2024-03-08 740/week @ 2024-03-15 679/week @ 2024-03-22 1155/week @ 2024-03-29 758/week @ 2024-04-05

3,452 downloads per month
Used in 14 crates (6 directly)

Apache-2.0 OR MIT

270KB
6K SLoC

nusb

A new pure-Rust library for cross-platform low-level access to USB devices.

Documentation

Compared to rusb and libusb

  • Pure Rust, no dependency on libusb or any other C library.
  • Async-first, while not requiring an async runtime like tokio or async-std. Still easily supports blocking with futures_lite::block_on.
  • No context object. You just open a device. There is a global event loop thread that is started when opening the first device.
  • Thinner layer over OS APIs, with less internal state.

Current status

  • Support for Linux, Windows, and macOS
  • Device listing and descriptor parsing
  • Transfers on control, bulk and interrupt endpoints
  • Used in production by probe-rs and others, but still relatively new. Please test with your device and report issues.

License

MIT or Apache 2.0, at your option


lib.rs:

A new library for cross-platform low-level access to USB devices.

nusb is comparable to the C library libusb and its Rust bindings rusb, but written in pure Rust. It's built on and exposes async APIs by default, but can be made blocking using futures_lite::future::block_on or similar.

Use nusb to write user-space drivers in Rust for non-standard USB devices or those without kernel support. For devices implementing a standard USB class such as Mass Storage, CDC (Serial), HID, Audio, or Video, this is probably not the library you're looking for -- use something built on the existing kernel driver instead. (On some platforms you could detach or replace the kernel driver and program the device from user-space using this library, but you'd have to re-implement the class functionality yourself.)

USB and usage overview

When a USB device connects, the OS queries the device descriptor containing basic device information such as the vendor and product ID (VID / PID) and string descriptors like the manufacturer, product, and serial number strings. list_devices returns an iterator listing connected USB devices, which can be filtered by these fields to identify and select the desired device.

Call device_info.open() to open a selected device. Additional information about the device can be queried with device.active_configuration().

USB devices consist of one or more interfaces exposing a group of functionality. A device with multiple interfaces is known as a composite device. To open an interface, call Device::claim_interface. Only one program (or kernel driver) may claim an interface at a time.

Use the resulting Interface to transfer data on the device's control, bulk or interrupt endpoints. Transfers are async by default, and can be awaited as individual Futures, or use a Queue to manage streams of data.

For more details on how USB works, USB in a Nutshell is a good overview.

Logging

nusb uses the log crate to log debug and error information.

When submitting a bug report, please include the logs: use a log backend like env_logger and configure it to enable log output for this crate (for env_logger set environment variable RUST_LOG=nusb=debug.)

Platform support

Linux

nusb is built on the kernel's usbfs API.

A user must have write access on the /dev/bus/usb/XXX/YYY nodes to successfully open a device. Use udev rules to configure these permissions.

For a single-user system used for development, it may be desirable to give your user account access to all USB devices by placing the following in /etc/udev/rules.d/70-plugdev-usb.rules:

SUBSYSTEM=="usb", MODE="0660", GROUP="plugdev"

This grants access on all USB devices to the plugdev group, which your user may be a member of by default on Debian/Ubuntu-based distros. If you are developing an app for others to install, you should scope the permissions more narrowly using the ATTRS{idVendor}=="ZZZZ", ATTRS{idProduct}=="ZZZZ" filters to only apply to your device.

Windows

nusb uses WinUSB on Windows.

On Windows, devices are associated with a particular driver, which persists across connections and reboots. Composite devices appear as multiple devices in the Windows device model, and each interface can be associated with a separate driver.

To use nusb, your device or interface must be associated with the WinUSB driver. If you control the device firmware, the recommended way is to use a WCID descriptor to tell Windows to install the WinUSB driver automatically when the device is first connected. Alternatively Zadig (GUI) or libwdi (CLI / C library) can be used to manually install the WinUSB driver for a device.

macOS

nusb uses IOKit on macOS.

Users have access to USB devices by default, with no permission configuration needed. Devices with a kernel driver are not accessible.

Dependencies

~0.1–12MB
~114K SLoC