在分析v4l2(video for linux 2.0)框架之前,我们需先了解驱动程序分层的概念。
所谓分层,其实是利用了面向对象的思想---继承,我们知道,子类继承父类,并且对于父类提供的资源,合则用,不合则改(重载)。对于某一类驱动程序,内核把这一类驱动相同的部分提取出来单独作为一层,这一层称为核心层,它向应用层提供这一类驱动程序的统一接口。而这一类驱动的不同实例需要我们单独编写代码,这一层我们称为硬件相关层。硬件相关层处于核心层下面,继承核心层的代码,同时突出自己的差异,我们的主要工作也在于编写特定硬件相关的代码。
(1)v4l2框架分析(虚拟摄像头驱动例子: vivi.c )
static int __init vivi_init(void)
vivi_create_instance();
v4l2_device_register(); // 主要完成一些初始化工作
video_device_alloc(); //分配一个video_device结构体
设置video_device结构体代码
video_register_device();
video_register_device_index();
cdev_alloc();
设置 vdev->cdev->ops = &v4l2_fops;
cdev_add();
(2)v4l2框架大致为:
应用层: open read write
-------------------------------------------------------------------------------------------------------------
核心层: v4l2_open v4l2_read v4l2_write (向上提供统一接口) v4l2-dev.c文件
--------------------------------------------------------------------------------------------------------------
硬件相关层(以虚拟摄像头驱动为例 vivi.c):
vivi.open vivi.read vivi.write
(3)函数调用过程:
1. open
app: open("/dev/video0",....)
-------------------------------------------------------------------------------------------------------
drv: v4l2_fops.v4l2_open
vdev = video_devdata(filp); // 根据次设备号从数组中得到video_device
ret = vdev->fops->open(filp);
vivi_ioctl_ops.open
v4l2_fh_open
2.read
app: read()
---------------------------------------------
drv: v4l2_read ()
video_device->fops->read();
videobuf_read_stream();
(4)驱动程序编写步骤:
1.分配video_device
2.设置
3.注册:video_register_device