USB UVC 设备示例
源码位置: samples/subsys/usb/device/uvc 查看源码
功能说明
演示如何使用 USB UVC(USB Video Class)设备功能将摄像头采集的视频流通过 USB 接口传输到 PC,使设备作为标准 USB 摄像头被识别和使用。
本示例基于 TinyUSB 协议栈实现 UVC 设备功能,支持将 LISA Camera 采集的 图片格式为YUV422(YCbYCr422) ,图片大小为640*480的视频流实时传输到PC端,可被PC标准视频应用程序(如 ffmpeg、VLC或potplayer等)直接使用。
硬件连接
开发板
Arcs-EVB开发板
摄像头连接
摄像头模组: GC0328 DVP 接口摄像头
接口类型: DVP(Digital Video Port)
I2C 配置: I2C0 用于摄像头配置
USB 连接
连接方式: Arcs-EVB开发板的USB_ARCS的USB口通过USB线缆连接到PC
示例内容
初始化 LISA Camera 驱动,配置摄像头分辨率和像素格式
初始化 USB UVC 设备,配置 USB 描述符和 UVC 类参数
注册摄像头帧回调函数,接收采集的视频帧
启动摄像头采集,通过 UVC 接口将视频流传输到 PC
PC 端识别为标准 USB 摄像头设备
编译
重要提示:在编译前,请先确认您使用的开发板型号。SDK 目前支持以下开发板:
arcs_evb - ARCS EVB 评估板
arcs_mini - ARCS Mini 开发板
根据您的开发板型号,选择对应的编译命令:
在示例目录下执行编译:
# 使用 arcs_evb 开发板
./build.sh -C -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -DBOARD=arcs_mini
Note
如果在 SDK 根目录执行,需要指定示例路径:
# 使用 arcs_evb 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_mini
Note
确保已安装对应的工具链。
烧录
编译完成后,使用 SDK tools 目录下的 cskburn 工具烧录固件:
./tools/burn/cskburn -s /dev/ttyUSB0 -b 3000000 0x0 build/arcs.bin -C arcs
Note
烧录参数说明:
-s /dev/ttyUSB0:串口设备路径,需要根据实际情况修改 - Linux 系统:通常是/dev/ttyUSB0或/dev/ttyACM0- 可通过ls /dev/tty*命令查看可用串口设备 - 不同开发板或 USB 转串口芯片可能使用不同的设备名-b 3000000:烧录波特率(3Mbps)0x0:烧录起始地址build/arcs.bin:编译生成的固件路径-C arcs:芯片类型
注意事项:
确保开发板已正确连接到电脑
如果无法识别串口设备,请检查 USB 连接线是否正常,或尝试其他 USB 端口
预期输出
设备端日志:
********Arcs SDK 0.1.0 @ v0.0.1-779-g94ba42f861c1********
Running on hart-id: 1
I/elog [1034:42:44.160 1 elog_async] EasyLogger V2.2.99 is initialize success.
I/lisa_i2c_arcs [1034:42:44.161 1 elog_async] I2C0 initialized successfully
I/lisa_dvp [1034:42:44.161 1 elog_async] DVP driver initialized
I/main [1034:42:44.163 1 main] === Camera UVC Streaming Demo
I/main [1034:42:44.163 1 main] Resolution: 640x480 @ 15 fps
I/video_camera [1034:42:44.163 1 main] camera device ready
I/video_camera [1034:42:44.163 1 main] Setting up camera...
I/lisa_camera [1034:42:44.165 1 main] PWDN pin initialized (pin=7)
I/lisa_camera [1034:42:44.165 1 main] Enabling XCLK output: 12000000 Hz
I/lisa_i2c_arcs [1034:42:44.167 1 main] I2C configured: speed=400000 Hz, mode=master
I/lisa_camera [1034:42:44.169 1 main] Sensor detected: PID=0x009D, addr=0x21
I/lisa_camera [1034:42:44.655 1 main] Detected sensor frame size: 640x480
I/lisa_camera [1034:42:44.657 1 main] Detected sensor pixel format: 0
I/lisa_camera [1034:42:44.657 1 main] Frame buffers initialized: count=5, size=614400
I/lisa_camera [1034:42:44.657 1 main] Camera setup completed
I/video_camera [1034:42:44.657 1 main] Camera capabilities: max_width=640, max_height=480, supported_formats=0x00000005
I/lisa_camera [1034:42:44.666 1 main] Frame buffers re-initialized: count=5, size=614400
I/lisa_camera [1034:42:44.670 1 main] Frame buffers re-initialized: count=5, size=614400
I/lisa_dvp [1034:42:44.670 1 main] DVP initialized successfully with GPDMA channel 2
I/lisa_dvp [1034:42:44.670 1 main] DVP clockout enabled successfully, freq: 12000000 Hz
I/video_camera [1034:42:44.671 1 camera_task] Capture task started
I/video_camera [1034:42:44.671 1 main] Camera capture started with internal task
I/uvc_stream [1034:42:44.671 1 main] TinyUSB UVC class ready
I/video_camera [1034:42:44.673 1 main] Frame callback registered
I/lisa_dvp [1034:42:44.673 1 main] DVP capture started
I/camera_bus_dvp [1034:42:44.673 1 main] DVP Normal capture started
I/lisa_camera [1034:42:44.673 1 main] Camera started
I/main [1034:42:44.673 1 main] Camera capture started
I/camera_bus_dvp [1034:42:44.863 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:44.950 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:45.037 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:45.123 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:45.210 1 isr] dvp_event_callback: event:1
I/uvc_stream [1034:42:45.258 1 usbd] USB mounted
I/camera_bus_dvp [1034:42:45.297 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:45.383 1 isr] dvp_event_callback: event:1
I/camera_bus_dvp [1034:42:45.470 1 isr] dvp_event_callback: event:1
PC 端测试方法
Windows
正常情况下设备管理器中查看”照相机”或”图像设备”分类下面是否有一个UVC Control的设备,如果有则进行下面操作
# 打开设备查看图片数据
ffplay.exe -f dshow -pixel_format yuyv422 -video_size 640x480 -i video="UVC Control"
# 保存图片数据到文件
ffmpeg.exe -f dshow -video_size 640x480 -pixel_format yuyv422 -i video="UVC Control" -c:v rawvideo out_yuyv.avi
Linux
# 查看video设备
➜ v4l2-ctl --list-devices # 得到名字为TinyUSB的设备,实际设备为/dev/video2,如下所示
TinyUSB Device: UVC Control (usb-0000:00:14.0-3.3.1.3):
/dev/video2
/dev/video3
/dev/media1
# 使用ffplay播放视频(具体设备由上面命令得出,此处假设设备为/dev/video2)
ffplay \
-f v4l2 \
-input_format yuyv422 \
-video_size 640x480 \
-i /dev/video2
# 保存YUYV422原始图片数据到文件(具体设备由上面命令得出,此处假设设备为/dev/video2)
ffmpeg \
-f v4l2 \
-input_format yuyv422 \
-video_size 640x480 \
-i /dev/video2 \
-c:v rawvideo \
out_yuyv_640x480.avi
核心 API
Camera API
API |
说明 |
|---|---|
|
初始化摄像头,配置分辨率和格式 |
|
注册帧回调函数 |
|
启动摄像头采集 |
|
停止摄像头采集 |
UVC API
API |
说明 |
|---|---|
|
初始化 UVC 设备 |
|
发送视频帧数据到 UVC |
关键代码
摄像头初始化
/* 配置摄像头参数 */
camera_config_t config = {
.width = CONFIG_IMAGE_WIDTH,
.height = CONFIG_IMAGE_HEIGHT,
.format = LISA_CAMERA_PIXFMT_YUV422,
};
ret = video_camera_init(&config);
帧回调处理
/* 摄像头帧回调函数 */
static void on_frame_captured(camera_frame_t *frame, void *user_data)
{
/* 将摄像头帧数据发送到 UVC */
uvc_stream_send_data((video_info_t *)frame);
}
/* 注册回调 */
video_camera_register_callback(on_frame_captured, NULL);
UVC 数据传输
/* 初始化 UVC */
ret = uvc_stream_init();
/* 启动采集 */
ret = video_camera_start_capture();
注意事项
摄像头型号: 目前仅测试GC0328
内存需求: UVC 传输YUYV422原始图片需要大量内存缓冲,确保 PSRAM 配置足够
USB 连接: 需确保 USB 线缆支持USB2.0的480Mbps的数据传输速度
帧率限制: 实际帧率受MCU处理性能限制,低于配置值,实测FPS=11.5(在linux平台测试)
像素格式: 当前示例仅使用 YUV422(YCbYCr422) 格式,帧大小为640480,用户可以扩展其他帧格式(如mpeg)和帧大小(如320240)
驱动支持: Windows 10/11、Linux均原生支持 UVC 设备,无需额外驱动
回调线程: 帧回调在摄像头驱动线程中执行,避免在回调中执行耗时操作