| Crates.io | crab-usb |
| lib.rs | crab-usb |
| version | 0.3.10 |
| created_at | 2025-07-31 09:45:37.597885+00 |
| updated_at | 2025-09-03 02:53:33.848966+00 |
| description | A usb host for embedded systems, written in Rust. |
| homepage | |
| repository | https://github.com/drivercraft/CrabUSB |
| max_upload_size | |
| id | 1774767 |
| size | 258,164 |
A USB Host driver implementation written in Rust for embedded systems.
CrabUSB is a no_std USB Host driver library that provides async support for USB device communication. It currently supports xHCI (Extensible Host Controller Interface) and is designed for embedded systems and operating system kernels.
no_std compatible with minimal memory footprintThe driver uses a lock-free design based on TRB (Transfer Request Block) rings, where each TRB represents an async task. The future queries the ring to get async results without requiring a specific executor.
setup dma-api
implement the Kernel trait for your system
use crab_usb::*;
// Implement the Kernel trait for your system
struct KernelImpl;
impl_trait! {
impl Kernel for KernelImpl {
fn sleep<'a>(duration: Duration) -> BoxFuture<'a, ()> {
your_os::sleep(duration).boxed()
}
fn page_size() -> usize {
your_os::page_size()
}
}
}
// Initialize USB host controller
let mut host = USBHost::new_xhci(mmio_base);
let handle = host.event_handler();
// Handle USB events in your OS irq callback
your_os::register_irq_handler(usb_irq, move || {
handle.handle_event();
});
host.init().await?;
// Probe for connected devices
let devices = host.device_list().await.unwrap();
for mut device in devices {
println!("Device: {:?}", device);
// Claim an interface
let mut interface = device.claim_interface(0, 0).await?;
// Get endpoint for bulk transfers
let mut bulk_in = interface.endpoint_bulk_in(0x81)?;
// Perform data transfer
let mut data = vec![0u8; 64];
bulk_in.submit(&mut data)?.await?;
// submit batch
let mut datas = vec![vec![0u8; 64]; 10];
let mut results = Vec::new();
for data in datas.iter_mut() {
let res = bulk_in.submit(data)?;
results.push(res);
}
// Wait for all transfers to complete
for res in results {
res.await?;
}
}
cargo install ostool
cargo test -p crab-usb --test test --target aarch64-unknown-none-softfloat -- --show-output
cargo test --release --test test -- --show-output --uboot
lsusb
for example, to find the device of a webcam:
Bus 003 Device 038: ID 1b17:0211 Sonix Technology Co., Ltd. GENERAL WEBCAM
add the following line to bare-test.toml:
args = "-usb -device qemu-xhci,id=xhci -device usb-host,bus=xhci.0,vendorid=0x1b17,productid=0x0211"
Then run the test
if no device is found, you may do not have the permission to access the USB device, you can run the following command to add permission:
sudo chmod 666 /dev/bus/usb/003/038
or you can add rules to /etc/udev/rules.d/99-usb.rules:
SUBSYSTEM=="usb", ATTR{idVendor}=="1b17", ATTR{idProduct}=="0211", GROUP="plugdev", MODE="660"
then reload udev rules:
sudo usermod -aG plugdev $USER
sudo udevadm control --reload-rules
sudo udevadm trigger
check if the device is accessible:
ls -l /dev/bus/usb/003/038
Contributions are welcome! Please ensure that:
cargo clippyThis project is licensed under the MIT License - see the LICENSE file for details.