ARTICLE DETAIL

资讯详情

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

ESP-IoT-Solution USB Device UVC:将 ESP32 摄像头封装为标准 UVC 设备的组件实践

ESP-IoT-Solution USB Device UVC:将 ESP32 摄像头封装为标准 UVC 设备的组件实践 ESP-IoT-Solution USB Device UVC将 ESP32 摄像头封装为标准 UVC 设备的组件实践【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读usb_device_uvc是 ESP-IoT-Solution 中基于 TinyUSB 协议栈实现的 USB UVCUSB Video Class设备驱动组件支持 ESP32-S2/ESP32-S3/ESP32-P4 等芯片可将摄像头等图像采集设备封装为标准 UVC 设备向 USB HostPC、手机、开发板直接输出 JPEG 视频流。读完本文你将掌握该组件的依赖接入方式、四个用户回调的完整用法、关键配置项分辨率/帧率/传输模式/双摄像头的取值与底层影响以及它在源码层的帧发送流水线和测试验证方法。组件概述与核心特性usb_device_uvc让 ESP32 系列芯片以UVC 标准设备的身份枚举到 USB Host 端Host 无需安装特殊驱动即可识别为摄像头并获取视频流。组件本身不包含图像采集逻辑而是通过回调函数把用户的 Camera 或任意图像源接入 UVC 标准协议栈从而把摄像头包装成一个标准 UVC 设备。官方文档docs/en/usb/usb_device/usb_device_uvc.rst列出的特性包括通过 UVC Stream 接口支持视频流输出同时支持Isochronous等时与Bulk批量两种传输模式支持多种分辨率与帧率组合。从源码看该组件基于 TinyUSB 设备栈实现底层通过usb_new_phy配置 USB PHY 为 OTG Device 模式tusb_init()初始化协议栈再创建tusb_device_task周期调用tud_task()与独立的video_task多摄像头时还有video_task2完成视频帧搬运核心实现在 components/usb/usb_device_uvc/usb_device_uvc.c。添加组件到工程组件已发布到乐鑫组件仓库通过 ESP-IDF 组件管理器一条命令即可添加依赖CMake 阶段会自动下载idf.py add-dependency espressif/usb_device_uvc*组件同时依赖 TinyUSB 相关的描述符与配置头文件这些文件随组件一并携带在 components/usb/usb_device_uvc/tusb 目录下tusb_config.h、usb_descriptors.c、uvc_frame_config.h。用户参考唯一核心配置 API组件对外只提供极简的配置 API。由于驱动基于 TinyUSB 栈实现官方文档说明其不提供 deinit 接口需要注意的是当前仓库的头文件 components/usb/usb_device_uvc/include/usb_device_uvc.h 中已包含uvc_device_deinit()用于停止任务、拆除 TinyUSB 栈与释放 PHY可配合uvc_device_init()做完整的生命周期管理。整个使用过程分两步#include usb_device_uvc.h static esp_err_t camera_start_cb(uvc_format_t format, int width, int height, int rate, void *cb_ctx) { // 用户在这里初始化摄像头 // 摄像头需按给定的 format、width、height 和 frame rate 进行初始化 return ESP_OK; } static void camera_stop_cb(void *cb_ctx) { // 用户代码停止采集、关闭摄像头 return; } static uvc_fb_t* camera_fb_get_cb(void *cb_ctx) { // 用户代码返回一帧图像缓冲 // 摄像头应准备好下一帧并返回帧缓冲 return uvc_fb; } static void camera_fb_return_cb(uvc_fb_t *fb, void *cb_ctx) { // 帧缓冲在被拷贝到传输缓冲后归还给用户 // 用户代码回收该帧缓冲 return; } // 用于存储待发送给 Host 的数据的缓冲 const size_t buff_size 30 * 1024; uint8_t *uvc_buffer (uint8_t *)heap_caps_malloc(buff_size, MALLOC_CAP_DEFAULT); assert(uvc_buffer ! NULL); uvc_device_config_t config { .uvc_buffer uvc_buffer, .uvc_buffer_size 40 * 1024, .start_cb camera_start_cb, .fb_get_cb camera_fb_get_cb, .fb_return_cb camera_fb_return_cb, .stop_cb camera_stop_cb, .cb_ctx NULL, }; ESP_ERROR_CHECK(uvc_device_config(0, config)); ESP_ERROR_CHECK(uvc_device_init());配置结构与回调语义uvc_device_config_t的每个字段都有明确的职责见 usb_device_uvc.h字段类型说明uvc_bufferuint8_t *UVC 传输缓冲用于暂存待发送帧uvc_buffer_sizeuint32_t传输缓冲大小必须大于单帧大小start_cbuvc_input_start_cb_tHost 打开 UVC 设备时回调携带具体格式与分辨率fb_get_cbuvc_input_fb_get_cb_tHost 请求新帧时回调返回一帧图像fb_return_cbuvc_input_fb_return_cb_t帧数据拷贝完成后回调用于回收帧缓冲stop_cbuvc_input_stop_cb_tHost 关闭 UVC 设备时回调cb_ctxvoid *回调上下文供用户自定义使用回调返回的帧结构uvc_fb_t包含buf帧数据指针、len字节长度、width/height像素宽高、formatuvc_format_t枚举UVC_FORMAT_JPEG或UVC_FORMAT_H264以及timestampstruct timeval自开机以来的时间戳。测试代码 usb_device_uvc_test.c 展示了如何用内置 JPEG 图片构造一帧数据取esp_timer_get_time()填充时间戳将嵌入镜像的jpg_start/jpg_end直接作为buf与len。uvc_device_config()会先做严格入参校验index必须小于摄像头数量、config及各回调指针、uvc_buffer非空、uvc_buffer_size大于 0任一不满足均返回ESP_ERR_INVALID_ARG。uvc_device_init()则会根据 Kconfig 选择UVC_FORMAT_JPEG/UVC_FORMAT_H264初始化格式创建事件组、初始化 PHY 与 TinyUSB 栈并挂起三个任务TinyUSB 任务、UVC 任务以及双摄像头模式下的 UVC2 任务。帧发送流水线从回调到 USB 端点理解video_task的循环逻辑usb_device_uvc.c就能把握组件的性能边界等待 Host 打开流tud_video_n_streaming()返回假时任务仅做vTaskDelay(1)空转并复位帧计数与传输忙标志帧间隔控制通过s_uvc_device.interval_ms由 Host 提交的dwFrameInterval换算而来控制出帧节奏取帧调用fb_get_cb获取一帧uvc_fb_t尺寸检查若pic-len uvc_buffer_size打印告警并直接调用fb_return_cb丢弃该帧拷贝与归还memcpy将帧拷入uvc_buffer随后立即fb_return_cb归还用户缓冲避免阻塞采集端发送tud_video_n_frame_xfer()发起 USB 传输tx_busy置位等待tud_video_frame_xfer_complete_cb回调通过任务通知解除忙状态。Host 发起设置流格式时TinyUSB 会调用tud_video_commit_cbusb_device_uvc.c它打印bFrameIndex与dwFrameInterval将后者从 100ns 单位换算为毫秒存入interval_ms先调用stop_cb再调用start_cb避免重复提交时传感器双重初始化并把索引映射到UVC_FRAMES_INFO表中对应分辨率/帧率后传入start_cb。Kconfig 配置分辨率、帧率、传输模式与双摄像头所有设备级参数均通过idf.py menuconfig下的USB Device UVC菜单配置定义见 components/usb/usb_device_uvc/Kconfig。USB 设备基础信息配置项默认值说明TUSB_VID0x303AUSB 设备 VIDTUSB_PID0x8000USB 设备 PIDTUSB_MANUFACTUREREspressif厂商字符串TUSB_PRODUCTESP UVC Device产品名TUSB_SERIAL_NUM12345678序列号双摄像头与 USB 速率UVC_SUPPORT_TWO_CAM默认关闭开启后支持两路摄像头CFG_TUD_VIDEO与CFG_TUD_VIDEO_STREAMING由 1 变为 2见 tusb_config.h源码中同时启用video_task2TINYUSB_RHPORT选择 USB PHY 控制器。ESP32-P4/ESP32-S31 默认 High SpeedHS其余目标默认 Full SpeedFS。对应tusb_config.h中OPT_MODE_HIGH_SPEED/OPT_MODE_FULL_SPEED的区分。Cam1 / Cam2 独立配置每个摄像头都有三组独立选项Cam2 仅在开启双摄像头后出现格式FormatFORMAT_MJPEG默认、FORMAT_H264、FORMAT_UNCOMPR未压缩传输模式Transfer ModeUVC_MODE_ISOCIsochronous默认或UVC_MODE_BULKBulk。Bulk 模式下端点缓冲大小在 FS 为 64 字节、HS 为 512 字节Isochronous 模式 FS 为 512 字节、HS 为 1023 字节分辨率FramesizeQVGA 320x240、HVGA 480x320、VGA 640x480、SVGA 800x600、HD 1280x720默认、FHD 1920x1080。帧率UVC_CAMn_FRAMERATE与分辨率联动QVGA/HVGA 默认 30 FPSVGA/SVGA/HD/FHD 默认 15 FPS。分辨率宽高分别由UVC_CAMn_FRAMESIZE_WIDTH/UVC_CAMn_FRAMESIZE_HEIGT定义例如 HD 对应 1280×720。多分辨率上报表UVC_CAMn_MULTI_FRAMESIZE默认开启会向 Host 追加 VGA640×480与 HVGA480×320等备选分辨率。UVC_MULTI_FRAME_CONFIG菜单还允许自定义三档额外帧规格默认分别为 640×48015、480×32030、320×24030。这些条目最终汇总进UVC_FRAMES_INFO[][4]静态表uvc_frame_config.h第 0 项为 Kconfig 默认分辨率1~3 项为多分辨率配置表内还包含_Static_assert保证条目数为 4。任务调度配置配置项默认值说明UVC_TINYUSB_TASK_PRIORITY5范围 1~15TinyUSB 任务优先级UVC_TINYUSB_TASK_CORE-1范围 -1~1TinyUSB 任务绑核-1 为不绑定UVC_CAM1_TASK_PRIORITY4Cam1 采集任务优先级UVC_CAM1_TASK_CORE-1Cam1 任务绑核UVC_CAM2_TASK_PRIORITY/UVC_CAM2_TASK_CORE4 / -1双摄像头模式下 Cam2 对应配置在uvc_device_init()中这些值通过xTaskCreatePinnedToCore生效负值映射为tskNO_AFFINITYusb_device_uvc.c。测试与示例单元测试组件自带 Unity 测试工程components/usb/usb_device_uvc/test_apps测试流程完整覆盖了配置→初始化→运行→反初始化使用嵌入的esp_1280_720.jpg作为视频源循环 15 次每次 1 秒后调用uvc_device_deinit()并释放缓冲setUp/tearDown中还通过heap_caps_get_free_size对比运行前后 8bit/32bit 内存检测内存泄漏。需要说明的是该测试依赖于真实 USB Host 枚举设备属于需要接线的硬件测试用例。官方示例文档推荐了两个可直接运行的示例位于 examples/usb/device 下usb_webcam单摄像头 UVC 网络摄像头示例main/usb_webcam_main.c中演示了完整的回调实现与配置流程将 ESP32 变成即插即用的 USB 摄像头usb_dual_uvc_device双 UVC 设备示例配合UVC_SUPPORT_TWO_CAM配置实现双路视频流输出。注意事项传输缓冲大小uvc_buffer_size必须大于最大单帧大小否则超出帧会被直接丢弃源码中打印frame size is too big, dropping frame告警文档示例中buff_size分配 30KB 而配置填写 40KB实际以配置字段为准。帧缓冲生命周期fb_get_cb返回的缓冲在memcpy完成后即通过fb_return_cb归还采集端可在该回调中复用或释放帧缓冲避免长时间占用。双摄像头模式开启UVC_SUPPORT_TWO_CAM后uvc_device_init()要求两个摄像头均已配置uvc_init[1]为真否则返回ESP_ERR_INVALID_STATE若仅使用单路需关闭该选项。运行环境组件针对 ESP32-S2/ESP32-S3/ESP32-P4 等带 USB OTG 外设的芯片设计ESP32-P4/ESP32-S31 默认启用 High Speed 模式其余目标为 Full Speed传输模式与端点缓冲大小会随速率联动变化。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表