V4L2框架

怎么写字符设备驱动?

  1. 构造file_operations:
    .open = drv_open
    .read = drv_read
    .write = drv_write

2.告诉内核:
register_chrdev(主设备号,file_operations, name)
备注:主设备号可以写0,让系统自动分配

有的书不建议使用register_chrdev结构体:因为太老了。可以替换成如下步骤:
step1: 分配cdev step2: 设置cdev step3: cdev_add
3.入口函数.:调用 register_chrdev

4.出口函数:调用 unregister_chrdev


对于复杂的字符设备驱动程序,引用分层概念
eg: LCD
fbmem.c :
1.file_operations open/read/write
2.register_dev
3.入口和出口

只需要设置硬件相关:
1.分配fb_info
2.设置fb_info
3.注册
4.硬件相关的操作


总结:
怎么写分层驱动?
1.分配结构体
2.设置
3.注册
4.硬件相关操作


V4L2框架:

APP: Open read write

核心层: V4l2-dev.c: 1.file_operaions 2.注册 (1.cdev_alloc 2.cdev_ops = v4l2_file_operations 3. cdev_add)

硬件相关
uvc_driver.c ----- v4l2_device_register
----- video_devie_alloc
---- video_register_device : 1. 分配 video_device 2. 设置video_device 3.注册video_register_device

虚拟视频驱动vivi.c分析
1.分配 video_device
2.设置
3.注册:video_register_device

vivi_init:
vivi_crate_instance:
v4l2_device_register //不是主要,只是初始化,比如自旋锁,引用计数
video_device_alloc
//设置
1.vfd
.name = "vivi",
.fops = &vivi_fops,
.ioctl_ops = &vivi_ioctl_ops,
.release = video_device_release,

  1. vfd->v4l2_dev = &dev->v4l2_dev

3.设置ctrl 属性(用于APP的ioctrl)
video_register_device(video_device, type: VFL_TYPE_GRABBER, video_nr)
+++++++++ vdev->cdev = cdev_alloc()
+++++++++++ vdev->cdev->ops = &v4l2_fops;
+++++++++++++ cdev_add
+++++++++++++ video_device[vdev->minor] = vdev;

分析vivi.c的open\read\write\ioctl过程
1.open
app : open("dev/video0",....)


2.dev :
v4l2open
++++++++ 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
+++++++++ struct video_device *vdev = video_devdata(filp);
+++++++++++++++++++++vdev->fops->read(filp, buf, sz, off);

3.ioctrl
app: ioctl
drv : v4l2_fops.unlocked_ioctl
++++++++++++struct video_device *vdev = video_devdata(filp);
+++++++++++++++++video_ioctl2
+++++++++++++++++++++++ video_do_ioctl(file, cmd, parg);
++++++++++++++++++++++++++++ struct video_device *vfd = video_devdata(file);
++++++++++++++++++++++++++++++根据APP传入的cmd来获得、设置某些属性

怎么写v4l2的驱动?
1.分配/设置/注册 v4l2_device : v4l2_device_register, v4l2_device(辅助作用,提供引用计数)
2.分配一个video_device结构体: video_device_alloc
3.设置:a. vfd->v4l2_dev b. vfd : .fops = .... open / read /write 被上层的 v4l2.fops调用 .ioctrl = ...
c.app可以通过ioctrl来设置亮度等信息,驱动程序里谁来接受/存储/设置到硬件?/提供这些信息
属性:v4l2_ctrl
管理:v4l2_ctrl_handle: a. v4l2_ctrl_hander_init b. v4l2_ctrl_new_std v4l2_ctrl_new_custom ....创建v4l2_ctrl,添加到链表 c : 跟vdev关联: v4l2_dev.ctrl_handler = v4l2_ctrl_hander vdeo_dev ->v4l2_dev

打赏作者