diff --git a/IMX6ULL/doc_pic/13_V4L2/02_V4L2驱动程序框架.md b/IMX6ULL/doc_pic/13_V4L2/02_V4L2驱动程序框架.md new file mode 100644 index 0000000..cf2c0ed --- /dev/null +++ b/IMX6ULL/doc_pic/13_V4L2/02_V4L2驱动程序框架.md @@ -0,0 +1,111 @@ +# V4L2驱动程序框架 # + +参考资料: + +* 深入理解linux内核v4l2框架之videobuf2:https://blog.csdn.net/yyjsword/article/details/9243717 + +## 1. 整体框架 + +* 字符设备驱动程序的核心是:file_operations结构体 +* V4L2设备驱动程序的核心是:video_device结构体,它里面有2大成员 + * v4l2_file_operations结构体:实现具体的open/read/write/ioctl/mmap操作 + * v4l2_ioctl_ops结构体:v4l2_file_operations结构体一般使用video_ioctl2函数,它要调用v4l2_ioctl_ops结构体 + +![image-20230802131727705](pic/21_v4l2_framework.png) + +### 1.1 V4L2驱动程序注册流程 + +参考`drivers\media\usb\airspy\airspy.c`: + +```shell +static struct video_device airspy_template = { + .name = "AirSpy SDR", + .release = video_device_release_empty, + .fops = &airspy_fops, + .ioctl_ops = &airspy_ioctl_ops, +}; + +// 分配/设置video_device结构体 +s->vdev = airspy_template; + +// 初始化一个v4l2_device结构体(起辅助作用) +/* Register the v4l2_device structure */ +s->v4l2_dev.release = airspy_video_release; +ret = v4l2_device_register(&intf->dev, &s->v4l2_dev); + +// video_device和4l2_device建立联系 +s->vdev.v4l2_dev = &s->v4l2_dev; + +// 注册video_device结构体 +ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1); + __video_register_device + // 根据次设备号把video_device结构体放入数组 + video_device[vdev->minor] = vdev; + + // 注册字符设备驱动程序 + vdev->cdev->ops = &v4l2_fops; + vdev->cdev->owner = owner; + ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); + +``` + + + +### 1.2 ioctl调用流程分析 + +#### 1.2.1 两类ioctl + +底层驱动程序提供了很多ioctl的处理函数,比如: + +![image-20230802171650240](pic/23_std_ioctls.png) + + + +这些ioctl被分为2类: + +* INFO_FL_STD:标准的,无需特殊的代码来处理,APP的调用可以直达这些处理函数 +* INFO_FL_FUNC:这类ioctl需要特殊处理,比如对于`VIDIOC_ENUM_FMT`,它需要根据设备的类型分别枚举: + ![image-20230802182129884](pic/26_func_ioctl_example.png) + + + +简单地说,这2类ioctl的差别在于: + +* INFO_FL_STD:APP发出的ioctl直接调用底层的video_device->ioctl_ops->xxxx(....) +* INFO_FL_FUNC:APP发出的ioctl,交给`drivers\media\v4l2-core\v4l2-ioctl.c`,它先进行一些特殊处理后,再调用底层的video_device->ioctl_ops->xxxx(....) + + + +怎么区分这些ioctl呢?`drivers\media\v4l2-core\v4l2-ioctl.c`中有个数组: + +![image-20230802182925664](pic/27_v4l2_ioctls.png) + +这个数组里,每一项都表示一个ioctl: + +* 使用`IOCTL_INFO_FNC`定义的数组项,表示它是`INFO_FL_FUNC`类型的 + ![image-20230802183344592](pic/24_ioctl_func.png) +* 使用`IOCTL_INFO_STD`定义的数组项,表示它是`INFO_FL_STD`类型的 + ![image-20230802183251984](pic/25_v4l2_ioctls_offset.png) + + + +#### 1.2.2 调用流程 + +APP调用摄像头的ioctl,流程为: + +![image-20230802170836061](pic/22_ioctl_detail.png) + + + +### 1.3 buffer的内核实现 + +APP操作buffer的示意图如下: + +![image-20230617171816630](pic/05_buffers.png) + +驱动程序中如何管理这些buffer呢? + + + +## 2. 从0编写一个虚拟的摄像头驱动 + diff --git a/IMX6ULL/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif b/IMX6ULL/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif new file mode 100644 index 0000000..ce29353 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif differ diff --git a/IMX6ULL/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif b/IMX6ULL/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif new file mode 100644 index 0000000..ef6b9d2 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/21_v4l2_framework.png b/IMX6ULL/doc_pic/13_V4L2/pic/21_v4l2_framework.png new file mode 100644 index 0000000..8edff5c Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/21_v4l2_framework.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/22_ioctl_detail.png b/IMX6ULL/doc_pic/13_V4L2/pic/22_ioctl_detail.png new file mode 100644 index 0000000..2c2ced4 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/22_ioctl_detail.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/23_std_ioctls.png b/IMX6ULL/doc_pic/13_V4L2/pic/23_std_ioctls.png new file mode 100644 index 0000000..fd94742 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/23_std_ioctls.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/24_ioctl_func.png b/IMX6ULL/doc_pic/13_V4L2/pic/24_ioctl_func.png new file mode 100644 index 0000000..bcde028 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/24_ioctl_func.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png b/IMX6ULL/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png new file mode 100644 index 0000000..defa744 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/26_func_ioctl_example.png b/IMX6ULL/doc_pic/13_V4L2/pic/26_func_ioctl_example.png new file mode 100644 index 0000000..85e3695 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/26_func_ioctl_example.png differ diff --git a/IMX6ULL/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png b/IMX6ULL/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png new file mode 100644 index 0000000..387b718 Binary files /dev/null and b/IMX6ULL/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png differ diff --git a/README.md b/README.md index 197c270..39d98cc 100644 --- a/README.md +++ b/README.md @@ -771,24 +771,31 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git * 2023.06.18 发布"摄像头驱动" ```shell - 01_V4L2应用程序开发_数据采集流程 + [01-1]_V4L2应用程序开发_数据采集流程 ``` -* 2023.06.18 发布"摄像头驱动" +* 2023.07.18 发布"摄像头驱动" ```shell - 02_V4L2应用程序开发_控制流程 + [01-2]_V4L2应用程序开发_控制流程 ``` -* 2023.06.18 发布"摄像头驱动" +* 2023.07.18 发布"摄像头驱动" ```shell - 03_V4L2应用程序开发_列出帧细节 - 04_V4L2应用程序开发_获取数据 -05_V4L2应用程序开发_调试 - 06_V4L2应用程序开发_控制亮度 + [01-3]_V4L2应用程序开发_列出帧细节 + [01-4]_V4L2应用程序开发_获取数据 +[01-5]_V4L2应用程序开发_调试 + [01-6]_V4L2应用程序开发_控制亮度 ``` +* 2023.08.03 发布"摄像头驱动" + + ```shell + [02-1]_驱动总体框架 + [02-2]_ioctl调用流程分析 + ``` + diff --git a/STM32MP157/doc_pic/13_V4L2/02_V4L2驱动程序框架.md b/STM32MP157/doc_pic/13_V4L2/02_V4L2驱动程序框架.md new file mode 100644 index 0000000..cf2c0ed --- /dev/null +++ b/STM32MP157/doc_pic/13_V4L2/02_V4L2驱动程序框架.md @@ -0,0 +1,111 @@ +# V4L2驱动程序框架 # + +参考资料: + +* 深入理解linux内核v4l2框架之videobuf2:https://blog.csdn.net/yyjsword/article/details/9243717 + +## 1. 整体框架 + +* 字符设备驱动程序的核心是:file_operations结构体 +* V4L2设备驱动程序的核心是:video_device结构体,它里面有2大成员 + * v4l2_file_operations结构体:实现具体的open/read/write/ioctl/mmap操作 + * v4l2_ioctl_ops结构体:v4l2_file_operations结构体一般使用video_ioctl2函数,它要调用v4l2_ioctl_ops结构体 + +![image-20230802131727705](pic/21_v4l2_framework.png) + +### 1.1 V4L2驱动程序注册流程 + +参考`drivers\media\usb\airspy\airspy.c`: + +```shell +static struct video_device airspy_template = { + .name = "AirSpy SDR", + .release = video_device_release_empty, + .fops = &airspy_fops, + .ioctl_ops = &airspy_ioctl_ops, +}; + +// 分配/设置video_device结构体 +s->vdev = airspy_template; + +// 初始化一个v4l2_device结构体(起辅助作用) +/* Register the v4l2_device structure */ +s->v4l2_dev.release = airspy_video_release; +ret = v4l2_device_register(&intf->dev, &s->v4l2_dev); + +// video_device和4l2_device建立联系 +s->vdev.v4l2_dev = &s->v4l2_dev; + +// 注册video_device结构体 +ret = video_register_device(&s->vdev, VFL_TYPE_SDR, -1); + __video_register_device + // 根据次设备号把video_device结构体放入数组 + video_device[vdev->minor] = vdev; + + // 注册字符设备驱动程序 + vdev->cdev->ops = &v4l2_fops; + vdev->cdev->owner = owner; + ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); + +``` + + + +### 1.2 ioctl调用流程分析 + +#### 1.2.1 两类ioctl + +底层驱动程序提供了很多ioctl的处理函数,比如: + +![image-20230802171650240](pic/23_std_ioctls.png) + + + +这些ioctl被分为2类: + +* INFO_FL_STD:标准的,无需特殊的代码来处理,APP的调用可以直达这些处理函数 +* INFO_FL_FUNC:这类ioctl需要特殊处理,比如对于`VIDIOC_ENUM_FMT`,它需要根据设备的类型分别枚举: + ![image-20230802182129884](pic/26_func_ioctl_example.png) + + + +简单地说,这2类ioctl的差别在于: + +* INFO_FL_STD:APP发出的ioctl直接调用底层的video_device->ioctl_ops->xxxx(....) +* INFO_FL_FUNC:APP发出的ioctl,交给`drivers\media\v4l2-core\v4l2-ioctl.c`,它先进行一些特殊处理后,再调用底层的video_device->ioctl_ops->xxxx(....) + + + +怎么区分这些ioctl呢?`drivers\media\v4l2-core\v4l2-ioctl.c`中有个数组: + +![image-20230802182925664](pic/27_v4l2_ioctls.png) + +这个数组里,每一项都表示一个ioctl: + +* 使用`IOCTL_INFO_FNC`定义的数组项,表示它是`INFO_FL_FUNC`类型的 + ![image-20230802183344592](pic/24_ioctl_func.png) +* 使用`IOCTL_INFO_STD`定义的数组项,表示它是`INFO_FL_STD`类型的 + ![image-20230802183251984](pic/25_v4l2_ioctls_offset.png) + + + +#### 1.2.2 调用流程 + +APP调用摄像头的ioctl,流程为: + +![image-20230802170836061](pic/22_ioctl_detail.png) + + + +### 1.3 buffer的内核实现 + +APP操作buffer的示意图如下: + +![image-20230617171816630](pic/05_buffers.png) + +驱动程序中如何管理这些buffer呢? + + + +## 2. 从0编写一个虚拟的摄像头驱动 + diff --git a/STM32MP157/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif b/STM32MP157/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif new file mode 100644 index 0000000..ce29353 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/2-1_V4L2驱动整体框架.tif differ diff --git a/STM32MP157/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif b/STM32MP157/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif new file mode 100644 index 0000000..ef6b9d2 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/2-2_ioctl调用流程分析.tif differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/21_v4l2_framework.png b/STM32MP157/doc_pic/13_V4L2/pic/21_v4l2_framework.png new file mode 100644 index 0000000..8edff5c Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/21_v4l2_framework.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/22_ioctl_detail.png b/STM32MP157/doc_pic/13_V4L2/pic/22_ioctl_detail.png new file mode 100644 index 0000000..2c2ced4 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/22_ioctl_detail.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/23_std_ioctls.png b/STM32MP157/doc_pic/13_V4L2/pic/23_std_ioctls.png new file mode 100644 index 0000000..fd94742 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/23_std_ioctls.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/24_ioctl_func.png b/STM32MP157/doc_pic/13_V4L2/pic/24_ioctl_func.png new file mode 100644 index 0000000..bcde028 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/24_ioctl_func.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png b/STM32MP157/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png new file mode 100644 index 0000000..defa744 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/25_v4l2_ioctls_offset.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/26_func_ioctl_example.png b/STM32MP157/doc_pic/13_V4L2/pic/26_func_ioctl_example.png new file mode 100644 index 0000000..85e3695 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/26_func_ioctl_example.png differ diff --git a/STM32MP157/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png b/STM32MP157/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png new file mode 100644 index 0000000..387b718 Binary files /dev/null and b/STM32MP157/doc_pic/13_V4L2/pic/27_v4l2_ioctls.png differ