USB Host 外接 UVC 摄像头示例

功能说明

本工程 cherryusb_video_usb 支持 Venusa RD EVB(venusa_rd_evb) 和 ARCS EVB(arcs_evb) 两种开发板。开发板作为 USB Host(主机),通过 USB 接口接收外接 UVC 摄像头的视频,将帧数据缓存在 PSRAM 中,再通过 LVGL 显示到 ST7789P3 SPI LCD。

两种板型使用相同的视频接收与显示流程,屏幕连接方式不同:Venusa RD EVB 使用外接 SPI 屏,ARCS EVB 使用开发板原配 SPI 屏。

外接 UVC 摄像头(USB Device)
          │ USB 视频数据
          ▼
开发板(USB Host,CherryUSB → PSRAM → LVGL)
          │ SPI
          ▼
ST7789P3 LCD(320×240 横屏预览)

摄像头使用 USB 数据接口,不使用板上的 DVP 摄像头接口。电脑连接开发板用于烧录和查看串口日志;视频数据来自外接摄像头。

特性

  • UVC Host 接收:支持 Bulk 和 ISO(等时)传输,使用工程内的 CherryUSB Video 和 MUSB 接收实现。

  • 格式自动协商:优先选择 MJPEG,未找到时回退到 YUY2(UNCOMPRESSED / YUV422);分辨率和帧间隔通过摄像头描述符及 UVC Probe/Commit 协商。

  • 全屏预览:YUY2 转换或 MJPEG 解码后输出 RGB565,缩放到 320×240;图像处理和 LVGL 更新在 UI 任务中执行。

  • 帧缓冲保护:使用双帧缓冲接收视频,避免覆盖显示任务正在使用的数据,并丢弃检测到的异常帧。

  • 设备热插拔:插入后启动接收,拔出后停止视频流并释放资源。

当前预览界面只有一个全屏区域。配置最多允许 2 台摄像头,经 USB Hub 接入时,各摄像头分别接收数据,但共用此预览区域,标签显示当前画面的 CAM0 或 CAM1。

硬件连接

开发板和摄像头

  • 开发板 × 1:venusa_rd_evb 或 arcs_evb,编译时通过 -DBOARD 指定。

  • 外接 USB UVC 摄像头 × 1,支持 MJPEG 或 YUY2;建议使用 USB 2.0 High-speed 摄像头。

  • 与板端接口匹配、支持 Host 连接的 USB 数据线或转接板。

  • ST7789P3 SPI LCD × 1:Venusa 使用外接屏,ARCS EVB 使用开发板原配屏。

USB 接口用途

两种板型的摄像头均通过芯片 USB 数据口外接,烧录与串口日志使用独立的烧录/串口口:

板型

摄像头连接口

烧录/串口口

venusa_rd_evb

J1(丝印 USB_ARCS)

J46(CH343P)

arcs_evb

芯片 USB 数据口

板载烧录/串口口

Venusa 的 J1/J46 编号以 7S_RD_EVB_V1_0.pdf 原理图为准;ARCS EVB 接口位置请参考 ARCS EVB 板型说明。

单摄像头直接通过合适的转接线连接。需要连接两台时,在开发板与摄像头之间增加 USB 2.0 High-speed Hub,建议使用带独立电源的 Hub,以满足摄像头供电需求。

USB Host 供电与 CC 配置

两种板型作为 Host 接外设时,都需要保证摄像头获得稳定的 5 V 供电,并按实际板卡和转接线确认 Type-C CC 配置。可使用带 Host 供电的转接板或带独立电源的 USB Hub。

Venusa RD EVB 的 J1 默认硬件配置面向 Device 使用,依据上述原理图:

  • VBUS 5 V 输出:J1 的 VBUS 经 D2(SS24)连接板内 VBUS,默认方向是外部 VBUS 输入,不能保证向摄像头输出 5 V。应在 J1 连接器侧实测约 5 V;若为 0 V,按板级方案调整供电路径,或使用带 Host 供电的外部转接板。SW1 仅控制板内 5V_IN → VBUS,仍需确认连接器侧电压。

  • CC1 / CC2:默认 R3/R4 为 5.1 kΩ 下拉(Rd,Device/受电端)。作为 Type-C Host/供电端时,应按板级供电设计配置 Rp 上拉,具体阻值与供电能力匹配。

ARCS EVB 的供电路径和 CC 配置应以实际板卡原理图为准,上述 D2、SW1、R3/R4 说明仅适用于 Venusa RD EVB。

软件中的 USBC_CFG_IDDIG = 0 只切换 USB 控制器角色,不会改变板上的供电路径或 CC 电阻。供电及 CC 配置不正确时,摄像头可能无法上电或枚举。

显示屏

ST7789P3 LCD 的物理分辨率为 240×320,LVGL 旋转 270° 后逻辑分辨率为 320×240。

  • Venusa RD EVB:使用外接 ST7789P3 SPI 屏,LCD 引脚在 src/video_display.c 中配置,并覆盖板级默认 pinmux:

LCD 信号

Venusa 引脚

复用功能

SCLK

PA22

SPI1 CLK,ALT6

MOSI / SDA / D0

PA23

SPI1 MOSI,ALT6

CS

PA21

GPIOA 输出,ALT0,软件片选

D/C / DC / RS

PA24

GPIOA 输出,ALT0

RST / RES

PA26

GPIOA 输出,ALT0

BL 控制

PA14

PWM0 channel 0,ALT11,2 kHz,低电平有效

此引脚映射针对 Venusa;soc/arcs/pinmux.yaml 是 ARCS/LS26XX 的映射,不能套用于 Venusa。

  • ARCS EVB:使用开发板原配 SPI 屏,通过板载屏幕连接器连接,无需按 Venusa 的引脚表重新接线。src/video_display.c 的 ARCS 分支沿用原配屏的引脚分配,并覆盖板级 SPI1 和 GPIO pinmux,将 PB5 配置为 GPIO 软件片选;背光继续使用 boards/arcs_evb/pinmux.c 中的默认 PWM 配置。以下复用功能已按 soc/arcs/pinmux.yaml 核对:

LCD 信号

ARCS EVB 引脚

复用功能

SCLK

PB3

SPI1 CLK,ALT6

MOSI / D0

PB1

SPI1 MOSI,ALT6

CS

PB5

GPIOB 输出,ALT0,软件片选

D/C / DC

PB0

GPIOB 输出,ALT0

RST / RES

PA1

GPIOA 输出,ALT1

BL 控制

PA0

PWM channel 0,ALT12,2 kHz,低电平有效

SPI 配置为 Mode 3、50 MHz;MISO 和 TE 未使用。屏幕与开发板须共地,供电和背光接法按屏幕模组规格连接。不要同时启用占用这些引脚的 DVP/RGB 接口。

示例内容

  1. 根据目标板型配置 USB PHY 和时钟为 Host 模式,并初始化对应的 ST7789P3 SPI LCD 和 LVGL。

  2. 外接 UVC 摄像头插入后,枚举设备并解析支持的格式、分辨率和端点信息。

  3. 选择格式和分辨率,通过 UVC Probe/Commit 协商视频参数;ISO 模式下还会结合接收带宽选择未压缩视频分辨率。

  4. 从 PSRAM 分配帧缓冲,按摄像头端点类型启动 Bulk 或 ISO 接收,组装完整视频帧。

  5. 将待显示帧交给 UI 任务,完成 YUY2 转换或 MJPEG 解码,更新全屏预览;运行期间约每秒打印接收和显示统计。

  6. 摄像头拔出后停止 URB,释放帧缓冲等资源,等待再次插入。

主要文件:

文件

作用

src/main.c

Host 初始化、格式选择、采集任务和周期统计

src/video_display.c

LCD 引脚配置(区分板型)、图像转换、LVGL 预览

src/cherryusb/usbh_video.c

UVC 协商、帧组装、Bulk/ISO 接收和帧缓冲管理

src/cherryusb/usb_hc_musb.c

本工程使用的 MUSB Host 控制器实现

src/usb_config.h

USB 设备数量、缓冲对齐等配置

编译

安装 SDK 所需工具链后,在 SDK 根目录执行:

Venusa RD EVB:

bash build.sh -j8 \
  -S samples/subsys/usb/host/cherryusb_video_usb \
  -B build_cherryusb_video_usb_venusa \
  -DBOARD=venusa_rd_evb

ARCS EVB:

bash build.sh -j8 \
  -S samples/subsys/usb/host/cherryusb_video_usb \
  -B build_cherryusb_video_usb_arcs \
  -DBOARD=arcs_evb

本示例未显式切换应用核心,沿用芯片默认配置:Venusa 为 AP 核(Hart 0),ARCS 为 CP 核(Hart 1),实际结果以构建目录中的 .config 为准。生成的固件位于对应 -B 指定的构建目录下的 arcs.bin。

烧录

电脑连接板载烧录/串口口,按板卡操作进入下载模式。在 SDK 根目录执行:

Venusa RD EVB:

./tools/burn/cskburn -C venusa -s /dev/ttyACM0 -b 3000000 \
  0x0 build_cherryusb_video_usb_venusa/arcs.bin

ARCS EVB:

./tools/burn/cskburn -C arcs -s /dev/ttyACM0 -b 3000000 \
  0x0 build_cherryusb_video_usb_arcs/arcs.bin

将 /dev/ttyACM0 替换为实际串口设备。-C 指定芯片系列(Venusa 为 venusa,ARCS/LS26 为 arcs),0x0 为固件烧录地址。烧录完成后复位开发板,通过烧录/串口口以 921600 波特率查看日志,将外接摄像头连接到已配置好 Host 供电的 USB 口。

预期输出

启动时可看到以下日志,具体前缀以实际日志配置为准:

========================================
  CherryUSB Host Video Example
  Preferred format: MJPEG (auto-negotiated from device)
  Max devices: 2
========================================

[INFO] Initializing display...
[INFO] Initializing USB Host...
[INFO] USB Host initialized, please connect USB cameras

插入摄像头后会打印设备信息、协商结果及接收模式。以下为 YUY2、320×240、ISO 模式的日志片段示意,实际值取决于摄像头:

[VIDEO0] Camera connected: video0
[VIDEO0] Opening device (format=UNCOMPRESSED 320x240)...
...
[VIDEO0] frame_buf allocated: 153600 B (320x240)
[VIDEO0] Starting ISO streaming...
[VIDEO0] Streaming started

运行期间约每秒输出 [VIDEO0] Running: ... 和 [DISP0] ...,主要字段如下:

字段

含义

frames / last

已交付完整帧数 / 最近一帧的视频数据字节数

gap

完整帧交付间隔,以及观测到的最小、最大间隔(ms)

bad / last_bad

被丢弃的异常帧数 / 最近异常帧的数据字节数

busy

因帧缓冲仍被显示任务占用而丢弃的帧数

pkt_err

检测到的接收或 UVC payload 错误计数,不等同于精确丢包数

converted / decode_err

成功转换或解码的帧数 / 解码失败数

convert / wait

图像处理耗时 / 帧等待显示处理的时间(ms)

YUY2 的完整帧大小为 宽 × 高 × 2,例如 320×240 对应 153600 字节;MJPEG 为压缩数据,帧大小可随图像内容变化。LCD 显示缩放到 320×240 的全屏画面,并标注摄像头编号。

验证方法

分别在 venusa_rd_evb 和 arcs_evb 上执行以下步骤,保存各板型的串口日志和画面观察结果:

  1. 启动显示和 Host:烧录对应板型固件后复位,确认出现 USB Host initialized,LCD 点亮并显示 CAM: waiting...。

  2. 插入摄像头:通过芯片 USB 数据口连接已供电的 UVC 摄像头,确认出现 Camera connected、协商格式和分辨率,以及 Streaming started。

  3. 确认实际出图:移动摄像头或镜头前的物体,确认 LCD 画面随之变化、颜色和布局正常,无局部错位、重复条带或持续停帧。仅有 Streaming started 不能证明图像显示成功。

  4. 观察运行统计:连续运行数分钟,确认 frames 和 converted 持续增加;记录 bad、busy、pkt_err 和 decode_err 的变化,结合实际画面判断是否存在接收或解码异常。busy 增加可能是显示处理较慢导致丢帧,不等同于摄像头断开。

  5. 热插拔验证:拔出摄像头,确认出现 Camera disconnected 和资源清理日志;重新插入后应再次启动视频流并恢复画面,系统不应崩溃。

基础验证使用一台摄像头即可。若需要验证 MJPEG、YUY2 或双摄像头 Hub 场景,应分别记录协商结果与显示情况;双摄像头共用一个全屏预览区域,并非分屏显示。

配置说明

prj.conf

配置项

值

说明

CONFIG_CHERRYUSB_HOST_VIDEO

y

启用 UVC Host

CONFIG_CHERRYUSB_HOST_MUSB_LISA

y

启用 MUSB Host 控制器

CONFIG_PSRAM_HEAP

y

启用 PSRAM 动态堆

CONFIG_PSRAM_HEAP_SIZE

0x500000

PSRAM 堆大小,5 MiB

CONFIG_LISA_DISPLAY_PANEL_ST7789P3

y

启用 ST7789P3 LCD 驱动

CONFIG_LV_DRIVER_ROTATE_270

y

旋转为 320×240 横屏

CONFIG_LV_USE_GPU_CSK_DMA2D

y

启用 DMA2D 显示加速

CONFIG_LV_USE_SJPG

y

启用 TJpgDec,供 MJPEG 解码使用

src/usb_config.h

配置项

值

说明

CONFIG_USBHOST_MAX_VIDEO_CLASS

2

最多可分配的 UVC 设备实例数

CONFIG_USB_ALIGN_SIZE

32

DMA 缓冲区对齐字节数

CONFIG_USBH_VIDEO_BULK_CHUNK_SIZE

512

dwMaxPayloadTransferSize 为 0 时,Bulk 接收缓冲区的默认长度,不代表固定的 USB 包大小

首选视频格式由 src/main.c 中的 VIDEO_FORMAT_PREF 控制,当前为 USBH_VIDEO_FORMAT_MJPEG。

注意事项

  1. 适用板型:本工程同时支持 Venusa RD EVB(-DBOARD=venusa_rd_evb)和 ARCS EVB(-DBOARD=arcs_evb)。Venusa 使用外接 ST7789P3 SPI 屏,ARCS EVB 使用开发板原配 SPI 屏。

  2. ISO 带宽限制:当前接收实现按每微帧最多 1 次事务、最多 1024 字节设计,不支持每微帧多次事务的高带宽 ISO 模式。摄像头分辨率、帧率应匹配实际接收带宽。

  3. 预览和采集帧率:USB 2.0 High-speed 的 480 Mbps 是总线标称速率,实际帧率还取决于摄像头协商参数、接收处理、解码及 SPI 显示耗时。

  4. 兼容性验证:MJPEG 解码和多摄像头路径已实现,但尚未完成对应的实板验证;实际使用需结合摄像头格式、供电和日志确认。