// USB 后端操作结构 structusb_backend_ops { // 批量传输 int (*bulk_send)(void *handle, int ep, constchar *buf, ssize_t len); int (*bulk_recv)(void *handle, int ep, char *buf, ssize_t len);
// 设备扫描 int (*scan_device)(structsunxi_efex_ctx_t *ctx); int (*scan_device_at)(structsunxi_efex_ctx_t *ctx, uint8_t bus, uint8_t port); int (*scan_devices)(structsunxi_scanned_device_t **devices, size_t *count);
// 热插拔支持 int (*hotplug_snapshot)(structsunxi_hotplug_device_t **devices, size_t *count);
// 后端生命周期 int (*init)(structsunxi_efex_ctx_t *ctx); int (*exit)(structsunxi_efex_ctx_t *ctx); };
flowchart TD
A[sunxi_usb_bulk_send/recv] --> B[get_backend_ops]
B --> C{平台检测}
C -->|Linux/macOS| D[返回 libusb_ops]
C -->|Windows| E{current_backend}
E -->|LIBUSB| F[返回 libusb_ops]
E -->|WINUSB/AUTO| G[返回 winusb_ops]
D --> H[调用 ops->bulk_send/recv]
F --> H
G --> H
H --> I[执行后端具体实现]
libusb 后端实现
源码位置: src/usb/usb_layer_libusb.c
批量发送实现
源码位置: src/usb/usb_layer_libusb.c:16-38
#include<libusb.h>
staticintlibusb_bulk_send(void *handle, int ep, constchar *buf, ssize_t len) { if (!handle || !buf || len <= 0) { return EFEX_ERR_NULL_PTR; }
constint r = libusb_bulk_transfer(hdl, ep, (void *) buf, (int) chunk, &bytes, DEFAULT_USB_TIMEOUT); if (r != 0) { return EFEX_ERR_USB_TRANSFER; } len -= bytes; buf += bytes; } return EFEX_ERR_SUCCESS; }
libusb 批量发送流程图
flowchart TD
A[libusb_bulk_send] --> B{参数检查}
B -->|失败| C[返回 NULL_PTR]
B -->|通过| D[设置 max_chunk = 128KB]
D --> E{len > 0?}
E -->|否| F[返回 SUCCESS]
E -->|是| G[计算本次 chunk min len, max_chunk]
G --> H[sunxi_usb_hex_dump 调试输出]
H --> I[libusb_bulk_transfer OUT 端点]
I --> J{传输成功?}
J -->|否| K[返回 USB_TRANSFER]
J -->|是| L[更新 len -= bytes buf += bytes]
L --> E
批量接收实现
源码位置: src/usb/usb_layer_libusb.c:40-60
staticintlibusb_bulk_recv(void *handle, int ep, char *buf, ssize_t len) { if (!handle || !buf || len <= 0) { return EFEX_ERR_NULL_PTR; }
libusb_device_handle *hdl = (libusb_device_handle *) handle; int bytes;
while (len > 0) { constint r = libusb_bulk_transfer(hdl, ep, (uint8_t *) buf, (int) len, &bytes, DEFAULT_USB_TIMEOUT); if (r != 0) { return EFEX_ERR_USB_TRANSFER; }
sunxi_usb_hex_dump(buf, (size_t) bytes, "RECV");
len -= bytes; buf += bytes; } return EFEX_ERR_SUCCESS; }
libusb 批量接收流程图
flowchart TD
A[libusb_bulk_recv] --> B{参数检查}
B -->|失败| C[返回 NULL_PTR]
B -->|通过| D{len > 0?}
D -->|否| E[返回 SUCCESS]
D -->|是| F[libusb_bulk_transfer IN 端点]
F --> G{传输成功?}
G -->|否| H[返回 USB_TRANSFER]
G -->|是| I[sunxi_usb_hex_dump 调试输出]
I --> J[更新 len -= bytes buf += bytes]
J --> D
设备扫描实现
源码位置: src/usb/usb_layer_libusb.c:72-105
staticintlibusb_scan_device(structsunxi_efex_ctx_t *ctx) { if (!ctx) { return EFEX_ERR_NULL_PTR; }
flowchart TD
A[libusb_scan_device] --> B[libusb_init 初始化上下文]
B --> C[libusb_get_device_list 获取设备列表]
C --> D[遍历设备列表]
D --> E[libusb_get_device_descriptor]
E --> F{VID == 0x1f3a PID == 0xefe8?}
F -->|否| G[继续下一个设备]
G --> D
F -->|是| H[libusb_open 打开设备]
H --> I{打开成功?}
I -->|否| J[返回错误码]
I -->|是| K[保存设备句柄到 ctx]
K --> L[释放设备列表]
L --> M[返回 SUCCESS]
// 只处理批量端点 if ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK) continue;
// IN 还是 OUT 端点 if ((ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) ctx->epin = ep->bEndpointAddress; else ctx->epout = ep->bEndpointAddress; } } } libusb_free_config_descriptor(config); return EFEX_ERR_SUCCESS; } } } return EFEX_ERR_USB_INIT; }
libusb 后端初始化流程图
flowchart TD
A[libusb_backend_init] --> B{ctx->hdl 有效?}
B -->|否| C[返回 USB_INIT 错误]
B -->|是| D[libusb_kernel_driver_active]
D --> E{内核驱动活跃?}
E -->|是| F[libusb_detach_kernel_driver]
E -->|否| G[继续]
F --> G
G --> H[libusb_claim_interface 声称接口 0]
H --> I{声称成功?}
I -->|否| C
I -->|是| J[libusb_get_active_config_descriptor]
J --> K[遍历接口和端点]
K --> L{端点类型?}
L -->|非批量| M[跳过]
L -->|批量| N{方向?}
N -->|IN| O[保存 epin]
N -->|OUT| P[保存 epout]
M --> K
O --> K
P --> K
K --> Q[释放配置描述符]
Q --> R[返回 SUCCESS]
后端退出实现
源码位置: src/usb/usb_layer_libusb.c:332-350
staticintlibusb_backend_exit(structsunxi_efex_ctx_t *ctx) { if (!ctx) { return EFEX_ERR_NULL_PTR; }