首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

libusb 開發者指南:USB 裝置存取完整 API 詳解

     編輯:關於C語言

1. 簡介

libusb 是跨平台的 USB 裝置存取庫,支援 Linux、FreeBSD、NetBSD、OpenBSD、macOS。本文基於 libusb-0.1 API,涵蓋核心函式、裝置操作、控制/批量/中斷傳輸、平台專屬擴充。

2. 核心架構概念

  • 總線:USB 主控制器層級,每個總線掛載多個裝置。
  • 裝置:實體 USB 裝置,擁有唯一位址、描述符。
  • 介面:裝置功能單元(如鍵盤、滑鼠、大量儲存),一個裝置可含多個介面。
  • 端點:資料傳輸通道(IN/OUT、Control/Bulk/Interrupt/Isochronous)。
  • 設定:裝置運作模式組合(介面+替代設定)。

3. 核心 API 流程

// 1. 初始化
usb_init();

// 2. 掃描總線與裝置
usb_find_busses();
usb_find_devices();

// 3. 取得總線鏈表
struct usb_bus *busses = usb_get_busses();

// 4. 遍歷尋找目標裝置
for (struct usb_bus *bus = busses; bus; bus = bus->next) {
    for (struct usb_device *dev = bus->devices; dev; dev = dev->next) {
        // 比對 VID/PID、類別等
        if (dev->descriptor.idVendor == MY_VID && dev->descriptor.idProduct == MY_PID) {
            // 找到目標
        }
    }
}

4. 裝置操作關鍵函式

函式用途備註
usb_open(dev)開啟裝置取得 handle後續操作需此 handle
usb_close(handle)關閉裝置釋放資源
usb_set_configuration(handle, cfg)設定作用配置對應 bConfigurationValue
usb_claim_interface(handle, iface)認領介面任何介面操作前必須呼叫
usb_release_interface(handle, iface)釋放介面對應 bInterfaceNumber
usb_set_altinterface(handle, alt)設定替代設定對應 bAlternateSetting
usb_clear_halt(handle, ep)清除端點暫停優於 deprecated usb_resetep
usb_reset(handle)重置裝置需重新掃描與開啟

5. 資料傳輸三大類型

5.1 控制傳輸

// 標準控制請求
int usb_control_msg(handle, requesttype, request, value, index, bytes, size, timeout);

// 取得字串描述符
int usb_get_string_simple(handle, index, buf, buflen); // 回傳 ASCII

// 取得通用描述符
int usb_get_descriptor(handle, type, index, buf, size);

5.2 批量傳輸

int usb_bulk_write(handle, ep, bytes, size, timeout); // 發送資料
int usb_bulk_read(handle, ep, bytes, size, timeout);  // 接收資料

適用大量資料、無即時性要求(如大量儲存、印表機)。

5.3 中斷傳輸

int usb_interrupt_write(handle, ep, bytes, size, timeout);
int usb_interrupt_read(handle, ep, bytes, size, timeout);

適用低延遲、小封包、週期性輪詢(鍵盤、滑鼠、手柄)。

6. 同步 vs 非同步

  • libusb-0.1:所有函式同步阻塞,完成或逾時才返回。
  • libusb-1.0+:支援非同步 I/O、事件驅動、多執行緒安全。

7. 錯誤處理慣例

  • 回傳 int:< 0 表示錯誤(負錯誤碼),>=0 為傳輸位元組數或成功碼。
  • usb_open 回傳 handle,失敗回傳 NULL。
  • 常見錯誤碼:EBUSY(介面被佔用)、ENOMEM(記憶體不足)、EPIPE(端點暫停)。

8. 平台專屬擴充(_np 後綴)

// Linux 專屬
int usb_get_driver_np(handle, interface, name, namelen);     // 取得核心驅動名稱
int usb_detach_kernel_driver_np(handle, interface);          // 脫離核心驅動,供 user-space 使用

使用前檢查巨集 LIBUSB_HAS_GET_DRIVER_NP 等。

9. 完整範例:尋找並開啟印表機類別裝置

usb_init();
usb_find_busses();
usb_find_devices();

struct usb_bus *bus;
for (bus = usb_get_busses(); bus; bus = bus->next) {
    struct usb_device *dev;
    for (dev = bus->devices; dev; dev = dev->next) {
        // 檢查裝置類別
        if (dev->descriptor.bDeviceClass == 7) { // Printer class
            usb_dev_handle *h = usb_open(dev);
            if (h) {
                usb_set_configuration(h, 1);
                usb_claim_interface(h, 0);
                // ... 進行列印操作 ...
                usb_release_interface(h, 0);
                usb_close(h);
            }
        }
    }
}

10. 遷移建議

新專案**強烈建議直接使用 libusb-1.0**,提供:

  • 非同步傳輸、事件迴圈、熱拔插監控。
  • 更完善的錯誤碼、記憶體管理、執行緒安全。
  • 統一的 C API,支援 C++、Python、Rust 等綁定。

libusb-0.1 僅供維護舊專案參考。掌握 USB 協定層級(描述符、請求、端點)比熟悉 API 更重要,建議配合《USB 2.0/3.0 規格書》閱讀。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved