[问题分类]:硬件(摄像头)
[板卡类型]:RDK S100
在尝试在RDK S100上部署YOLO的时候,接入的两个usb摄像头都存在问题,其中一个在运行相关代码后会掉线,另一个在开机后无法识别。
具体表现为:摄像头1 第一遍lsusb可以识别到该设备,运行一次需要调用该摄像头的代码后,再一次lsusb该摄像头就无法被识别到,此时该相机连接的USB口以及与之同属一个接口的另一个USB口均无法识别任何USB设备
摄像头2 在板子为开机前接入板上USB口,开机后无法识别到该相机,重新插拔后可以识别到。在运行中也会出现和摄像头1一样的问题。
补充信息:
摄像头1和2是完全相同的两个摄像头;
摄像头1的掉线问题在dmesg日志中无记录,只有在掉线后会日志会反复报错无法识别到摄像头;
运行代码:任何一段使用cv库打开摄像头的代码都有可能触发摄像头掉线问题,终端l4v2在几次测试中并未引发该问题;
应该不会是供电问题,测量接入摄像头工作时USB口电流仅0.112A,功率不足0.6W
最可能的原因不是供电,而是 USB 带宽:S100 上下两个 USB 口属于同一个 USB host,uvcvideo 发起取流时带宽申请超限,会把整个 host 搞挂——这正好解释「掉线后同组两个口都认不出任何设备」,以及 v4l2 简单测试不触发、OpenCV 一开流就触发。官方文档对接双 USB 摄像头有明确要求:先限制 uvcvideo 带宽。
排查步骤:
- 按官方要求加载 uvcvideo 带宽限制参数,再插摄像头:
sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128
验证稳定后可持久化:在 /etc/modprobe.d/uvcvideo.conf 里加一行 options uvcvideo quirks=128。
-
两个摄像头分开插到左右两个口(不同 host),不要插在上下同组口。另外同一个 host 带不动两路 720p@30fps(USB2.0 带宽就 480Mb/s),建议先用 640x480@20fps 验证稳定性。
-
如果加了 quirks 单接一路还是稳定掉线,一个终端挂 sudo dmesg -w,另一个终端复现,把掉线瞬间的报错(比如 device descriptor read/64, error -110/-71)和摄像头 lsusb 的 VID:PID 回帖发出来,再往下定位。
摄像头2 开机不识别、重插就好,大概率和上面的枚举异常同源,先做完第 1、2 步一起验证。
参考官方文档(含双摄带宽说明):
单摄像头的时候就有掉线的问题。
此外,官方文档以及终端lsusb -t都读到USB口是3.0的啊?在另一个相机(第三个,usb2.0)上可以验证640x480@30fps不会引发掉线问题,但在我需要使用的usb3.0相机,以640x480@60fps就会掉线(实测该相机无论@60还是@200都会掉线)
摄像机掉线瞬间dmesg 读不到任何报错。程序结束运行后去lsusb时是可以读到的,再一次运行程序就可能出现掉线,同时日志开始反复出现uvcvideo: 2‑2:1.1: Failed to query (129) UVC probe control :‑110 (exp. 34).
我的相机是 usb3.0的,现在测试也可以跑到200fps,这是受限于usb host?
最可能原因:USB 等时带宽不够导致 UVC 协商超时。-110 就是 ETIMEDOUT——640x480@60 如果是 YUYV 裸流约需 295Mb/s,已逼近 USB 等时传输上限,probe 阶段协商不下来就直接超时掉线;你 2.0 相机 30fps 没问题也印证是带宽问题。官方文档对 S100 双 USB 相机场景也明确要求先限制 uvcvideo 带宽。
排查步骤:
1)按官方文档先限制 uvcvideo 带宽,再跑程序验证:
sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128
文档参考:3.1.2 USB 摄像头使用 | RDK S100/S600 DOC
2)优先用 MJPG 格式取流。如果程序里按 YUYV 开 60fps,改成 MJPG(V4L2 里就是 pixelformat 从 YUYV 换成 MJPG),带宽能降一个数量级,大概率直接解决。
3)注意 USB host 分布:S100 上下两个口是同一个 host,左右两个口才是独立 host。相机直插板子,不要过 hub;如果同时接两路,左右口各插一个。
4)跑程序时另开一个终端挂着 dmesg -w,掉线瞬间若有 xhci 相关报错(比如带宽分配、reset 之类)把它贴上来。
如果 MJPG@60fps + quirks=128 还是掉,补充下相机具体型号和 v4l2-ctl -d /dev/videoX --list-formats-ext 的输出,再往下看。
先回答帧率问题:200fps 是不是卡在 USB 上,算一笔账就知道。
USB 3.0 理论带宽 5Gbps,实际有效吞吐大概在 400MB/s 量级。你的需求带宽 ≈ 宽 × 高 × 每像素字节数 × fps,拿这个数和有效带宽比:
- 算出来远小于 400MB/s:USB 不是瓶颈,200fps 多半就是这颗相机传感器/固件本身的上限;
- 算出来接近或超过:才是被 USB 卡住。
再确认两件事:
# 看相机是否协商到 USB3.0(Speed=5000M),如果显示 480M 说明掉到了 USB2.0 模式,那瓶颈就是它
lsusb -t
# 看相机支持的所有格式和对应最大帧率
v4l2-ctl -d /dev/video0 --list-formats-ext
另外注意 S100 有两个 USB host,上下两个口是同一个 host,多相机要分到左右两个口插,避免共享带宽。官方 USB 摄像头说明:
关于标题说的掉线:高帧率时相机功耗和总线负载都高,先看供电(用板子原装电源、别用劣质 hub)和换根短线试试;掉线瞬间内核一般有记录:
dmesg | grep -i usb
如果日志里反复出现 disconnect/over-current,基本就是供电或线缆问题,而不是软件问题。
这边在 S100 4.0.5-Beta 上接了三只真实 UVC 摄像头,把“单路、同主控并发、反序启动”拆开测了一遍。现象可以稳定复现,但需要把两类错误分开看。
先看拓扑。三只摄像头虽然插在不同物理口,lsusb -t 中却都只显示 480M;其中两只落在同一个 USB2 主控 Bus 1,第三只在 Bus 3。这里要看摄像头设备所在的那一行,不能只看根 Hub 或蓝色插口是不是 USB3。
三只相机单独打开都能完成采集:一只 640×480 MJPG 约 98.7fps,另外两只 1080P MJPG 分别约 29.7fps、21.8fps。并发打开时,Bus 3 上的相机和 Bus 1 上第一只相机可以工作,但 Bus 1 的第二只会在 VIDIOC_STREAMON 直接返回:
VIDIOC_STREAMON returned -1 (No space left on device)
usb 1-2: Not enough bandwidth for new device state.
usb 1-2: Not enough bandwidth for altsetting 11
把启动顺序反过来后,失败者也跟着交换:先开 Sunplus,后开的 HIK 报 ENOSPC;先开 HIK,后开的 Sunplus报 ENOSPC。所以这组现象不是某个 /dev/videoX 固定损坏,而是两只 UVC 等时端点共用一个 480M 主控时,后启动者申请不到带宽。失败后所有视频节点仍在,也没有相机掉线。
建议先按下面顺序排查:
lsusb -t
v4l2-ctl -d /dev/video0 --list-formats-ext
v4l2-ctl -d /dev/video2 --list-formats-ext
# 分别单开,确认两路都能独立工作
v4l2-ctl -d /dev/video0 \
--set-fmt-video=width=640,height=480,pixelformat=MJPG \
--set-parm=60 --stream-mmap=4 --stream-count=300 --stream-to=/dev/null
# 再同时打开,并紧跟内核日志
sudo dmesg -w
- 如果两只相机在
lsusb -t 中都挂在同一个 480M Bus 下,优先把其中一路换到另一个主控对应的物理口;不是简单换同一 Hub 上的孔。
- 使用 MJPG,并严格选择
--list-formats-ext 中实际存在的分辨率和帧率。降低平均码率有帮助,但 UVC 等时传输还要按设备声明的 altsetting/最大包长预留,不能只用“宽×高×fps”估算。
- 独立供电 Hub 只能改善供电,不能增加同一上游主控的总线带宽。若 Hub 所有口共享一个上行链路,带宽仍然共享。
- 真正的 USB3 摄像头应在摄像头自身那一行显示
5000M 或更高;它不是解决问题的必要条件,但若设备实际支持 SuperSpeed,让高速相机协商到 5000M 可以把它移出 USB2 的 480M 预算。
还需要纠正一点:uvcvideo quirks=128 对应 Linux 的 UVC_QUIRK_FIX_BANDWIDTH,源码中的带宽重算分支只对未压缩格式生效,不能把它当成 MJPG 的通用修复。不要一上来就写入 /etc/modprobe.d;先用拓扑和正反启动 A/B 确认问题层级。
帖子里的这条日志:
Failed to query (129) UVC probe control :-110
属于 UVC 控制传输超时,不能仅凭 -110 就等同于带宽不足。如果出现的是“相机从 lsusb 消失、同组设备一起失联”,需要同时保留故障前后的 lsusb -t、相机 VID:PID 和事件窗口内 dmesg -w;这时还要继续排查相机固件、USB3 协商、数据线以及 xHCI 恢复,和上面的 ENOSPC 是不同层。
附件里的脚本默认只收集拓扑、格式和日志;只有显式传入 --stream 才会并发压测。它还会扫描日志内容,因为实测中 v4l2-ctl 在 STREAMON 失败时可能仍返回 0,单看 shell 退出码会误判。
bash s100_uvc_multi_diag.sh --stream \
/dev/video0:MJPG:640:480:60 \
/dev/video2:MJPG:640:480:60
topic35658_s100_uvc_multi_diag.zip (2.4 KB)
本次实机已经验证的是:S100 上共享同一 480M 主控的两路 UVC 可以稳定复现带宽分配失败,并能通过反序启动确认机制。没有使用 USB3 摄像头,也不把楼主的 SuperSpeed -110/整组失联宣称为已经复现;如果楼主把上述三份信息贴出来,可以继续判断是端点预算还是设备/链路超时。