1、vivi.c分析html
一、vivi.c是Linux中虛擬的v4l2驅動,使用它來學習v4l2驅動架構linux
1.vivi驅動涉及文件:緩存
vivi.c 驅動的具體實現架構
v4l2-common.capp
V4L2-dev.c video_register_device(struct video_device *vdev...);框架
V4L2-device.c v4l2_device_register(struct device *dev,struct v4l2_device *v4l2_device);ide
videobuf_core.c函數
videobuf_vmalloc.c學習
2.主要關注如下幾個結構體:spa
struct video_device 視頻類設備的基類,另外字符設備驅動的基類爲cdev,全部的操做都是圍繞cdev結構體
struct v4l2_file_operations 包含vivi_read,vivi_open等函數具體實現。在系統調用的時候,會首先調用cdev的file_operations的v4l2_read,v4l2_open等函數,在這些函數中會使用struct file中的video_device來調用vivi_read等函數具體去實現。
struct v4l2_ioctl_ops ioctl操做的函數的具體實現
struct V4l2_device
struct videobuf_buffer 視頻數據緩衝區,對應一幀視頻,裏面包含視頻的大小等信息
struct videobuf_queue 視頻緩衝區隊列
以上幾個結構體可能不會被單獨使用,通常都被包含在某個更大的對象結構中,好比video_device和v4l2_device都包含在vivi_dev中,而vivi_dev被包含在viv_fh中,videobuf_buffer被包含在vivi_buffer中。
這個struct file_opertions v4l2_fops是字符設備給上層提供的系統調用,這裏的函數最終調用的仍是struct v4l2_file_operations (vivi_fops)的實現,能夠查看v4l2_open的實現。videobuf_queue_ops中實現了緩衝隊列的一些操做,buffer_setup,buffer_prepare,buffer_queue,buffer_release等,可是這些申請的緩衝隊列都是在內核空間,在vivi_mmap函數中videobuf_mmap_mapper(struct videobuf_queue *q,struct vm_area_struct *vma);將緩衝隊列映射到vm_area_struct虛擬地址
3.分析程序流程:
在vivi.c文件中
vivi_create_instance()
v4l2_device_register()
給video_device vdev對象賦值v4l2_file_operations和v4l2_ioctl_ops等
video_device_register()
初始化video_device對象vdev
初始化video_device中的cdev結構體
cdev_add()註冊字符設備
初始化video_device中struct device結構體
device_register()在/dev/目錄下建立設備節點
v4l2_dev.c文件裏file_operations中的v4l2_ioctl最終調用的仍是vivi.c文件裏v4l2_file_operations中的video_ioctl2函數,可是這裏的video_ioctl2不像vivi_open,vivi_read等是具體的實現,video_ioctl2具體的實現已經單獨拿出來放到v4l2_ioctl.c文件中了,因此video_ioctl2最終調用的是v4l2_ioctl.c文件中的__video_do_ioctl(file,cmd,arg)函數,而__video_do_ioctl(file,cmd,arg)函數又回過來調用vivi_ioctl中vivi_ioctl_ops中的函數。
2、V4L2架構分析
v4l2向上爲應用程序提供了統一的調用接口,向下爲設備驅動程序提供了統一的V4L2框架;Linux中V4L2驅動的視頻設備(如攝像頭、視頻採集卡)的設備文件爲/dev/videoX,主設備號81,對於視頻設備次設備號爲0-63(是字符設備),Radio設備爲64-127,Teltext設備爲192-223,VBI設備是224-255,V4L2驅動的視頻設備在用戶空間經過ioctl()控制,還能夠進行mmap()映射。
要想了解 V4l2 有幾個重要的文檔是必需要讀的:
1、源碼Documentation/video4linux目錄下的V4L2-framework.txt和videobuf
2、V4L2的官方API文檔V4L2 API Specification
3、源碼drivers/media/video目錄下的sample程序vivi.c(虛擬視頻驅動程序,此代碼模擬一個真正的視頻設備V4L2 API)。
V4l2能夠支持多種設備,它能夠有如下幾種接口:
1. 視頻採集接口(video capture interface):這種應用的設備能夠是高頻頭或者攝像頭.V4L2的最初設計就是應用於這種功能的.
2. 視頻輸出接口(video output interface):能夠驅動計算機的外圍視頻圖像設備--像能夠輸出電視信號格式的設備.
3. 直接傳輸視頻接口(video overlay interface):它的主要工做是把從視頻採集設備採集過來的信號直接輸出到輸出設備之上,而不用通過系統的CPU.
4. 視頻間隔消隱信號接口(VBI interface):它可使應用能夠訪問傳輸消隱期的視頻信號.
5. 收音機接口(radio interface):可用來處理從AM或FM高頻頭設備接收來的音頻流.
V4L2 驅動核心
V4L2 的驅動源碼在drivers/media/video目錄下,主要核心代碼有:
v4l2-dev.c //linux版本2視頻捕捉接口,主要結構體 video_device 的註冊 v4l2-common.c //在Linux操做系統體系採用低級別的操做一套設備structures/vectors的通用視頻設備接口。 //此文件將替換videodev.c的文件配備常規的內核分配。 v4l2-device.c //V4L2的設備支持。註冊v4l2_device v4l22-ioctl.c //處理V4L2的ioctl命令的一個通用的框架。 v4l2-subdev.c //v4l2子設備 v4l2-mem2mem.c //內存到內存爲Linux和videobuf視頻設備的框架。設備的輔助函數,使用其源和目的地videobuf緩衝區。 頭文件linux/videodev2.h、media/v4l2-common.h、media/v4l2-device.h、media/v4l2-ioctl.h、media/v4l2-dev.h、media/v4l2-ioctl.h等。
來源:http://zjbintsystem.blog.51cto.com/964211/464729 http://www.rosoo.net/a/201001/8382.html (此兩者相似)
open(CAPTURE_DEVICE, O_RDWR | O_NONBLOCK, 0))關於阻塞模式和非阻塞模式,應用程序可以使用阻塞模式或非阻塞模式打開視頻設備,若是使用非阻塞模式調用視頻設備,即便還沒有捕獲到信息,驅動依舊會把緩存(DQBUFF)裏的東西返回給應用程序。
參考:http://blog.csdn.net/luckywang1103/article/details/17406029
關於如何建立設備節點的:用戶空間的udev會根據device_create建立相應的設備節點;這裏只是簡單說說個人理解class_create與class_register功能上相似,只是class_register須要分配struct class對象內存並初始化。自動建立設備節點class_create與device_create或者class_register,device_register,用戶空間的udev會根據device_create建立相應的設備節點
linux中class_create和class_register說明:http://www.cnblogs.com/skywang12345/archive/2013/05/15/driver_class.html (未看)
v4l2驅動架構解析與開發引導: http://www.360doc.com/content/13/1010/16/7775902_320343471.shtml