ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TinyUSB 应用指南:基于 ESP32 的 USB 设备开发全解析(esp-iot-solution 实践篇)

TinyUSB 应用指南:基于 ESP32 的 USB 设备开发全解析(esp-iot-solution 实践篇) 物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载本文是 esp-iot-solution 仓库中 TinyUSB 应用指南 的深度拓展围绕乐鑫 IoT 方案中 TinyUSB 协议栈的两种集成路线esp_tinyusb高层封装与espressif/tinyusb原生组件、芯片选型以及 UAC 音频、UVC 视频两类典型 USB 设备应用展开。读完本文你将掌握如何在 ESP32-S2/S3/P4 上快速接入 USB CDC/MSC/HID/MIDI/DFU/网卡等类、如何通过tusb_config.h与描述符文件定制原生 TinyUSB 设备、以及如何基于 usb_device_uac 与 usb_device_uvc 组件实现 USB 声卡与 USB 摄像头并理解 UAC 异步反馈、UVC 图像格式等底层原理。TinyUSB 简介与芯片选型TinyUSB 是一个开源的嵌入式 USB 主机/设备协议栈库由 Adafruit 开发和维护目标是为小型微控制器提供轻量级、跨平台、易于集成的 USB 功能。它支持多种 USB 设备类型包括HID人机接口设备键盘、鼠标、Surface Dial 旋钮等MSC大容量存储U 盘、无线磁盘CDC通信设备类虚拟串口、串口桥MIDI音乐设备数字接口电子乐器以及DFU固件升级、ECM/NCM/RNDISUSB 网卡等类在 esp-iot-solution 中基于原生 TinyUSB 封装了若干上层组件components/usb/目录下的usb_device_uac、usb_device_uvc、usb_stream、esp_tinyuf2等覆盖音频、视频、U 盘、固件升级等场景。在动手开发前需要根据芯片的 USB 外设能力进行选型。下表整理了当前仓库支持矩阵SoCUSB 1.1 Full SpeedUSB 2.0 High SpeedESP32-S2✅ 支持—ESP32-S3✅ 支持—ESP32-P4✅ 支持✅ 支持选型要点绝大多数 USB 设备HID、MSC、CDC、UAC、UVC 等在 Full Speed 下即可工作ESP32-S2/S3 足以覆盖若追求更高带宽如大分辨率视频流、高采样率多声道音频则需选择支持 High Speed 的 ESP32-P4。这一能力差异在源码中也有直接体现例如 usb_device_uvc/tusb/tusb_config.h 中通过CONFIG_TINYUSB_RHPORT_HS区分ESP32-P4 使能时定义CFG_TUSB_RHPORT1_MODEHigh Speed 端口其余芯片定义CFG_TUSB_RHPORT0_MODE并回退到 Full Speed。TinyUSB 组件两种集成路线仓库将 TinyUSB 的接入方式划分为两个组件分别面向简单快速与深度定制两类需求二者不可混淆务必按项目复杂度选择。esp_tinyusb 组件高层封装简单应用首选esp_tinyusb组件封装了一系列 TinyUSB API可方便地将 USBCDC-ACM、MSC、MIDI、HID、DFU、ECM/NCM/RNDIS类集成进自己的工程。使用步骤在工程目录下运行以下命令添加依赖idf.py add-dependency esp_tinyusb~1.0.0在menuconfig中配置需要使用的 USB 类打开对应 Kconfig 选项即可启用对应 Class。在工程代码中调用 esp_tinyusb 提供的 API 完成初始化与数据收发。esp-iot-solution 仓库examples/usb/device/下提供了丰富的落地示例可直接参考usb_dual_uvc_device双摄 UVC 设备usb_uacUSB 声卡UACusb_webcamUSB 摄像头UVC可将 ESP32-S3-EYE 变为 USB 摄像头usb_extend_screenUSB 扩展屏usb_lcd_displayUSB LCD 显示器usb_dongle、usb_hid_device、usb_msc_wireless_disk、usb_surface_dial、usb_uart_bridge注意esp_tinyusb 封装了许多 USB 类使开发被支持的 USB 类非常容易但这也意味着进行某些底层改动比较困难仅适合简单的 USB 应用。espressif/tinyusb 组件原生封装复杂应用首选espressif/tinyusb组件基于原生 tinyusb 仓库将其代码封装为独立组件方便在自己的工程中使用。该组件需要使用 ESP-IDF release/v5.0 及以上版本。使用步骤在工程目录下添加依赖idf.py add-dependency tinyusb~0.15.10编写tusb_config.h该文件通过定义一系列宏来决定 TinyUSB 的配置并反向提供给 espressif/tinyusb 组件。同时在 main 组件的CMakeLists.txt中添加以下代码将配置头文件目录注入组件编译可参考 原生 TinyUSB 开发指南 的工程目录结构idf_component_get_property(tusb_lib espressif__tinyusb COMPONENT_LIB) target_include_directories(${tusb_lib} PRIVATE path_to_your_tusb_config)工程推荐目录结构为main/下单独建tusb/目录放置tusb_config.h、usb_descriptors.c、usb_descriptors.h保证依赖关系简单project_name | |-- main |-- CMakeLists.txt |-- idf_component.yml |-- main.c |-- tusb |-- tusb_config.h |-- usb_descriptors.c |-- usb_descriptors.h对应main/CMakeLists.txt放置于idf_component_register之后# espressif__tinyusb 应匹配当前依赖的 tinyusb 名称 idf_component_get_property(tusb_lib espressif__tinyusb COMPONENT_LIB) target_include_directories(${tusb_lib} PUBLIC ${COMPONENT_DIR}/tusb) target_sources(${tusb_lib} PUBLIC ${COMPONENT_DIR}/tusb/usb_descriptors.c)关于反向依赖工程依赖 tinyusb又需要向 tinyusb 提供头文件不可避免地存在反向依赖问题。目前官方做法是将 tinyusb 的关键文件作为源码直接编译进 main 组件解决。编写usb_descriptors.h定义 USB 设备的描述符包括设备描述符、配置描述符、接口描述符等。tinyusb 提供了大量描述符模板优先复用预定义描述符可方便地进行组装和长度计算。编写usb_descriptors.c实现向 tinyusb 提供描述符的回调函数核心是三个弱函数uint8_t const *tud_descriptor_device_cb(void); // 设备描述符 uint8_t const *tud_descriptor_configuration_cb(uint8_t index); // 配置描述符 uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid); // 字符串描述符注意配置描述符的长度必须等于实际长度各端点描述符的端点号要避免重复。仓库内可参考的现成实现usb_device_uvc/tusb/usb_descriptors.c、usb_device_uvc/tusb/usb_descriptors.h 以及 usb_hid_device 示例中的hid_device/usb_descriptors.c。esp-iot-solution 中采用原生 TinyUSB 路线的示例包括usb_hid_deviceUSB 键盘鼠标设备usb_msc_wireless_diskUSB 无线 U 盘usb_surface_dialWindows Surface Dial HID 设备usb_uart_bridge串口转 USB 设备注意espressif/tinyusb 提供了更多灵活性可以更方便地定制 USB 设备适合复杂的 USB 应用。若使用 ESP-IDF release/v4.4可使用leeebo/tinyusb_src组件其作用与 espressif/tinyusb 相同补全了对 v4.4 的支持。深入tusb_config.h关键配置宏TinyUSB 大部分功能通过宏开关控制。除上面提到的速率配置外原生 TinyUSB 开发指南 还系统总结了以下关键宏系统设置类宏CFG_TUSB_RHPORT0_MODE定义连接到 USB PHY 的方式和速率例如 USB 设备 全速#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED)CFG_TUSB_RHPORT1_MODE定义第二个 PHY 端口的方式和速率例如 USB 设备 高速#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)ESP32-P4 的 High Speed 场景使用ESP_PLATFORM使用 ESP-IDF 平台编译时需启用CFG_TUSB_OS定义操作系统使用 FreeRTOS 时设为OPT_OS_FREERTOS也可不启用操作系统CFG_TUSB_OS_INC_PATH在 ESP-IDF 中要求 include 路径添加freertos/前缀#define CFG_TUSB_OS_INC_PATH freertos/CFG_TUSB_DEBUG启用 tinyusb 日志打印等级共三级0 表示关闭CFG_TUSB_DEBUG_PRINTF定义日志打印函数例如esp_rom_printfCFG_TUD_ENABLED设为 1 启用 tinyusb device 功能CFG_TUSB_MEM_SECTION将 tinyusb 内存分配到特定内存段CFG_TUSB_MEM_ALIGN定义内存对齐方式例如#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))设备与 Class 类宏CFG_TUD_ENDPOINT0_SIZE端点 0 的最大包大小每个 USB Class 都有独立宏以 UVC 为例CFG_TUD_VIDEO视频控制接口数量、CFG_TUD_VIDEO_STREAMING视频流接口数量、CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE视频流端点 buffer 大小仓库内可参考的完整tusb_config.h实例usb_device_uvc/tusb/tusb_config.hUVC、usb_device_uac/tusb/tusb_config.hUAC。初始化 USB PHY 与协议栈static void usb_phy_init(void) { // Configure USB PHY usb_phy_config_t phy_conf { .controller USB_PHY_CTRL_OTG, .otg_mode USB_OTG_MODE_DEVICE, .target USB_PHY_TARGET_INT, }; usb_new_phy(phy_conf, s_uvc_device.phy_hdl); } static void tusb_device_task(void *arg) { while (1) { tud_task(); } } int main(void) { usb_phy_init(); bool usb_init tusb_init(); if (!usb_init) { ESP_LOGE(TAG, USB Device Stack Init Fail); return ESP_FAIL; } xTaskCreatePinnedToCore(tusb_device_task, TinyUSB, 4096, NULL, 5, NULL, 0); }若使用外部 USB PHY需改用相应外部 PHY 初始化流程。此外还可通过实现tud_mount_cb/tud_umount_cb/tud_suspend_cb/tud_resume_cb等设备层弱函数获取设备插入、拔出、暂停、恢复等事件。USB Device 应用一USB 音频UACTinyUSB 支持 USBUAC 2.0标准用于通过 USB 传输音频数据主要特点最高支持 32 位 / 384 kHz 的音频流兼容 USB 1.1 Full Speed 与 USB 2.0 High Speed延迟更低UAC 传输方式与三种同步机制UAC仅支持 USB 传输中的同步传输因此 UAC 音频设备的数据端点都是同步端点。同步传输不进行重传、延迟低但由于主机与从机的传输时钟不同步可能产生短暂静音/爆音由此产生三种同步方式SYNC 同步将输出时钟与每个 Frame 的 SOF 包同步自适应根据主机传输数据的速率调整输出的采样率ASYNC 异步相比前两者多了一个反馈端口从机根据主机当前的速率告知主机后续的发送速率从而完成数据的补发或少发不需要再适应主机的发送频率ASYNC 异步传输的反馈端点通过启用宏CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP实现反馈速率的计算。TinyUSB 提供了多种反馈数据计算方式其中基于 FIFO 的反馈计算AUDIO_FEEDBACK_METHOD_FIFO_COUNT最为简单且实用需要实现以下虚函数完成设置void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param) { (void)func_id; (void)alt_itf; // Set feedback method to fifo counting feedback_param-method AUDIO_FEEDBACK_METHOD_FIFO_COUNT; feedback_param-sample_freq s_uac_device-current_sample_rate; ESP_LOGD(TAG, Feedback method: %d, sample freq: %d, feedback_param-method, feedback_param-sample_freq); }工作原理UAC Class 内部维护一块软件 FIFO大小由CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ定义。将此内存大小设置为 10ms 的数据量UAC 驱动内部便拥有一块缓冲区并通过反馈端点将 FIFO 水位维持在二分之一处数据缺失时主机在一包中多发数据数据盈余时主机少发数据。应用建议每一次新音频传输开始前例如超过 100ms 没有数据到来即视为新音频先让 UAC 内部 FIFO 缓冲一半缓冲区大小的数据再开始播放这样可以保证 I2S 一直有数据可取不会产生爆音和噪声配合反馈端点软件 FIFO 大小会持续维持在稳定水平。仓库配套usb_device_uac 组件esp-iot-solution 将 UAC 能力封装为 usb_device_uac 组件支持 ESP32-S2/S3/P4可从主机侧收发音频最多 8 个扬声器通道、4 个麦克风通道采样率可配置特性包括通过 UAC 接口进行音频收发支持设置收发音频的间隔支持调节音量与设置静音支持同步传输的反馈端点组件当前不支持动态配置 MIC/SPK 采样率无法同时兼容 Windows 与 Linux若需在 macOS 上使用请启用宏UAC_SUPPORT_MACOS。添加依赖idf.py add-dependency espressif/usb_device_uac*关键 Kconfig 配置见 Kconfig.uacUAC_SPEAKER_CHANNEL_NUM扬声器通道数范围 0~8默认 1UAC_MIC_CHANNEL_NUM麦克风通道数范围 0~4默认 1UAC_SAMPLE_RATE采样率默认 48000位深选择16-bit、24-bit24 槽位打包、24-bit32 槽位、32-bit32 槽位UAC_BYTES_PER_SAMPLE随之自动缩放2/3/4 字节UAC_SPK_INTERVAL_MSSPK 首次读取 UAC 数据的间隔并使 SPK FIFO 容纳 n 毫秒数据默认 10msUAC_MIC_INTERVAL_MSMIC 写入 UAC 数据的间隔批量取数可降低从端延迟默认 10msUAC_SPK_NEW_PLAY_INTERVAL距上次收到音频数据超过该毫秒数即视为新一次播放默认 100msUAC_SUPPORT_MACOS在全速设备上支持 macOS 的 16.16 到 10.14 格式转换USB_DEVICE_UAC_AS_PART启用后需在工程中自行编写tusb_config.h与usb_descriptors.c适用于需要并入复合设备场景此时需在配置中额外提供spk_itf_num与mic_itf_num编程接口初始化入口为uac_device_init()配置结构体 usb_device_uac.h 定义如下回调uac_output_cb_t output_cbUAC 数据输出回调主机→设备扬声器方向传 NULL 则禁用输出uac_input_cb_t input_cbUAC 数据输入回调设备→主机麦克风方向传 NULL 则禁用输入uac_set_mute_cb_t set_mute_cb设置静音回调传 NULL 则忽略静音请求uac_set_volume_cb_t set_volume_cb设置音量回调传 NULL 则忽略音量请求cb_ctx用户自定义回调上下文skip_tinyusb_init为 true 时跳过 TinyUSB 与 USB PHY 的初始化用于复合设备等场景完整示例见 examples/usb/device/usb_uac。USB Device 应用二USB 视频UVCTinyUSB 支持 USBUVC 1.5标准用于通过 USB 传输视频数据可传输多种视频格式包括未压缩的 YUV 格式以及压缩的 MJPEG、H264、H265 等。传输方式当视频流接口Video Streaming传输视频时其传输端点可为同步传输或批量传输端点当视频流接口传输静态图像时传输类型为批量传输端点图像格式Format 与 FrameUVC 能传输多种视频格式这些图像格式通过视频描述符的Format和Frame定义图像类型FormatFrameMJPEGFORMAT_MJPEG0x06FRAME_MJPEG0x07YUV2 / NV12 / M420 / I420FORMAT_UNCOMPRESSED0x04FRAME_UNCOMPRESSED0x05H264FORMAT_H2640x13FRAME_H2640x14H265FORMAT_FRAME_BASED0x10FRAME_FRAME_BASED0x11其中Frame based格式比较特殊可以存储任意按帧存储的图像格式如 MJPG、H264、H265 等通过GUID 字段来表示具体的图像格式。双摄摄像头UVC 设备中一个物理摄像头对应一个 VCVideo Control描述符一个 VC 描述符可以挂多个 VSVideo Streaming描述符表示该摄像头可传输多种格式图像。但在某些特殊硬件上有两个物理摄像头此时需要两个 VC 描述符USB Descriptor | |-- Video Control | |-- Video Streaming | |-- Video Control |-- Video Streaming仓库配套usb_device_uvc 组件usb_device_uvc 是面向 ESP32-S2/ESP32-S3 的 UVC 设备驱动支持向 USB 主机流式传输 JPEG 帧用户可通过回调函数将摄像头或任意设备包装为 UVC 标准设备。特性支持通过 UVC 视频流接口传输视频同时支持同步isochronous与批量bulk两种模式支持多种分辨率与帧率支持传输两个摄像头的画面注意若在 Kconfig 中启用了UVC_SUPPORT_TWO_CAM且需要多摄像头切换请将UVC_CAM1_XFER_MODE与UVC_CAM2_XFER_MODE均设置为同步Isochronous模式。添加依赖idf.py add-dependency espressif/usb_device_uvc*关键实现驱动通过tud_video_n_streaming()启动视频流、tud_video_n_frame_xfer()传输一帧图像并通过弱函数tud_video_frame_xfer_complete_cb()检查是否传输完成视频流端点 buffer 大小由宏CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE定义。双摄场景下的描述符组装可参考 usb_device_uvc/tusb/usb_descriptors.c 与 uvc_frame_config.h。完整示例见 examples/usb/device/usb_webcam将 ESP32-S3-EYE 变为 USB 摄像头与 examples/usb/device/usb_dual_uvc_device双摄 UVC 设备。小结与进一步阅读本文梳理了 esp-iot-solution 中 TinyUSB 的两条技术路线需要快速交付且功能标准时选用esp_tinyusb高层封装需要深度定制如复合设备、自定义描述符时选用espressif/tinyusb原生组件。在设备类层面UAC 提供了声卡能力重点理解同步/自适应/异步三种同步机制与基于 FIFO 的反馈端点UVC 提供了摄像头能力重点理解 Format/Frame 描述符与双 VC 结构。可继续深入阅读仓库内的相关资料原生 TinyUSB 开发指南tusb_config.h宏全集、描述符文件写法、PHY 与协议栈初始化、Class 回调实现USB Device 方案综述仓库 USB 设备应用全景USB Host 方案从设备视角切换到主机视角USB OTG 外设介绍 与 USB PHY 介绍硬件底层组件源码usb_device_uac、usb_device_uvc、esp_tinyuf2示例集examples/usb/deviceUAC/UVC/HID/MSC/串口桥/扩展屏/U 盘等赞分享物联网嵌入式驱动开发硬件开发【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址https://gitcode.com/GitHub_Trending/es/esp-iot-solution点击查看免费下载相关推荐esp-iot-solution USB Device UAC 组件详解基于 TinyUSB 的 USB 音频设备驱动实践esp iot solution USB Device UAC 组件详解基于 TinyUSB 的 USB 音频设备驱动实践 usb_device_uac 是物联网嵌入式驱动开发硬件开发基于 TinyUSB 的 ESP32 USB 设备开发指南组件选型、原生移植与 UAC/UVC 音视频应用esp-iot-solution基于 TinyUSB 的 ESP32 USB 设备开发指南组件选型、原生移植与 UAC/UVC 音视频应用esp iot solution TinyUSB物联网嵌入式驱动开发硬件开发基于 esp-iot-solution 的 ESP-IDF Native TinyUSB 开发指南从工程结构到 UVC 设备实战基于 esp iot solution 的 ESP IDF Native TinyUSB 开发指南从工程结构到 UVC 设备实战 TinyUSB 是一套开源的物联网嵌入式驱动开发硬件开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表