libusb 1.0.0 clib Hardware — USB

USB device access from userspace. Enumerate, open, claim interfaces, and perform control, bulk, interrupt, and isochronous transfers — no kernel driver required.

ppm install libusb

What is libusb?

libusb wraps libusb-1.0 — the de-facto standard C library for USB device access from userspace. It lets you communicate with any USB device without writing a kernel driver, provided you have the right permissions. It is cross-platform: Linux (via usbfs), macOS (IOKit), and Windows (via WinUSB or libusb-win32).

Well-known projects built on libusb include OpenOCD (on-chip debugging), sigrok (logic analyzers & oscilloscopes), librealsense (Intel RealSense depth cameras), libfprint (fingerprint readers), and USBView.

CLib package

Requires libusb-1.0-0-dev. Ubuntu/Debian: sudo apt install libusb-1.0-0-dev

USB Transfer Types

TypeUse CaseCharacteristics
ControlDevice configuration & setupRequired by all USB devices; used for descriptor requests and class commands
BulkLarge data, no timing guaranteeHigh throughput, error-corrected, retried on error — used by storage, printers
InterruptSmall periodic dataGuaranteed latency, polled at fixed interval — used by keyboards, mice, HID
IsochronousReal-time streamingConstant bandwidth, no error retry — used by audio and video devices

USB Concepts

Lifecycle: Context → Device → Handle → Interface → Endpoint

Context — one library instance per application, created with NewContext.
Device — a USB device descriptor obtained by enumeration; not yet opened.
Handle — an open device; required for all I/O operations.
Interface — a logical function within a device (e.g., HID, audio, CDC); must be claimed before use.
Endpoint — a unidirectional data pipe. IN = device→host (bit 7 set, e.g. $81). OUT = host→device.

Types

Opaque Handles

TUSBContextLibrary instance. One per app. Pass to all enumeration and hotplug calls.
TUSBDeviceUSB device descriptor (not yet opened). Obtained from ListDevices or FindDevice.
TUSBHandleOpen device handle. Required for all transfers. Close with Close(H).
TUSBTransferAsync transfer handle (reserved for future async API).

TUSBSpeed

ValueConstantSpeedUSB Generation
0usUnknownUnknownNot detected
1usLow1.5 MbpsUSB 1.0
2usFull12 MbpsUSB 1.1
3usHigh480 MbpsUSB 2.0
4usSuper5 GbpsUSB 3.0
5usSuperPlus10 GbpsUSB 3.1

TUSBClass

ConstantCodeDevice Class
ucAudio$01Audio devices
ucHID$03Human Interface Device (keyboards, mice, gamepads)
ucPrinter$07Printers
ucStorage$08Mass storage (USB drives, card readers)
ucHub$09USB hubs
ucCDC$0ACommunications Device Class (serial adapters)
ucVideo$0EVideo capture devices
ucWireless$E0Wireless controllers (Bluetooth, Wi-Fi dongles)
ucVendor$FFVendor-specific protocol

TUSBDeviceInfo

TUSBDeviceInfo = record
BusNumber, DeviceAddress : Integer  { bus/port location }
VendorID, ProductID : Integer  { VID:PID in hex, e.g. $045E:$028E }
DeviceClass : Integer  { see TUSBClass }
Manufacturer, Product, SerialNumber : string
Speed : TUSBSpeed
NumConfigs : Integer  { usually 1 }

TUSBEndpoint

TUSBEndpoint = record
Address : Integer  { endpoint address; bit 7 = direction (1=IN) }
IsIN : Boolean  { True = device→host }
TransferType : Integer  { 0=control 1=isoc 2=bulk 3=interrupt }
MaxPacket : Integer  { max packet size in bytes }
Interval : Integer  { polling interval for interrupt/isoc endpoints }

TUSBHotplugEvent

type TUSBHotplugEvent = (
  heArrived = 1,  { device plugged in }
  heLeft    = 2   { device removed }
);

API Reference

Context

function NewContext: TUSBContext;
Initialize a libusb context. Call once at startup; pass to all subsequent API calls.
procedure FreeContext(Ctx: TUSBContext);
Release context and all associated resources. Call at program exit.
procedure SetDebug(Ctx: TUSBContext; Level: Integer);
Set log verbosity: 0 = none, 1 = errors only, 2 = warnings, 3 = info, 4 = debug.

Enumeration

function ListDevices(Ctx: TUSBContext): array of TUSBDevice;
Return all connected USB devices. Iterate and call GetDeviceInfo on each.
function GetDeviceInfo(Dev: TUSBDevice): TUSBDeviceInfo;
Read VID, PID, manufacturer string, product string, serial number, speed, and bus address from a device.
function FindDevice(Ctx: TUSBContext; VendorID, ProductID: Integer): TUSBDevice;
Find the first device matching the given VID:PID. Returns 0 if not found.
function FindDevices(Ctx: TUSBContext; VendorID, ProductID: Integer): array of TUSBDevice;
Find all devices matching VID:PID. Pass 0 for either to use as a wildcard.
function GetSpeed(Dev: TUSBDevice): TUSBSpeed;
Return the connection speed of a device as a TUSBSpeed enum value.

Open / Close

function Open(Ctx: TUSBContext; VendorID, ProductID: Integer): TUSBHandle;
Open the first device matching VID:PID. Returns a handle, or 0 on failure. Shorthand for FindDevice + OpenDevice.
function OpenDevice(Dev: TUSBDevice): TUSBHandle;
Open a specific device obtained from enumeration. Returns a handle or 0 on error.
procedure Close(H: TUSBHandle);
Close a device handle. Release all claimed interfaces before closing.

Interface

procedure ClaimInterface(H: TUSBHandle; Interface_: Integer);
Claim exclusive access to an interface. Required before any data transfer on that interface.
procedure ReleaseInterface(H: TUSBHandle; Interface_: Integer);
Release a previously claimed interface. Call before closing the handle.
procedure DetachKernelDriver(H: TUSBHandle; Interface_: Integer);
Detach an active kernel driver from an interface (Linux only). Necessary when the OS has already bound a driver (e.g., usbhid) and you need direct access.
procedure SetConfiguration(H: TUSBHandle; Config: Integer);
Set the active USB configuration. Most devices have only one configuration (Config = 1).
procedure SetAlternateSetting(H: TUSBHandle; Interface_, AltSetting: Integer);
Select an alternate interface setting. Used by audio/video devices that offer different bandwidth modes.

Synchronous Transfers

function ControlTransfer(H: TUSBHandle; RequestType, Request, Value, Index: Integer; const Data: string; TimeoutMs: Integer): Integer;
Perform a control transfer. RequestType, Request, Value, Index follow the USB spec (bmRequestType, bRequest, wValue, wIndex). TimeoutMs = 0 means no timeout. Returns bytes transferred.
function BulkTransfer(H: TUSBHandle; Endpoint: Integer; const Data: string; TimeoutMs: Integer): Integer;
Write data to a bulk OUT endpoint. Returns bytes transferred.
function BulkRead(H: TUSBHandle; Endpoint, MaxBytes, TimeoutMs: Integer): string;
Read up to MaxBytes from a bulk IN endpoint. Returns raw bytes as string.
function InterruptTransfer(H: TUSBHandle; Endpoint: Integer; const Data: string; TimeoutMs: Integer): Integer;
Write data to an interrupt OUT endpoint. Returns bytes transferred.
function InterruptRead(H: TUSBHandle; Endpoint, MaxBytes, TimeoutMs: Integer): string;
Read up to MaxBytes from an interrupt IN endpoint (e.g., HID reports). Returns received bytes as string.

Descriptors

function GetStringDescriptor(H: TUSBHandle; Index: Integer): string;
Read a string descriptor by index (language 0x0409 = English). Index 1 = Manufacturer, 2 = Product, 3 = SerialNumber.
function GetDeviceDescriptor(Dev: TUSBDevice): string;
Return raw device descriptor bytes (18 bytes per USB spec). Useful for low-level inspection.
function GetEndpoints(Dev: TUSBDevice; Interface_: Integer): array of TUSBEndpoint;
List all endpoints for a given interface. Inspect IsIN, TransferType, and MaxPacket to find the right endpoint for your transfer.

Hotplug

procedure RegisterHotplug(Ctx: TUSBContext; VendorID, ProductID: Integer; const CallbackID: string);
Register a hotplug event listener. VendorID and ProductID may be 0 to match any device. CallbackID identifies the event for routing in an agent handler.
procedure HandleEvents(Ctx: TUSBContext);
Process pending hotplug events without blocking. Call in a polling loop or from an agent's on tick handler.

Code Example — Enumerate & Read HID

uses libusb;
var
  Ctx: TUSBContext;
  H: TUSBHandle;
  Data: string;
  Info: TUSBDeviceInfo;
begin
  Ctx := NewContext;
  SetDebug(Ctx, 1);
  H := Open(Ctx, $046D, $C52B);  { Logitech Unifying Receiver }
  if H = 0 then begin
    WriteLn('Device not found');
    Exit;
  end;
  Info := GetDeviceInfo(FindDevice(Ctx, $046D, $C52B));
  WriteLn('Product: ', Info.Product);
  WriteLn('Speed: ', Ord(Info.Speed));
  DetachKernelDriver(H, 0);
  ClaimInterface(H, 0);
  Data := InterruptRead(H, $81, 64, 1000);  { EP 0x81 = IN endpoint 1 }
  WriteLn('Received ', Length(Data), ' bytes');
  ReleaseInterface(H, 0);
  Close(H);
  FreeContext(Ctx);
end.
Linux udev rule

By default, USB device nodes are owned by root. Add a udev rule to allow non-root access for your specific device:

SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c52b", MODE="0666"

Save to /etc/udev/rules.d/99-libusb.rules and run sudo udevadm control --reload-rules.

Package Info

Version1.0.0
Typeclib
C Librarylibusb-1.0
Authorgustavo

Install

ppm install libusb

Requires system library:
libusb-1.0-0-dev

Ubuntu/Debian:
sudo apt install libusb-1.0-0-dev

Notable Users

OpenOCD — on-chip debugging
sigrok — logic analyzers
librealsense — depth cameras
libfprint — fingerprint readers
USBView — device inspector

Functions

  • NewContext / FreeContext
  • SetDebug
  • ListDevices
  • GetDeviceInfo
  • FindDevice / FindDevices
  • GetSpeed
  • Open / OpenDevice
  • Close
  • ClaimInterface
  • ReleaseInterface
  • DetachKernelDriver
  • SetConfiguration
  • SetAlternateSetting
  • ControlTransfer
  • BulkTransfer / BulkRead
  • InterruptTransfer
  • InterruptRead
  • GetStringDescriptor
  • GetDeviceDescriptor
  • GetEndpoints
  • RegisterHotplug
  • HandleEvents
  • LibUSBVersion

See Also