目录
在”从零写的 UVC 驱动”程序基础上修改, 支持这款”USB/CMOS”二合一摄像头。
按照上一节我们进行第二步
2. 在"从零写的UVC驱动"基础上修改, 让它支持这款摄像头
a.用lsusb -v -d 0x1b3b:查看硬件差异
dmesg 命令或者内核打印的信息可以保存,修改时参考。
b.根据差异修改驱动程序
拷贝2.1.1.8中的14th命名为ip2970_ip2977_myuvc
我们要根据这些差异来设置这些全局变量
首先lsusb命令来查看差异
怎么使用:-d -v
lsusb -v -d 0x1b3b:
参考:ip2977_desc.TXT
1.1 修改全局变量
参考摄像头打印的信息完成修改(在14th myuvc.c基础上):
static int myuvc_bEndpointAddress = 0x81;//端点地址,传输视频数据
打印的信息中:搜索bEndpointAddress
VideoControl Interface Descriptor:
bEndpointAddress 0x81 EP 1 IN
bInterfaceSubClass 2 Video Streaming
bEndpointAddress 0x82 EP 2 IN
AudioStreaming Interface Descriptor:
bEndpointAddress 0x83 EP 3 IN
81是VideoControl Interface
82是Video Streaming
83是AudioStreaming Interface
传输视频数据选择0x82(Video Streaming),AudioStreaming 表示既可以支持视频也可以支持音频。
static int myuvc_bEndpointAddress = 0x82;
usb摄像头支持格式下面的几种分辨率:
VideoStreaming Interface Descriptor:
bNumFrameDescriptors 3
wWidth 640
wHeight 480
wWidth 320
wHeight 240
wWidth 160
wHeight 120
bcdUVC 1.00
bDescriptorSubtype 5 (PROCESSING_UNIT)
bUnitID 3
static struct frame_desc frames[] = {
{640, 480}, {320, 240},{160, 120}};
//static int bBitsPerPixel = 16; /* lsusb -v -d 0x1e4e: "bBitsPerPixel" */
//环宇飞扬摄像头一个像素占16位,usb摄像头输出压缩数据
static int uvc_version = 0x0100; /* lsusb -v -d 0x1b3b: bcdUVC */
static int ProcessingUnitID = 3;//设置音量等信息
关于
static int myuvc_streaming_bAlternateSetting = 8;
说明如下:
/* d. 设置VideoStreaming Interface所使用的setting
* d.1 从myuvc_params确定带宽
* d.2 根据setting的endpoint能传输的wMaxPacketSize
* 找到能满足该带宽的setting
*/
/* 手工确定:
* bandwidth = myuvc_params.dwMaxPayloadTransferSize = 1024
* 观察lsusb -v -d 0x1e4e:的结果:
* wMaxPacketSize 0x0400 1x 1024 bytes
* bAlternateSetting 8
*/
usb_set_interface(myuvc_udev, myuvc_streaming_intf, myuvc_streaming_bAlternateSetting);
先确定带宽bandwidth ,在打印信息中查找支持带宽的bAlternateSetting。
为了确定带宽,使用哪一个setting ,将myuvc_vidioc_streamon中确定带宽的函数:
/* a. 测试参数 */
ret = myuvc_try_streaming_params(&myuvc_params);
printk("myuvc_try_streaming_params ret = %d\n", ret);
/* b. 取出参数 */
ret = myuvc_get_streaming_params(&myuvc_params);
printk("myuvc_get_streaming_params ret = %d\n", ret);
/* c. 设置参数 */
ret = myuvc_set_streaming_params(&myuvc_params);
printk("myuvc_set_streaming_params ret = %d\n", ret);
myuvc_print_streaming_params(&myuvc_params);
放入
static int myuvc_probe(struct usb_interface *intf,const struct usb_device_id *id)
卸载usb摄像头自动安装的驱动,编译myuvc驱动,安装新的驱动,打印信息
(这还是在PC上测试)
[ 1260.095158] myuvc_probe : cnt = 0
[ 1260.095161] myuvc_probe : cnt = 1
[ 1260.269276] myuvc_try_streaming_params ret = 0
[ 1260.271368] myuvc_get_streaming_params ret = 0
[ 1260.273363] myuvc_set_streaming_params ret = 0
[ 1260.273365] video params:
[ 1260.273366] bmHint = 1
[ 1260.273366] bFormatIndex = 1 //第一个格式
[ 1260.273367] bFrameIndex = 2 //第二个分辨率
[ 1260.273368] dwFrameInterval = 333333
[ 1260.273368] wKeyFrameRate = 0
[ 1260.273369] wPFrameRate = 0
[ 1260.273370] wCompQuality = 0
[ 1260.273370] wCompWindowSize = 0
[ 1260.273371] wDelay = 0
[ 1260.273372] dwMaxVideoFrameSize = 77312
[ 1260.273372] dwMaxPayloadTransferSize = 800
[ 1260.273373] dwClockFrequency = 0
[ 1260.273374] bmFramingInfo = 0
[ 1260.273374] bPreferedVersion = 0
[ 1260.273375] bMinVersion = 0
[ 1260.273376] bMinVersion = 0