V4L接口

v4l(VideoforLinux标准)
v4l是linux中提供的一个音视频接口规范,所有的音视频设备的驱动编写要用的这些接口
Video4Linux
其中用到的数据结构有:
 2 -28,I was sitting just by them.
nothing romantic.what on hell happened? 
◆ video_capability 包含 摄像头基本信息
                       设备名称                               n a m e [ 3 2 ]   
                      最大最小分辨率信                    m a x w i d t h
                      号源信息                                channels  /type
◆ video_picture 包含设备采集 图象的各种属性
                        brightness(亮度)、
                        hue     (色调)、
                        contrast(对比度)、
                        whiteness(色度)、
                        depth(深度)
◆ video_mmap 用于 内存映射
◆ video_mbuf 利用mmap 进行映射的 帧信息
 
v4l-----资料之与usb相关
Linux核心中,视频部分的标准是VideoforLinux(简称V4L)
标准定义了一套 接口
内核、驱动、应用程序以这个接口为标准进行交流
USB摄像头的 驱动应当与内核提供的 视频驱动 挂钩
 
  驱动核心之间的通信过程:           声明-----------------指定-----------------调用---------------传递
 
声明video_device结构&& 指定  文件操作   函数指针数组
(应用程序 发出  文件操作  的命令时)
核心  根据   指针  调用  相应 函数
将该结构作为参数传递给应用程序
 
扩大URB的缓冲/建立两个URB( usb request block,简称urb)
                                         ( usb总线就像一条高速公路,数据可以看成是系统与设备交互的货物,而urb就可以看成是交通工具)
                                          (endpoint4种不同类型,于是能在这条高速公路上流动的 数据也就有四种,但对车是没有要求的。)
                                          ( struct urb的具体内容:要运什么,目的地是什么)
 
{
USB的基本特性:
每一个设备(device)会有一个或者多个的逻辑连接点在里面,每个连接点叫 endpoint.每个endpoint有四种数据传送方式: 控制(Control)方式传送; 同步(isochronous)方式传送; 中断(interrupt)方式传送; 大量(bulk)传送.但是所有的endpoint都被用来传送配置和控制信息。在host和endpoint设备的之间的连接叫作管道“pipe”。
}
 
 
系统中/驱动中
  核态、户态
在需要处理大批量数据的 图像处理过程中,要用 内存映射而不是拷贝的方式,实现系统调用。
 
首先使用vmalloc() 申请足够大的 核态内存,将其作为图像数据缓冲空间,两个URB带回的图像数据在这里暂存;
然后使用remap_page_range()函数将其逐页 映射到用户空间中。
户态的图像处理程序使用mmap()函数,直接 读写 核态图像缓冲内存,大大减少额外开销。
 
这就是linux中usb相关的那个结构体
keep away from wine.
Linux的内核是用c来编写的。用结构化的思想分析问题。
 usb_skeleton是USB的骨架。结构体名称是USB_SKEL.
 
struct usb_skel {
     struct usb_device *    udev;              /* the usb device for this device */
     struct usb_interface * interface;         /* the interface for this device */
     struct semaphore   limit_sem;         /* limiting the number of writes in progress */
     unsigned char *        bulk_in_buffer;        /* the buffer to receive data */
     size_t             bulk_in_size;      /* the size of the receive buffer */
     __u8          bulk_in_endpointAddr;  /* the address of the bulk in endpoint */
     __u8          bulk_out_endpointAddr; /* the address of the bulk out endpoint */
     struct kref        kref;
};
据说,USB的驱动分为两块,bus驱动 和 设备驱动
设备----配置(configuration)----接口(interface)----端点(endpoint)
通过端点进行数据交换,主机与端点之间建立起单向管道交换数据。
 
对于那篇文章的笔记
Linux内核用C语言编写,所以基本从面向对象和结构化的角度来实现。
定义的结构体 包含了驱动程序所有资源,即属性和成员。
我们所关心的 usb驱动或者规范是linux内核中的一部分,包括两个部分:一部分由Linux内核来实现,指的是当USB设备连接后,usb_core监测到设备的信息并确定调用什么驱动处理该设备。另一部分由我们实现,usb设备驱动,指的是当usb_core调用到我们写的驱动时,驱动开始工作。
这篇文章分成三个部分来叙述,1)usb的协议规范细节2)驱动框架3)源代码分析
 
2)驱动框架:
usb的设备驱动会被编译成模块,需要时被挂载到内核。
一个linux模块的例子:
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("GPL")                                                    //向linux内核告知该模块的 版权信息
static int hello_init(void)                                        // 初始化函数本身
{
printk(KERN_ALERT "hello world./n");
return 0;
static int hello_exit(void)                                        // 退出函数本身
{//never feel it this way.maybe ever have,but that's long ago.
printk(KERN_ALERT "GOODBYE/n");
module_init(hello_init);                                    //向内核 注册模块的初始化函数
module_exit(hello_exit);                                  //向内核 注册模块的退出函数
这个简单的例子说明了模块的写法。
要编译一个模块,需要用到内核源码树中的makefile
Makefile是用来进行项目配置和管理的。我们要把Linux编译、链接最后生成可执行的内核映像,Makefile文件是必不可少的。
一般的内核开发者只需要知道 如何使用 配置系统(除非是配置系统的维护者)无须了解配置系统的原理,只需要知道如何编写 Makefile 和配置文件。
 
1)USB的协议规范细节
从面向对象(OO)的角度,我们注意封装、继承等概念,同时要注重c语言中的结构化思想。
usb_skeleton
struct  usb_skel{
          struct  usb_device* udev;       
          struct  usb_interface* interface;
          struct semaphore limit_sem;
          unsigned char*  bulk_in_buffer;
          size_t    bulk_in_size;
          _u8      bulk_in_endpointAddr;
          _u8      bulk_out_endpointAddr;
          struct kref     kref;    
}
这个结构体描述的是该驱动所拥有的资源及状态。
结构体udev用来描述usb设备,semaphore limit_sem用于访问控制,kref是一个内核使用的引用计数器。
据前面所述,usb设备有若干配置(configuration),每个配置又有多个接口(interface),接口本身可以没有端点或者有不止一个端点(endpoint)。
linux用结构体 usb_host_endpoint来描述USB端点(endpoint)
 
3)源码分析
static int_init usb_skel_init(void)                                //初始化函数
{
   int result;
   result=usb_register(&skel_driver)
   if(result)
   err("usb_register failed.Error number %d",result);
   return result;
}
static void_exit usb_skel_exit(void)                            //退出函数
{
   usb_deregister(&skel_driver);
}
module_init(usb_skel_init);                         //模块向内核注册初始化函数
module_exit(usb_skel_exit);                       //模块向内核注册退出函数
MODULE_LICENSE("GPL");                          //版权信息
在这段程序中,有两三处关键字:usb_register(struct *usb_driver),usb_deregister(struct *usb_driver),skel_driver;
其中,skel_driver是结构体usb_driver的一个实现。
前面提到的两个函数是用来注册和注销驱动程序
而结构体的作用是向系统提供函数入口、驱动的名字。
这个结构体是:
static struct  usb_driver skel_driver={
.name="skeleton",
.probe=skel_probe,
.disconnect=skel_disconnect,
.id_table=skel_table,
};
------id_table 用来告诉内核  该模块支持的设备
#define USB_SKEL_VENDOR_ID oxfff0
#define USB_SKEL_PRODUCT_ID oxfff0
static struct usb_device_id  skel_table[]={
{USB_DEVICE(USB_SKEL_VENDOR_ID,USB_SKEL_PRODUCT_ID)},
{}                                                                                               //设备表的最后一个元素
};
MODULE_DEVICE_TABLE{usb,skel_table};
 
其中,最后一个函数的两个参数分别是:设备类型和设备表,而且设备表的最后一个元素是空的,用于表示结束。
------probe 是usb子系统自动调用的一个函数,当有usb设备接到硬件集线器时。
有待补充。
得到usb_device之后,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值