杰理 SDK 文档中心
首页
首页
  • SDK 概述与快速开始

    • SDK 概览与 AC791N 芯片平台
    • 环境搭建与编译指南
    • 烧录与固件升级
    • 工程结构导览
  • 产品方案应用

    • WiFi 摄像头方案
    • WiFi IPC 可视对讲方案
    • WiFi 故事机方案
    • 扫码枪 HID 方案
    • 开发板示例工程
  • 公共应用组件

    • 语音识别 ASR 引擎
    • LLM 与 AI 语音助手接入
    • 摄像头传感器驱动
    • UI 显示框架与驱动
    • USB 主机与设备栈
    • 文件系统与存储管理
    • 系统服务与外设管理
    • 生产测试与射频工具
  • 蓝牙协议栈

    • 经典蓝牙 BR/EDR
    • BLE 低功耗蓝牙
    • 蓝牙 Mesh 网络
    • 蓝牙扩展协议(RCSP/广播/无线麦克风)
  • WiFi 与网络协议栈

    • WiFi 驱动与网络模式
    • lwIP TCP/IP 协议栈
    • 网络安全与加密库
    • 应用层网络协议
    • 流媒体与音视频传输
    • 云平台接入 SDK
    • P2P 远程访问与设备互联
  • 芯片平台与驱动

    • wl82 平台与硬件加速
    • 外设驱动框架
    • 平台配置与固件打包工具
  • 媒体与音频引擎

    • 音频编解码与音源
    • 音效处理引擎
    • 视频与图像处理
  • 操作系统与运行时

    • 实时操作系统与 POSIX 层
    • C/C++ 运行时库
  • 开发资源与文档

    • 文档与规格书
    • 公共示例工程
    • UI 资源工程与打包
    • SDK 辅助工具与脚本

USB 主机与设备栈

本页介绍 AC79NN SDK 中位于 apps/common/usb 的 USB 双模式协议栈:它同时提供设备(Device/Gadget)栈与主机(Host)栈,并承载 MSD、HID、CDC、UAC/UAC2、UVC、Printer 等标准类驱动,以及 ADB、AOA、Apple MFI 等厂商扩展协议,是 U 盘、USB 声卡、USB 摄像头、USB 键盘/鼠标、USB 升级等上层能力共用的底层基础。

Purpose and Scope

本文档的目标读者是需要在 AC79NN 平台上启用、调试或扩展 USB 功能的嵌入式工程师。页面覆盖:

  • USB 栈的目录结构与分层(公共层、设备栈、主机栈、类驱动、厂商协议);
  • 设备栈的初始化时序与类注册机制(usb_device.c、usb_config.h);
  • 主机栈的配置入口、端点缓冲区管理与中断注册;
  • 各 USB 类驱动(MSD、HID、CDC、UAC、UVC、Printer)的归属与职责;
  • 由 TCFG_USB_* 编译宏控制的启用/禁用方式;
  • 关键 API 的签名、参数与语义。

不覆盖(属于兄弟页面):具体外设应用(如 U 盘文件系统、音频播放流程、摄像头采集流水线)请参见对应外设/应用文档;底层控制器寄存器操作与 DMA 细节属于 asm/usb.h 描述的硬件抽象层,不在本页展开。

Overview

AC79NN 的 USB 控制器可工作于两种角色:

  • 设备模式(Slave/Gadget):芯片作为 USB 外设连接 PC 或手机,通过 usb_device_mode(usb_id, class) 动态挂载一个或多个类驱动,实现 U 盘(MSD)、声卡(UAC)、虚拟串口(CDC)、摄像头(UVC)、HID 等设备功能;
  • 主机模式(Host):芯片作为 USB 主控,通过 usb_host_config(usb_id) 枚举外接设备,配合 usb_ctrl_transfer.c 与 usb_bulk_transfer.c 完成控制/批量传输,支持外接 U 盘、键盘鼠标、ADB 调试、AOA 附件等。

两种模式共用同一套硬件抽象(asm/usb.h)、端点 DMA 缓冲区管理(usb_alloc_ep_dmabuffer)与中断注册机制(usb_h_isr_reg / usb_g_isr_reg),上层通过 usb_config.h 暴露的统一接口选择工作模式。这种"一份硬件、两套栈"的设计让同一颗芯片在无需改版的情况下既能被 PC 枚举,也能自主枚举外部设备,是穿戴/音频 SoC 典型的外设互联方案。

栈的启用完全由编译期宏驱动(如 TCFG_USB_SLAVE_ENABLE、TCFG_USB_SLAVE_MSD_ENABLE 等),未启用的类不会被编译进来,从而精确控制代码体积与 RAM 占用——这对资源受限的 MCU 至关重要。

Architecture

下图依据 apps/common/usb 目录的真实组织关系绘制:

flowchart TD
    subgraph sg_Common["公共层 apps/common/usb"]
        USBConfig["usb_config.h<br/>模式配置与中断/DMA 注册接口"]
        USBCommon["usb_common_def.h<br/>公共宏与类型定义"]
        SCSI["usb/scsi.h<br/>SCSI 命令定义"]
    end

    subgraph sg_Device["设备栈 apps/common/usb/device"]
        USBDevice["usb_device.c<br/>设备模式入口与类挂载"]
        Desc["descriptor.c<br/>描述符管理"]
        UserSetup["user_setup.c<br/>厂商 Setup 请求"]
        MSD["msd.c / msd_upgrade.c<br/>大容量存储与升级"]
        HID["hid.c<br/>人机接口设备"]
        CDC["cdc.c<br/>通信设备类"]
        UAC["uac.c / uac2.c / uac_stream.c<br/>音频类"]
        UVC["uvc.c<br/>视频类"]
        Printer["printer.c<br/>打印机类"]
        RamDisk["ram_disk.c / ram_disk_circle.c / ram_disk_update.c<br/>RAM 盘"]
        TaskPC["task_pc.c<br/>PC 交互任务"]
    end

    subgraph sg_Host["主机栈 apps/common/usb/host"]
        CtrlTransfer["usb_ctrl_transfer.c<br/>控制传输"]
        BulkTransfer["usb_bulk_transfer.c<br/>批量传输"]
        Storage["usb_storage.h<br/>存储类"]
        HostCDC["usb_host_cdc.h<br/>CDC 类"]
        Audio["audio.h / hid.h / usb_hid_keys.h"]
        ADB["adb.c / adb_rsa_key.c<br/>Android 调试桥"]
        AOA["aoa.c<br/>Android Open Accessory"]
        MFI["apple_mfi.c<br/>Apple MFi"]
    end

    USBDevice --> Desc
    USBDevice --> UserSetup
    USBDevice --> MSD
    USBDevice --> HID
    USBDevice --> CDC
    USBDevice --> UAC
    USBDevice --> UVC
    USBDevice --> Printer
    USBDevice --> RamDisk
    USBDevice --> TaskPC

    CtrlTransfer --> Storage
    CtrlTransfer --> HostCDC
    CtrlTransfer --> ADB
    CtrlTransfer --> AOA
    CtrlTransfer --> MFI
    BulkTransfer --> ADB
    BulkTransfer --> AOA

    USBConfig --> USBDevice
    USBConfig --> CtrlTransfer
    USBConfig --> USBCommon

各层职责说明:

层次代表文件职责
公共配置层usb_config.h向上层应用屏蔽硬件差异,提供模式切换、端点缓冲、中断注册的统一定义;同时包含 usb/device/usb_stack.h 与 usb/host/usb_host.h 两个栈头文件
设备栈核心usb_device.c完成 SIE/中断/DMA 初始化,按 class 位掩码逐个挂载类驱动,负责设备保持(hold/release)
设备类驱动msd.c、hid.c、cdc.c、uac.c、uvc.c、printer.c各标准类的事件回调、描述符表(*_desc_config)与请求处理,由 usb_add_desc_config 注册
主机栈核心usb_host.c(经 usb/host/usb_host.h 引用)、usb_ctrl_transfer.c、usb_bulk_transfer.c主机枚举、控制/批量传输原语
厂商协议adb.c、aoa.c、apple_mfi.c基于控制/批量传输实现的私有协议,用于手机互联

设计意图:设备栈的类驱动全部通过编译宏 + 位掩码注册两条路径解耦——编译期宏决定代码是否编入,运行期 class 位决定是否挂载。这样既能在运行时切换功能(例如从 U 盘切到声卡),又不会为未使用的类付出任何代码与 RAM 代价。

注:图中 usb_host.c 与 usb/device/usb_stack.h 为头文件引用所证明的栈入口(见 usb_config.h);其余文件均通过仓库文件列表确认存在。

设备栈实现详解

初始化时序:从复位到可被枚举

设备模式入口是 usb_device_init()(编译宏 TCFG_USB_SLAVE_ENABLE 控制),其执行顺序如下(usb_device.c):

  1. usb_config(usb_id) — 硬件基础配置(时钟、引脚、控制器模式);
  2. usb_g_sie_init(usb_id) — 初始化串行接口引擎(SIE),使能设备侧数据通路;
  3. 依据 FUSB_MODE 写入电源/速度配置(usb_write_power(usb_id, 0x40) 或 0x60),并在未定义时报编译错误(#error "USB_SPEED_MODE not defined")——这是强制开发者显式声明速度模式的防呆设计;
  4. usb_slave_init(usb_id) — 从机功能初始化;
  5. 分配 EP0 DMA 缓冲区(64 字节)并调用 usb_set_dma_raddr 将端点 0~4 的 DMA 读地址统一指向该缓冲区——EP0 的控制传输(Setup/Data/Status 阶段)共用同一 DMA 缓冲,减少内存占用;
  6. 使能 INTRUSB_RESET_BABBLE | INTRUSB_SUSPEND 总线级中断,清空并配置 TX/RX 端点中断;
  7. usb_g_isr_reg(usb_id, 3, 0) — 将设备 ISR 注册到中断优先级 3、CPU 0。
static void usb_device_init(const usb_dev usb_id)
{
    usb_config(usb_id);
    usb_g_sie_init(usb_id);

#if defined(FUSB_MODE) && FUSB_MODE
    usb_write_power(usb_id, 0x40);
#elif defined(FUSB_MODE) && (FUSB_MODE==0)
    usb_write_power(usb_id, 0x60);
#else
#error "USB_SPEED_MODE not defined"
#endif

    usb_slave_init(usb_id);
    if (!ep0_dma_buffer[usb_id]) {
        ep0_dma_buffer[usb_id] = usb_alloc_ep_dmabuffer(usb_id, 0, 64);
    }

    usb_set_dma_raddr(usb_id, 0, ep0_dma_buffer[usb_id]);
    usb_set_dma_raddr(usb_id, 1, ep0_dma_buffer[usb_id]);
    usb_set_dma_raddr(usb_id, 2, ep0_dma_buffer[usb_id]);
    usb_set_dma_raddr(usb_id, 3, ep0_dma_buffer[usb_id]);
    usb_set_dma_raddr(usb_id, 4, ep0_dma_buffer[usb_id]);

    usb_write_intr_usbe(usb_id, INTRUSB_RESET_BABBLE | INTRUSB_SUSPEND);
    usb_clr_intr_txe(usb_id, -1);
    usb_clr_intr_rxe(usb_id, -1);
    usb_set_intr_txe(usb_id, 0);
    usb_set_intr_rxe(usb_id, 0);
    usb_g_isr_reg(usb_id, 3, 0);
}

Source: usb_device.c

设计意图:初始化顺序遵循"硬件就绪 → SIE 使能 → 电源/速度确定 → 从机功能 → DMA 缓冲 → 中断"的依赖链。EP0 缓冲在首次使用时惰性分配(if (!ep0_dma_buffer[usb_id])),避免在从未使用 USB 的固件中浪费 64 字节 RAM。

类挂载与运行期模式切换

usb_device_mode(usb_id, class) 是设备模式的核心切换函数(usb_device.c):

  • class == 0(卸载模式):按编译宏逐个释放已注册的类(msd_release、uac_release、cdc_release、uvc_release、hid_release、printer_release),然后调用 usb_device_hold(usb_id)(内部执行 usb_g_hold + usb_release)并延时 15 个系统 tick,让总线完全断开后再切换;
  • class != 0(挂载模式):先 usb_add_desc_config(usb_id, MAX_INTERFACE_NUM, NULL) 重置描述符表,随后用 class_index 依次递增地为每个命中的类添加描述符(usb_add_desc_config(usb_id, class_index++, msd_desc_config))并注册对应事件处理(msd_register 等)。
int usb_device_mode(const usb_dev usb_id, const u32 class)
{
    u8 class_index = 0;
    if (class == 0) {
#if TCFG_USB_SLAVE_MSD_ENABLE
        msd_release(usb_id);
#endif
#if TCFG_USB_SLAVE_AUDIO_ENABLE
        uac_release(usb_id);
#endif
#if TCFG_USB_SLAVE_CDC_ENABLE
        cdc_release(usb_id);
#endif
#if TCFG_USB_SLAVE_UVC_ENABLE
        uvc_release(usb_id);
#endif
#if TCFG_USB_SLAVE_HID_ENABLE
        hid_release(usb_id);
#endif
#if TCFG_USB_SLAVE_PRINTER_ENABLE
        printer_release();
#endif
        usb_device_hold(usb_id);
        os_time_dly(15);
        return 0;
    }

    usb_add_desc_config(usb_id, MAX_INTERFACE_NUM, NULL);

#if TCFG_USB_SLAVE_MSD_ENABLE
    if ((class & MASSSTORAGE_CLASS) == MASSSTORAGE_CLASS) {
        log_info("add desc msd");
        usb_add_desc_config(usb_id, class_index++, msd_desc_config);
        msd_register(usb_id);
    }
#endif
    /* ... 其余类同理:HID/CDC/UAC/UVC/Printer ... */
}

Source: usb_device.c

关键点:

  • class 参数是位掩码(如 MASSSTORAGE_CLASS),可一次挂载多个类,例如 U 盘 + 声卡组合;class_index 用于在描述符表中按顺序登记每个接口;
  • 释放与挂载都受 TCFG_USB_SLAVE_*_ENABLE 编译宏保护,未编译的类调用会被预处理器剔除;
  • 代码中保留了 usb_ep_conflict_check 的调用(当前被注释),说明设计上曾考虑过端点冲突预检——多类并存时端点资源(EP 数量有限)的分配冲突是真实存在的约束,当前版本交由各驱动的 register 流程自行处理;
  • 切换前 usb_add_desc_config(usb_id, MAX_INTERFACE_NUM, NULL) 重置描述符表,避免上次挂载的接口残留导致描述符错乱。

设备保持(Hold)与总线断开

usb_device_hold() 组合了 usb_g_hold() 与 usb_release():前者让设备侧 SIE 进入保持状态,后者释放控制器资源。配合 os_time_dly(15) 的延时,保证在模式切换过程中总线电平稳定、主机侧能看到一次干净的断开再枚举,避免热切换时出现协议级错误。

主机栈实现详解

主机模式通过 usb_config.h 暴露的统一接口驱动,核心入口如下(usb_config.h):

void usb_host_config(usb_dev usb_id);            /* 主机模式配置 */
void usb_host_free(usb_dev usb_id);              /* 主机模式释放 */
void *usb_h_get_ep_buffer(const usb_dev usb_id, u32 ep);
void *usb_h_alloc_ep_buffer(const usb_dev usb_id, u32 ep, u32 dma_size);
void usb_h_free_ep_buffer(const usb_dev usb_id, void *buf);
void usb_h_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id);
void usb_g_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id);
void usb_sof_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id);
void *usb_alloc_ep_dmabuffer(const usb_dev usb_id, u32 ep, u32 dma_size);
void usb_free_ep_dmabuffer(const usb_dev usb_id, void *buf);

Source: usb_config.h

主机侧传输原语

主机栈的传输能力集中在 usb_ctrl_transfer.c(控制传输,用于枚举与类请求)与 usb_bulk_transfer.c(批量传输,用于 U 盘、ADB 等大数据量通路)两个文件中,其配套头文件 usb_ctrl_transfer.h、usb_bulk_transfer.h 声明了对外接口。上层类协议(如 usb_storage.h 的存储类、usb_host_cdc.h 的 CDC 类、adb.c、aoa.c、apple_mfi.c)都建立在这两个传输原语之上。

典型主机侧数据路径:

flowchart LR
    App["上层应用<br/>(U盘/ADB/音频)"] --> Class["主机类驱动<br/>usb_storage / adb / aoa / apple_mfi"]
    Class --> Ctrl["usb_ctrl_transfer.c<br/>控制传输"]
    Class --> Bulk["usb_bulk_transfer.c<br/>批量传输"]
    Ctrl --> EP["端点 DMA 缓冲<br/>usb_h_alloc_ep_buffer"]
    Bulk --> EP
    EP --> HW["USB 控制器<br/>(asm/usb.h)"]

端点缓冲区管理

主机与设备模式都通过 usb_alloc_ep_dmabuffer / usb_free_ep_dmabuffer 分配 DMA 缓冲区。DMA 缓冲区要求地址与对齐满足控制器要求,因此必须走专用分配器而非普通堆分配。usb_h_alloc_ep_buffer 进一步提供按端点号(ep)组织的缓冲管理,usb_h_get_ep_buffer 用于查询已分配端点的缓冲地址——批量传输场景下,类驱动先分配端点缓冲,再在批量传输中反复使用,避免每笔传输都重新分配。

中断注册的三种角色

接口角色说明
usb_h_isr_reg(usb_id, prio, cpu)主机中断主机模式下处理总线事件与端点完成
usb_g_isr_reg(usb_id, prio, cpu)设备中断设备模式下处理 Setup 请求与端点事件(设备栈以优先级 3、CPU 0 注册)
usb_sof_isr_reg(usb_id, prio, cpu)SOF 中断帧起始中断,用于需要帧同步的场景(设备栈中默认注释关闭,以降低中断频率)

优先级与 CPU 亲和可调,便于在多核(如 AC79 系列双核)场景下把 USB 中断固定到特定核,避免与音频等实时任务抢占。

配置选项

USB 栈的启用与类选择由编译期宏控制(在 app_config.h 等工程配置中定义),核心宏如下:

宏类型默认说明
TCFG_USB_SLAVE_ENABLEbool0总开关:是否编译设备(从机)栈
TCFG_USB_SLAVE_MSD_ENABLEbool0大容量存储类(U 盘/升级盘)
TCFG_USB_SLAVE_AUDIO_ENABLEbool0音频类 UAC(含 uac2、uac_stream)
TCFG_USB_SLAVE_CDC_ENABLEbool0通信设备类(虚拟串口)
TCFG_USB_SLAVE_UVC_ENABLEbool0视频类(摄像头)
TCFG_USB_SLAVE_HID_ENABLEbool0人机接口设备(键盘/鼠标/自定义 HID)
TCFG_USB_SLAVE_PRINTER_ENABLEbool0打印机类
FUSB_MODEint必填速度模式:非 0 → 高速(写 0x40);0 → 全速(写 0x60);未定义直接编译报错
MAX_INTERFACE_NUMint—描述符表最大接口数,供 usb_add_desc_config 使用

运行期行为配置由 usb_device_mode(usb_id, class) 的 class 位掩码决定,可组合多个类同时挂载,或在运行时切换到 class == 0 完成整体卸载。

API 参考

usb_host_config(usb_dev usb_id)

将指定 USB 控制器配置为主机模式。usb_id 为 USB 硬件编号(usb_dev 枚举)。调用后即可使用主机类驱动与传输原语。

usb_host_free(usb_dev usb_id)

释放主机模式占用的资源,用于从主机模式退出。

void *usb_alloc_ep_dmabuffer(const usb_dev usb_id, u32 ep, u32 dma_size)

为端点 ep 分配 dma_size 字节的 DMA 缓冲区,返回缓冲区地址;失败返回 NULL。设备栈用它为 EP0 分配 64 字节控制传输缓冲。

void usb_free_ep_dmabuffer(const usb_dev usb_id, void *buf)

释放 DMA 缓冲区。

void *usb_h_get_ep_buffer(const usb_dev usb_id, u32 ep) / usb_h_alloc_ep_buffer(...) / usb_h_free_ep_buffer(...)

主机模式端点缓冲的查询、分配与释放三件套,供主机类驱动在批量传输场景复用缓冲。

void usb_h_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id) / usb_g_isr_reg(...) / usb_sof_isr_reg(...)

分别注册主机、设备、SOF 中断处理;priority 为中断优先级,cpu_id 为绑定的 CPU 核。

int usb_device_mode(const usb_dev usb_id, const u32 class)

设备模式运行期切换。class == 0 卸载全部类并 hold 总线;非 0 时按位掩码挂载对应类。返回 0 表示成功。

核心流程

设备模式:从挂载类到被主机枚举

以下时序基于 usb_device_init → usb_device_mode → ISR 处理链的真实调用关系绘制:

sequenceDiagram
    participant App as 应用任务
    participant Dev as usb_device.c
    participant Desc as descriptor.c
    participant Class as 类驱动(msd/hid/cdc/uac/uvc/printer)
    participant HW as USB 控制器/DMA
    participant PC as PC 主机

    App->>Dev: usb_device_mode(usb_id, MASSSTORAGE_CLASS)
    Dev->>Desc: usb_add_desc_config(usb_id, MAX_INTERFACE_NUM, NULL) 重置
    Dev->>Desc: usb_add_desc_config(usb_id, idx, msd_desc_config)
    Dev->>Class: msd_register(usb_id)
    Class-->>Dev: 注册回调/端点就绪
    Dev-->>App: 返回 0

    Note over HW,PC: USB 插入,总线复位
    PC->>HW: 复位/SETUP(Get Descriptor)
    HW->>Dev: INTRUSB_RESET_BABBLE 中断
    Dev->>Desc: 组包设备/配置描述符
    HW-->>PC: 描述符响应
    PC->>HW: SET_CONFIGURATION
    HW->>Dev: Setup 请求
    Dev->>Class: 类请求分发(msd/hid 等)
    Class-->>HW: 状态/数据响应
    PC->>Class: SCSI 命令(CBW) → 数据 → CSW
    Class-->>PC: 完成

要点:枚举完全由主机(PC)驱动,设备栈只负责在中断上下文中应答 Setup 请求并把类请求分发给对应驱动;大数据量通路(如 MSD 的 CBW/CSW)由类驱动的端点处理,不与 EP0 争用。

主机模式:从配置到外设枚举

sequenceDiagram
    participant App as 应用任务
    participant HC as usb_host_config
    participant HClass as 主机类驱动(usb_storage/adb/aoa)
    participant Ctrl as usb_ctrl_transfer.c
    participant Bulk as usb_bulk_transfer.c
    participant Dev as 外接设备(U盘/手机)

    App->>HC: usb_host_config(usb_id)
    HC-->>App: 就绪
    App->>Ctrl: 枚举(Get Device/Config Descriptor)
    Ctrl->>Dev: 控制传输
    Dev-->>Ctrl: 描述符
    App->>HClass: 匹配类并初始化
    HClass->>Bulk: 批量传输
    Bulk->>Dev: OUT/IN 数据
    Dev-->>HClass: 数据/状态

失败模式、边界情况与并发

端点冲突(多类并存)

设备栈允许一次挂载多个类,但控制器端点(EP)数量有限。源码中保留了 usb_ep_conflict_check(usb_id) 的调用框架(当前注释禁用),说明端点冲突是已知风险;多类组合(如 MSD + UAC + UVC 同时挂载)时需确保各驱动的端点分配不重叠。若启用组合类后出现枚举失败,应优先核查端点分配。

模式切换时序

usb_device_mode(usb_id, 0) 先逐个 *_release 释放类,再 usb_g_hold + usb_release,并 os_time_dly(15) 等待总线稳定。若在类释放前立即切换,主机侧可能看到残留端点导致枚举异常;因此切换函数本身已内置延时,应用层不应跳过。

DMA 缓冲与对齐

EP0 的 DMA 缓冲(64 字节)在首次初始化时惰性分配并共享给端点 0~4(usb_set_dma_raddr 指向同一地址)。这意味着端点 0~4 的 DMA 读地址相同——设计上仅 EP0 控制传输使用该缓冲;若类驱动为其它端点直接复用 EP0 缓冲而非法覆盖,会造成数据错乱。批量端点应使用 usb_h_alloc_ep_buffer 或 usb_alloc_ep_dmabuffer 单独分配。

中断上下文约束

设备 ISR 以优先级 3 注册,Setup 请求在中断上下文中分发到类驱动。类驱动的请求处理回调必须保持短小,不能阻塞或调用耗时操作(如等待 Flash 擦写完成再应答 Setup),否则会拖长中断占用、影响音频等实时任务。需要长耗时操作的路径(如 MSD 的底层读写在专用任务中完成)与 EP0 应答解耦。

编译期配置错误

FUSB_MODE 未定义会直接触发 #error "USB_SPEED_MODE not defined" 编译失败——这是刻意的防呆设计,强制开发者为每个 USB 实例显式声明速度模式,避免因默认值不确定导致高速/全速行为漂移。

扩展点

  1. 新增设备类驱动:参照 msd.c 模式,实现 xxx_desc_config(描述符表)与 xxx_register(usb_id) / xxx_release(usb_id),在 usb_device_mode 中按 TCFG_USB_SLAVE_XXX_ENABLE 宏追加挂载/释放分支,并通过 usb_add_desc_config(usb_id, class_index++, xxx_desc_config) 登记接口;
  2. 新增主机类协议:在 apps/common/usb/host/ 下实现,基于 usb_ctrl_transfer.h / usb_bulk_transfer.h 原语构建(参考 adb.c、aoa.c 的既有结构);
  3. 自定义 Setup 请求:user_setup.c 承载设备端厂商自定义请求处理,可在此扩展私有命令;
  4. 中断亲和性:通过 usb_g_isr_reg / usb_h_isr_reg 的 cpu_id 参数将 USB 中断绑定到特定核,为多核负载均衡提供接口。

相关链接

  • usb_config.h — 模式配置与中断/DMA 接口
  • usb_device.c — 设备栈初始化与类挂载
  • usb_ctrl_transfer.h / usb_bulk_transfer.h — 主机传输原语
  • usb_storage.h — 主机存储类
  • USB 外设示例(HID 从机测试 / U 盘主机测试)
  • 相关页面:存储与文件系统、音频播放、USB 升级流程(分别见各自目录页)
Prev
UI 显示框架与驱动
Next
文件系统与存储管理