在分析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