USB Gadget 模拟摄像头 g_webcam: musb-hdrc.4.auto: failed to start g_webcam: -22
-
大家好,
最近想用 OrangePi One (H3) 做一个虚拟摄像头,在开发板上读取原始摄像头的图像,做一些图像处理,再虚拟一个摄像头发到电脑上。
我参考的这个树莓派的项目:
https://github.com/likeablob/rpi-wfh-webcam
在树莓派上 modprobe g_webcam 可以正常加载,但是在好几块 H3 的板子上 (运行的 Armbian) 都报同样的错误:
$ sudo modprobe g_webcam musb-hdrc.4.auto: failed to start g_webcam: -22
于是我又尝试了更新的 configfs,但是依旧是同样的错误:
https://developer.ridgerun.com/wiki/index.php?title=How_to_use_the_UVC_gadget_driver_in_Linux
sudo modprobe libcomposite dwc2 usb_f_uvc mkdir -p /sys/kernel/config/usb_gadget/g1 cd /sys/kernel/config/usb_gadget/g1 echo 0x0525 > idVendor echo 0x0102 > idProduct mkdir -p strings/0x409 echo 0123456789 > strings/0x409/serialnumber echo $(hostname) > strings/0x409/manufacturer echo "UVC Gadget" > strings/0x409/product mkdir configs/c.1 mkdir configs/c.1/strings/0x409 mkdir functions/uvc.0 mkdir -p functions/uvc.0/streaming/uncompressed/u/360p cat <<EOF > functions/uvc.0/streaming/uncompressed/u/360p/dwFrameInterval 666666 1000000 5000000 EOF mkdir functions/uvc.0/streaming/header/h cd functions/uvc.0/streaming/header/h ln -s ../../uncompressed/u cd ../../class/fs ln -s ../../header/h cd ../../class/hs ln -s ../../header/h cd ../../class/ss ln -s ../../header/h cd ../../../control mkdir -p header/h ln -s header/h class/fs ln -s header/h class/ss cd ../../../ echo 2048 > functions/uvc.0/streaming_maxpacket ln -s functions/uvc.0 configs/c.1 ls /sys/class/udc > UDC
不过 g_serial 和 g_eth 都能正常工作,请问是不是 H3 的芯片本身 USB IP 核不支持模拟摄像头呢?
-
据说是端点(end point)不够。
-
@memory 多谢提醒,于是我对比了一下3个芯片的手册:
Allwinner H3:
https://wiki.friendlyarm.com/wiki/images/4/4b/Allwinner_H3_Datasheet_V1.2.pdfRaspberrypi Zero (BCM2835):
https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdfAllwinner D1:
https://dl.linux-sunxi.org/D1/D1_Datasheet_V0.1_Draft_Version.pdfH3 和 BCM2835 的 User-Configurable Endpoint 数量都是 8,D1 数量是 10,测试结果 H3 不能用 g_webcam,BCM2835 和 D1s 可以用。
我也感觉不是 linux 固件的问题,而是 H3 芯片本身不支持,但不完全确定是 Endpoint 数量不够造成的。
(内心还是希望芯片是支持的,不然就只能换芯片了 T_T)
-
@wuhanstudio 改UDC驱动,UDC驱动已经几百年没更新了。如果确定硬件端点够,改一下就可以了。
-
就是说D1 / D1s 可以模拟摄像头吗?
-
@uuuuid 是的,D1s 加载 g_webcam 模块后用 v4l2-ctl --list-devices 会出现虚拟的摄像头设备,可惜 H2/H3/H5 会报错 invalid argument -22,虽然只是少了2个端点
-
@wuhanstudio
确实, V3s 也不行:V3s Linux4.13执行modprobe g_webcam 出现端点错误, 是端点不够吗? 其他的 g_serial/g_ffs没问题
https://whycan.com/t_2915.html -
@tigger 不太确定是不是端点不够,D1s 有 10 个端点可以使用,但是 BCM2835 只有 8 个端点也能正常使用,H3 也是 8 个端点就报错了
-
有复合设备吗?把不必要的复合设备关掉,看能不能减少端点占用。
-
@aozima 多谢提醒,我检查了一下 configfs 只配置了 720p 的 MPJEG 摄像头设备,没有复合设备:
https://github.com/wuhanstudio/adversarial-camera/blob/master/configfs/usb-gadget.sh
发现 Invalid argument -22 报错就是最后一行无法配置 (Allwinner H2, H3, H5):
ls /sys/class/udc > /sys/kernel/config/usb_gadget/pi4/UDC
-
@uuuuid 我最近又试了一下,D1s 可以配置 USB Gadget 为摄像头,配置好之后 uvc-gadget 也可以启动,连接到 Windows 后检测到新设备,设备管理器出现了 UVC Camera,但是一旦打开摄像头软件 D1s 就会报错无法接收数据,暂时还没找到原因.
https://github.com/wuhanstudio/adversarial-camera/tree/master/uvc-gadget
# ./uvc-gadget -u /dev/video2 -v /dev/video0 -f 1 -r 1 Format: 1 0:YUYV 1:MJPEG V4L2 device is USB 2.0 Camera: USB Camera on bus usb-sunxi-ehci-1 V4L2: Getting current format: MJPG 1280x720 V4L2: Setting format to: MJPG 1280x720 V4L2: Getting current format: MJPG 1280x720 v4l2 open succeeded, file descriptor = 3 uvc device is sunxi_usb_udc on bus gadget uvc open succeeded, file descriptor = 4 V4L2: Buffer 0 mapped at address 0x3fc64ca000, length 1843789. V4L2: Buffer 1 mapped at address 0x3fc6307000, length 1843789. V4L2: 2 buffers allocated. [ 219.698224] sunxi_set_cur_vol_work()394 WARN: get power supply failed [ 219.744990] android_work: sent uevent USB_STATE=CONNECTED [ 219.773589] configfs-gadget gadget: high-speed config #2: c [ 219.779827] configfs-gadget gadget: uvc: uvc_function_set_alt(0, 0) [ 219.786814] configfs-gadget gadget: uvc: reset UVC Control [ 219.792940] configfs-gadget gadget: uvc: uvc_function_set_alt(1, 0) [ 219.800053] configfs-gadget gadget: uvc: uvc_function_set_alt(1, 0) [ 219.821854] configfs-gadget gadget: uvc: uvc_function_set_alt(1, 0) control request (req 81 cs 02) control request (req 81 cs 02) control request (req 81 cs 02) [ 219.838593] android_work: sent uevent USB_STATE=CONFIGURED [ 221.116837] sunxi_vbus_det_work()3292 WARN: get power supply failed [ 221.123844] configfs-gadget gadget: uvc: uvc_function_disable() [ 221.148585] android_work: sent uevent USB_STATE=DISCONNECTED [ 610.318603] ERR: Operation not supported [ 610.323187] ERR: Operation not supported [ 610.336907] android_work: sent uevent USB_STATE=CONNECTED [ 611.706855] sunxi_vbus_det_work()3292 WARN: get power supply failed [ 611.726906] android_work: sent uevent USB_STATE=DISCONNECTED [ 612.041672] ERR: Operation not supported [ 612.046235] ERR: Operation not supported [ 612.056868] android_work: sent uevent USB_STATE=CONNECTED [ 612.663794] ERR: Operation not supported [ 612.668374] ERR: Operation not supported [ 613.916841] sunxi_vbus_det_work()3292 WARN: get power supply failed [ 613.936900] android_work: sent uevent USB_STATE=DISCONNECTED [ 614.354751] ERR: Operation not supported [ 614.359314] android_work: sent uevent USB_STATE=CONNECTED [ 614.365351] ERR: Operation not supported [ 615.756834] sunxi_vbus_det_work()3292 WARN: get power supply failed [ 615.776902] android_work: sent uevent USB_STATE=DISCONNECTED [ 616.039829] ERR: Operation not supported [ 616.044524] ERR: Operation not supported [ 616.056874] android_work: sent uevent USB_STATE=CONNECTED [ 616.686031] ERR: Operation not supported [ 616.690586] ERR: Operation not supported [ 617.946849] sunxi_vbus_det_work()3292 WARN: get power supply failed [ 617.966909] android_work: sent uevent USB_STATE=DISCONNECTED
-
@baidxi 最新定位到 D1s 报错在 sunxi_udc.c (能识别到新 UVC 摄像头设备,但是没有数据):
ret = dev->driver->setup(&dev->gadget, crq);
上面这一行返回了 -EOPNOTSUPP, 完整代码:
buildroot/dl/linux/git/drivers/usb/sunxi_usb/udc/sunxi_udc.c Line 1383: DMSG_PANIC("ERR: Operation not supported\n"); spin_unlock(&dev->lock); ret = dev->driver->setup(&dev->gadget, crq); spin_lock(&dev->lock); if (ret < 0) { if (dev->req_config) { DMSG_PANIC("ERR: config change %02x fail %d?\n", crq->bRequest, ret); return; } if (ret == -EOPNOTSUPP) DMSG_PANIC("ERR: Operation not supported\n"); else DMSG_PANIC("ERR: dev->driver->setup failed. (%d)\n", ret); udelay(5); USBC_Dev_ReadDataStatus( g_sunxi_udc_io.usb_bsp_hdle, USBC_EP_TYPE_EP0, 1); USBC_Dev_EpSendStall( g_sunxi_udc_io.usb_bsp_hdle, USBC_EP_TYPE_EP0); dev->ep0state = EP0_IDLE; /* deferred i/o == no response yet */ } else if (dev->req_pending) { dev->req_pending = 0; }
-
@memory [ 98.945505] handle_ep0: ep0 setup end
[ 104.065802] handle_ep0: ep0 setup end请问这个是端点不够的意思吗? -
@wuhanstudio 这个有进展吗?我遇到了相同的情况
-
usb摄像头一般是USB ISO模式传输的,可能usb驱动将端点配置为BULK模式了,可以试试修改底层的usb驱动,drivers/usb/sunxi_usb/include/sunxi_udc.h和drivers/usb/sunxi_usb/udc/sunxi_udc.c,将ep5in_bulk_name修改为iso。
-
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号