此处我只说用uvc通用驱动
查询摄像头是否是UVC设备,参见官网
- 1 找到CAMERA ID
-
2 lsusb -d VID:PID -v | grep “14 Video”
如果输出有下面信息说明支持bFunctionClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Video
bInterfaceClass 14 Videolsusb -d VID:PID -v 可以列出了一个usb设备的有所信息,接口,更详细的树形图lsusb -t
UVC驱动代码详解
详情请看此系列博文
我要说的一点就是该驱动的可能限制,在写应用程序时就要注意到。
uvc_driver.c里头一段话就说了驱动的限制:
This driver aims to support video input and ouput devices compliant with the ‘USB Video Class’ specification.
The driver doesn’t support the deprecated v4l1 interface. It implements the mmap capture method only, and doesn’t do any image format conversion in software. If your user-space application doesn’t support YUYV or MJPEG, fix it :-). Please note that the MJPEG data have been stripped from their Huffman tables (DHT marker), you will need to add it back if your JPEG codec can’t handle MJPEG data.
从中看出以下几点:
- 1 只支持mmap方式 ,不支持read,usrptr什么的。所以v4l2里说的用户获取摄像头数据的方式有三种在这个驱动里那是没有的,到底支不支持你要看看你自己的内核里面的驱动说明了。
- 2 不再支持v4l1接口
- 3 不做任何图像格式转换,只输出YUYV或MJPEG(?)
- 4 MJPEG 格式的data没有Huffman tables,所以如果要做格式转换需要自己加入Huffman tables才行。
明明是UVC摄像头,但不是不支持怎么办?
更新驱动文件吧,下载下来的内核里的uvc驱动并不是最新的,现在摄像头更新的快且多,肯定是跟不上的,因此需要自己修改,一般在 static struct usb_device_id uvc_ids[]这个结构里增加你的摄像头型号就好了:
比如我的摄像头是0ac8:3420,就不支持,那么在drivers/media/video/uvc/uvc_driver.c
的uvd_ids中增加如下就行。
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x0ac8,
.idProduct = 0x3420,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_FIX_BANDWIDTH },
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
譔结构如下
struct usb_device_id {
/* which fields to match against? */
__u16 match_flags;
/* Used for product specific matches; range is inclusive */
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;
/* Used for device class matches */
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
/* Used for interface class matches */
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
/* Used for vendor-specific interface matches */
__u8 bInterfaceNumber;
/* not matched against */
kernel_ulong_t driver_info
__attribute__((aligned(sizeof(kernel_ulong_t))));
};
/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
match_flags用上面的宏赋值,是个位或值,可用”|”赋多值,
driver_info的值可参考What are quirks and how do I use them?
心得
在编译uvc驱动的内核时,最好将它们以模块的方式编译内核,并勾选上自动加载(Automatic kernel module loading),新版内核如果选择了加载模块就默认了似乎,因为我也没找到这选项。一插上摄像头,uvc相关模块就自动加载了。如下:
# lsmod
Module Size Used by Not tainted
uvcvideo 64611 0
videobuf2_core 21211 1 uvcvideo
videodev 85103 2 uvcvideo,videobuf2_core
videobuf2_vmalloc 2119 1 uvcvideo
videobuf2_memops 1550 1 videobuf2_vmalloc
leds_s3c24xx 1193 0
led_class 2321 1 leds_s3c24xx
evbug 1594 0
#
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
要想能自动加载,需要了解下Linux中加载模块有关的几个命令:
depmod, modprobe, lsmod,insmod
-
首先安装模块到文件系统中:
make modules_install INSTALL_MOD_PATH=/path/to/rootfs
- 1
- 1
这样会将编译出来的模块安装到/path/to/rootfs/lib/kernel-version/modules下
-
在开发板上运行depmod。
depmod没有这个命令工具则在busybox中的Linux Module Utilities选中再编译。
这样驱动要更新,直接替换了原来的驱动文件就可以了,不需要每次都去编译内核这么麻烦。
-
顶
- 0
-
踩
- 0
我的同类文章
- •RGB565,RGB24,YUV2016-09-22
- •Linux UVC driver 独立交叉编译记录2016-09-06
- •记录USB摄像头的几个问题2016-09-13
- •v4l2 camera测试程序 保存成图片2016-04-27