doc/help/Drivers-USB.md
The Raw USB driver talks to USB devices directly through libusb, bypassing the operating system's class drivers. It is the right driver when a device exposes vendor-specific bulk, control, or isochronous endpoints rather than presenting itself as a serial port (CDC), an HID device, or a mass-storage volume.
If the device shows up as a virtual COM port, use the UART driver. For gamepads, joysticks, or HID firmware, use the HID driver. This page covers everything else: logic analysers, oscilloscopes, custom data-acquisition boards, vendor-specific scientific instruments, and any device whose datasheet says "uses bulk endpoints".
USB is layered. From the bottom up:
Almost every consumer USB device implements one of the standard classes. The OS bundles a generic driver for each class, so plugging in a USB-CDC microcontroller exposes a COM port without any extra install.
Vendor-specific USB devices skip the standard classes. They expose endpoints with custom semantics that the OS does not know how to interpret. libusb is a userspace library that lets an application open such a device and talk to its endpoints directly.
Every USB device has at least one endpoint (endpoint 0, the control endpoint). Most devices have several. Endpoints are unidirectional buffers identified by a number and a direction (IN = device to host, OUT = host to device).
Each endpoint is configured for one of four transfer types:
flowchart TB
USB[USB transfer types]
USB --> CTRL[Control
EP0 always; bidirectional
config, descriptors, setup]
USB --> BULK[Bulk
large data, no timing guarantee
guaranteed delivery]
USB --> INT[Interrupt
small periodic data
guaranteed latency]
USB --> ISO[Isochronous
continuous streaming
no retransmission, no checksum]
For Serial Studio's USB driver, the relevant types are bulk (the default, for streaming captured data), isochronous (for high-rate continuous streams where dropped frames are acceptable), and control (vendor-specific commands, available in Advanced mode).
A USB device describes itself through a tree of descriptors:
flowchart TD
Device[Device Descriptor
VID, PID, USB version]
Device --> Cfg[Configuration Descriptor
power requirements]
Cfg --> If1[Interface Descriptor
logical function]
If1 --> EP1[Endpoint Descriptor
EP1 IN, bulk, 64 bytes]
If1 --> EP2[Endpoint Descriptor
EP2 OUT, bulk, 64 bytes]
Cfg --> If2[Interface Descriptor
another function]
If2 --> EP3[Endpoint Descriptor
EP3 IN, interrupt, 8 bytes]
The host queries the device for its descriptor tree on enumeration, decides what to do with it, and binds drivers accordingly. A vendor-specific bulk device usually has one configuration, one interface, and a couple of endpoints (one IN for reading, one OUT for writing).
Every USB device has a Vendor ID (VID) and Product ID (PID), both 16-bit. VIDs are assigned by the USB-IF; PIDs are chosen by the vendor. Together they uniquely identify a device model. Serial Studio lists USB devices as VID:PID, followed by the manufacturer and product strings when the device reports them (for example 1234:5678 – Acme Logic Analyzer).
The USB driver wraps libusb. The setup flow is:
EP 0x81 – Bulk IN (IF0, max 64 B). The first endpoint matching the transfer mode is selected automatically; OUT Endpoint defaults to None (Read-only) when no matching OUT endpoint exists.The USB driver runs two dedicated threads:
Each completed transfer carries a timestamp captured at completion time and is queued to the main thread for FrameReader processing. See Threading and Timing Guarantees.
USB device access is permission-controlled differently on each OS:
root can open arbitrary USB devices. Add a udev rule granting the user access to a specific VID:PID:
/etc/udev/rules.d/99-myusbdevice.rules:
SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTR{idProduct}=="5678", MODE="0666"
sudo udevadm control --reload-rules && sudo udevadm trigger. Serial Studio enables libusb's auto-detach on Linux, so a kernel class driver bound to the interface (for example cdc_acm) is detached automatically when the interface is claimed and re-attached on release.For step-by-step setup, see the Protocol Setup Guides, Raw USB section.
The TCP API and the in-app AI assistant configure this driver through the io.usb.* scope:
| Command | Parameters | Notes |
|---|---|---|
io.usb.listDevices | none | Returns devices array and selectedIndex (index 0 is the "Select Device" placeholder) |
io.usb.setDeviceIndex | deviceIndex (integer) | Selects a device by list index |
io.usb.setTransferMode | mode (0 = Bulk Stream, 1 = Advanced, 2 = Isochronous) | |
io.usb.setInEndpointIndex | endpointIndex (integer) | Endpoint lists populate when the device connects |
io.usb.setOutEndpointIndex | endpointIndex (integer) | Index 0 is "None (Read-only)" |
io.usb.setIsoPacketSize | size (1 to 49152 bytes) | |
io.usb.getConfig | none | Returns mode, indices, packet size, and both endpoint lists |
Transport details and command safety tiers are in the API Reference.
lsusb shows the device; lsusb -v -d VID:PID shows its descriptor. If lsusb works but Serial Studio does not see the device, it is a permissions problem.dmesg | grep usb for hints and close other applications using the device.sudo udevadm trigger.