前面两篇说的有点多了,不过多了解点东西也挺好的,遇到问题时可以有更多的思路,真正驱动是从这一块开始。一般BSP的camera都是完好的,我们只用关心驱动这些就可以了。
1. V4L2
1)简介
在Linux中,摄像头方面的标准化程度比较高,这个标准就是V4L2驱动程序,这也是业界比较公认的方式。
V4L全称是Video for Linux,是Linux内核中标准的关于视频驱动程序,目前使用比较多的版本是Video for Linux 2,简称V4L2。它为Linux下的视频驱动提供了统一的接口,使得应用程序可以使用统一的API操作不同的视频设备。从内核空间到用户空间,主要的数据流和控制类均由V4L2驱动程序的框架来定义。
V4L2驱动程序一般只提供Video数据的获得,而如何实现视频预览,如何向上层发送数据,如何把纯视频流和取景器、视频录制等实际业务组织起来,都是camera的硬件抽象层需要负责的工作。
V4L2驱动核心实现为如下文件:drivers/media/video/v4l2-dev.c。
V4l2-dev.h中定义的video_device是V4L2驱动程序的核心数据结构,它为具体的摄像头sensor驱动提供了接口调用。
V4l2的采集过程(应用程序):
1) 打开设备,获得文件描述符;
2) 设置图片格式;
3) 分配缓冲区;
4) 启动采集过程,读取数据;
5) 停止采集,关闭设备。
2)数据结构
V4L2的主要数据结构是video_device,定义在v4l2_dev.h中:
- struct video_device
- {
- /* device ops */
- const struct v4l2_file_operations *fops; /*接口函数指针*/
- /* sysfs */
- struct device dev; /* v4l 设备结构 */
- struct cdev *cdev; /* 字符设备结构*/
- /* Set either parent or v4l2_dev if your driver uses v4l2_device */
- struct device *parent; /* 设备父指针 */
- struct v4l2_device *v4l2_dev; /* v4l2设备指针*/
- /* device info */
- char name[32]; /*设备名称*/
- int vfl_type;
- /* 'minor' is set to -1 if the registration failed */
- int minor; /*次设备号*/
- u16 num;
- /* use bitops to set/clear/test flags */
- unsigned long flags;
- /* attribute to differentiate multiple indices on one physical device */
- int index;
- /* V4L2 file handles */
- spinlock_t fh_lock; /* Lock for all v4l2_fhs */
- struct list_head fh_list; /* List of struct v4l2_fh */
- int debug; /* debug 级别*/
- /* Video 标准变量 */
- v4l2_std_id tvnorms; /* Supported tv norms */
- v4l2_std_id current_norm; /* Current tvnorm */
- /* 回调函数 */
- void (*release)(struct video_device *vdev);
- /* ioctl 回调函数 */
- const struct v4l2_ioctl_ops *ioctl_ops;
- };
struct video_device
{
/* device ops */
const struct v4l2_file_operations *fops; /*接口函数指针*/
/* sysfs */
struct device dev; /* v4l 设备结构 */
struct cdev *cdev; /* 字符设备结构*/
/* Set either parent or v4l2_dev if your driver uses v4l2_device */
struct device *parent; /* 设备父指针 */
struct v4l2_device *v4l2_dev; /* v4l2设备指针*/
/* device info */
char name[32]; /*设备名称*/
int vfl_type;
/* 'minor' is set to -1 if the registration failed */
int minor; /*次设备号*/
u16 num;
/* use bitops to set/clear/test flags */
unsigned long flags;
/* attribute to differentiate multiple indices on one physical device */
int index;
/* V4L2 file