基于V4L2框架的linux驱动程序编写

6467T Vpif的V4L2 linux驱动程序框架

linux中,使用V4L2框架来管理视频采集设备。V4L2框架主要包括两层:V4L2DeviceV4L2 Subdevice,其中V4L2 Device是虚拟的设备,用以管理V4L2 Subdevice,而Subdevice才是真正的物理设备,例如各种视频AD芯片和sensor等。

基于V4L2框架的linux驱动程序编写_第1张图片

从上图可以看出,对于imagesensor的驱动程序编写有两种方式,一种是直接将imagesensor作为video_device,另一种是将其作为subdevice供上一层调用。考虑到如果将imagesensor直接作为video_device来编写驱动程序的话,那需要自己处理一些内存管理的问题,这比较复杂,所以我们采用第二种方法。


编写image sensor驱动程序

由于Linux中已经有了用于视频设备驱动程序的V4L2框架,在编写sensor驱动程序时,主要功能就是对其进行初始化以及编写一些API函数。

首先,作为V4L2 subdevice,在sensor的驱动程序中的以下函数是必须实现的。

函数名

功能

__init int e2v570_mod_init()

模块初始化

__exit void e2v570_mod_exit()

模块退出时清理内存

e2v570_probe()

注册时对设备进行探测

e2v570_remove()

移除设备时运行

 

然后,由于vpif要调用sensor驱动程序,这过程中又会使用到另外一些函数,主要包括以下部分。

函数名

功能

e2v570_querystd()

查询sensor支持的视频格式

e2v570_s_stream()

使能/关闭sensor输出

e2v570_cropcap()

获取视频的裁剪功能

e2v570_s_std()

设置sensor输出的视频格式

 

另外,由于e2v570是使用SPI总线访问其寄存器,所以还需要编写寄存器访问函数,主要包括以下部分。

函数名

功能

reg_read()

e2v570寄存器

reg_write()

e2v570寄存器

e2v570_write_array()

e2v570写一系列寄存器

reg_write16()

16位寄存器

 

编写完所有基本API函数之后,使用以下代码将这些API函数传递给一些结构体,然后就可以实现内核的统一管理所有驱动程序。


// v4l2 子设备的视频操作函数
static const struct v4l2_subdev_video_ops e2v570_subdev_video_ops = {
         .querystd = e2v570_querystd,
         .s_stream = e2v570_s_stream,
         .cropcap  = e2v570_cropcap,
};
// v4l2子设备的核心操作函数
static const struct v4l2_subdev_core_ops e2v570_subdev_core_ops = {
         .s_std        = e2v570_s_std,
         .g_chip_ident = e2v570_g_chip_ident,
};
// v4l2子设备的所有API
static const struct v4l2_subdev_ops e2v570_subdev_ops = {
         .core         = & e2v570_subdev_core_ops,
         .video        = & e2v570_subdev_video_ops,
};
 
// 用于spi驱动程序的结构体,定义e2v570的spi设备ID,并添加到spi设备表
static const struct spi_device_id e2v570_id[] = {
         { " e2v570", 0 },
         { }
};
MODULE_DEVICE_TABLE(spi, e2v570_id);
//spi设备的驱动程序函数
static struct spi_driver e2v570_ spi _driver = {
         .driver = {
                   .owner = THIS_MODULE,
                   .name = " e2v570",
         },
         .probe                = e2v570_probe,
         .remove            = e2v570_remove,
         .id_table  = e2v570_id,
};
// 定义模块初始化和退出时运行的函数
module_init(e2v570_mod_init);
module_exit(e2v570_mod_exit);

系统上电时,内核在内存中解压并运行,这时首先会调用 e2v570 驱动程序中的初始化函数 e2v570_mod_init() ,添加 spi 设备及 spi 设备驱动程序,然后 VPIF 驱动程序初始化时会调用 e2v570 驱动程序中的 e2v570_probe() 函数,对 e2v570 进行一系列的初始化,并且注册为 V4L2 子设备。

你可能感兴趣的:(基于V4L2框架的linux驱动程序编写)