攝像頭驅動程序徹底分析-_第1頁
攝像頭驅動程序徹底分析-_第2頁
攝像頭驅動程序徹底分析-_第3頁
攝像頭驅動程序徹底分析-_第4頁
攝像頭驅動程序徹底分析-_第5頁
已閱讀5頁,還剩15頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、前言先前已經分析過V4L2的框架,并且使用了xawtv測試了vivi虛擬驅動程序,對框架的分析并沒有深入結構,比如說ioctl有很多,但是并不清楚哪些是必須的,哪些可以不要。并且也不知道測試程序是如何拿到視頻數據的。本文將介紹如何根據虛擬驅動vivi的使用過程徹底分析攝像頭驅動。第1章vivi測試補充加載vivi.ko驅動之前,先加載videobuf-core.kovideobuf-vmalloc.kov4l2-common.ko這3個模塊,然后就可以加載vivi.ko成功了。然而換了一臺電腦,再執行一遍就不行了,在加載v4l2-common.ko時執行“sudo insmod v4l2-co

2、mmon.ko”打印信息提示如下: Insmod:error inserting v4l2-common.ko:-1 Unknown symbol in module使用dmesg命令查看詳細信息:v4l2_common:Unknown symbol v4l2_device_register_subdevv4l2_common:Unknown symbol v4l2_device_unregister_subdev那么為什么原來的電腦可以正常加載驅動,現在的電腦就不行了呢?1.2 加載vivi.ko失敗原因這是因為先前電腦測試時是先插上的UVC攝像頭測試的,這時電腦會自動加載對應的v4l2相關

3、的驅動ko,這個時候再加載vivi.ko驅動的時候就不缺少相應的symbol。而換了一臺電腦沒有插uvc攝像頭驅動,所以問題就出現了。解決辦法-依次執行下面三步驟:sudo modprobe vivi /安裝ubuntu自帶的驅動程序sudo rmmod vivi /卸載內核自帶的vivi驅動sudo insmod vivi.ko /安裝自己編譯出的vivi.ko1.3 insmod與modprobe第2章分析xawtv源碼2.1 獲取xawtv源碼下載源碼后建立一個sourceinsight工程,當然可以從main開始分析,看看涉及到哪些系統調用。但是這樣會非常復雜,因為xawtv除了調用v

4、ivi驅動程序之外,還有其他很多的工作,如何快捷的知道有哪些調用呢?有一個辦法,使用strace工具可以看出xawtv使用了哪些系統調用。2.2 strace工具使用方法:strace o xxx.log cmdcmd為命令,執行cmd命令時會將涉及到的系統調用(open,read,write都會記錄到到xxx.log中。執行”strace o xawtv.log xawtv”,在當前目錄生成xawtv.log,將該文件拷到PC機上,下面對該文件進行分析。2.3 分析xawtv.log使用UltraEdit打開xawt.log,xawtv不指定設備打開時是默認打開video0,因此上節操作的是

5、video0,因為文件內容比較多,我們需要先得到我們關系的東西,搜索“/dev/video0”,得到如下圖: 可以看出open打開兩次,第一次打開后發現ioctl用不了,因此close,然后打開第2次。可以看出open之后,得到一個文件句柄“4”,后面接了一大堆ioctl。搜索“(4,”,就可以看出涉及到哪些調用了。勾選搜索對話框的“列出包含字符串的行”,搜索如下圖: 復制搜索到的結果,存為新的文件“xawtv涉及的vivi驅動的系統調用.txt”。從xawtv.log可以看出,open之后,涉及到的第一個系統調用是:open("/dev/video0", O_RDWR|O

6、_LARGEFILE = 4ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0x8f0b998 = -1 EINV AL (Invalid argumentclose(4ioctl失敗,然后關閉。我們重點關注第2次open后面的內容,如下: 詳細如下:open("/dev/video0", O_RDWR|O_LARGEFILE = 4ioctl(4, VIDIOC_QUERYCAP or VT_OPENQRY, 0xbf90a2e4 = 0ioctl(4, VIDIOC_G_FMT or VT_SENDSIG, 0xbf90a218 = 0i

7、octl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, 0xc02c

8、564a, 0xbf90a0f8 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0xbf90a18c = -1 EINV AL (Invalid argumentioctl(4, V

9、IDIOC_QUERYCAP or VT_OPENQRY, 0xbf90a124 = 0ioctl(4, VIDIOC_G_INPUT, 0xbf909fcc = 0ioctl(4, VIDIOC_ENUMINPUT, 0xbf909fcc = 0fstat64(4, st_mode=S_IFCHR|0660, st_rdev=makedev(81, 0, . = 0ioctl(4, MA TROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0xbf90a018 = -1 EINV AL (Invalid argumentioctl(4, VIDIOC_QUERY

10、CAP or VT_OPENQRY, 0x8f0b998 = 0fcntl64(4, F_SETFD, FD_CLOEXEC = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bacc = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bb18 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bb64 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bbb0 = 0ioctl(4, VIDIOC_ENUMINPUT, 0x8f0bbfc = -1 EINV AL (Invalid argumentioctl(4

11、, VIDIOC_ENUMSTD, 0x8f0bf8c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0bfcc = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c00c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c04c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c08c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c0cc = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c10c = 0ioctl(4, VIDIOC_ENUMSTD, 0x8f0c14c = -1 E

12、INV AL (Invalid argumentioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c38c = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c3cc = 0ioctl(4, VIDIOC_ENUM_FMT or VT_SETMODE, 0x8f0c40c = 0ioctl(4, VIDIOC_G_PARM, 0x8f0ba00 = 0ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cb8c = 0ioctl(4, MATROX

13、FB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cbd0 = 0ioctl(4, MATROXFB_TVOQUERYCTRL or VIDIOC_QUERYCTRL, 0x8f0cc14 = 0ioctl(4, VIDIOC_G_STD, 0xbf90a3a8 = 0ioctl(4, VIDIOC_G_INPUT, 0xbf90a3bc = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xb

14、f90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3b4 = 0ioctl(4, MATROXFB_G_TVOCTRL or VIDIOC_G_CTRL, 0xbf90a3c4 = 0ioctl(4, VIDIOC_TRY_FMT, 0x8f0dca4 = 0ioctl(4, VIDIOC_S_FMT or VT_RELDISP, 0xbf909cf4 = 0ioctl(4, VIDIOC_TRY_

15、FMT, 0x8f0dca4 = 0ioctl(4, VIDIOC_REQBUFS or VT_DISALLOCA TE, 0x8f0dd80 = 0ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x8f0dd94 = 0ioctl(4, VIDIOC_QUERYBUF or VT_RESIZE, 0x8f0ddd8 = 0ioctl(4, VIDIOC_QBUF, 0x8f0dd94 = 0ioctl(4, VIDIOC_QBUF, 0x8f0ddd8 = 0ioctl(4, VIDIOC_STREAMON, 0xbf909fcc = 0ioctl(4, MA

16、TROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, MATROXFB_S_TVOCTRL or VIDIOC_S_CTRL, 0xbf90a3b0 = 0ioctl(4, VIDIOC_S_INPUT, 0xbf90a424 = 0ioctl(4, VIDIOC_S_STD, 0x8f0bf90

17、 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0ioctl(4, VIDIOC_QBUF, 0x8f0dd94 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0ioctl(4, VIDIOC_QBUF, 0x8f0ddd8 = 0ioctl(4, VIDIOC_DQBUF, 0xbf90a2a0 = 0.由上小節可得系統調用順序:1、open("/dev/video0", O_RDWR|O_LARGEFILE = 4-打開設備2、ioctl(4, VIDIOC_QUERYCAP3、ioctl(4, VIDIO

18、C_G_FMT-獲得攝像頭數據的格式4、for( -從上圖可以看出連續多次調用,從下面分析xawtv源碼也可以看出。ioctl(4, VIDIOC_ENUM_FMT-列舉出攝像頭支持的格式5、ioctl(4, 0xc02c564a, 0xbf90a0f8 = -1 EINV AL (Invalid argument-Invalid先不管6、ioctl(4, VIDIOC_QUERYCAP7、ioctl(4, VIDIOC_G_INPUT-獲得當前使用的輸入源8、ioctl(4, VIDIOC_ENUMINPUT-列舉出輸入源,數據可能有多個通道9、ioctl(4, VIDIOC_QUERYCT

19、RL-查詢屬性,比如亮度,對比度10、ioctl(4, VIDIOC_QUERYCAP11、fcntl64(4, F_SETFD, FD_CLOEXEC-當應用程序關閉,并且不是直接調用close來關閉這個文件的話,系統幫忙來關閉12、for(ioctl(4, VIDIOC_ENUMINPUT-列舉出輸入源,數據可能有多個通道13、for(ioctl(4, VIDIOC_ENUMSTD-列舉標準制式14、for(ioctl(4, VIDIOC_ENUM_FMT-列舉支持的格式15、ioctl(4, VIDIOC_G_PARM-獲取參數16、for(ioctl(4, VIDIOC_QUERYCT

20、RL -查詢屬性,比如亮度,最小值,最大值,默認值17、ioctl(4, VIDIOC_G_STD-獲得當前使用的標準制式,攝像頭所支持的制式是PAL,還是NTSC等18、ioctl(4, VIDIOC_G_INPUT-當前使用的哪一個通道19、for(ioctl(4, VIDIOC_G_CTRL-獲得當前的屬性,比如亮度,對比度20、ioctl(4, VIDIOC_TRY_FMT-試試能否支持某種格式,比如RGB,YUV21、ioctl(4, VIDIOC_S_FMT-設置攝像頭使用某種格式(嘗試成功后22、ioctl(4, VIDIOC_REQBUFS-請求系統分配緩沖區23、ioctl(

21、4, VIDIOC_QUERYBUF-查詢所分配的緩沖區24、for(ioctl(4, VIDIOC_QBUF-把緩沖區放入隊列25、ioctl(4, VIDIOC_STREAMON-啟動攝像頭26、for(ioctl(4, VIDIOC_S_CTRL-設置屬性,比如亮度27、ioctl(4, VIDIOC_S_INPUT-設置輸入源28、ioctl(4, VIDIOC_S_STD-設置標準(制式29、for(select(5, 4, NULL, NULL, 5, 0 /查詢是否有數據ioctl(4, VIDIOC_DQBUF-de-queque,把緩沖區從隊列中取出/*處理*/ioctl(4

22、, VIDIOC_QBUF-處理完后把緩沖區放入隊列VIDIOC_ENUM_FMT有多次使用,在sourcesight里面搜索下xawtv源碼,發現在drv0-v4l2.c中有用到VIDIOC_ENUM_FMT,是一個for循環。for (h->nfmts = 0; h->nfmts < MAX_FORMA T; h->nfmts+ h->fmth->nfmts.index = h->nfmts;h->fmth->nfmts.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 = xioctl(h->f

23、d, VIDIOC_ENUM_FMT, &h->fmth->nfmts, EINVALbreak;同樣查看源碼,VIDIOC_ENUMINPUT,VIDIOC_ENUMSTD也多次調用,是一個for 循環。這些調用都是在drv0-v4l2.c里面的get_device_capabilities(struct v4l2_handle *h函數里面。由上面分析,涉及到的系統調用非常多,而有些是不必要的,下面來做精簡。在代碼中查找,系統調用在應用程序的函數可以總結如下:/*12都是在v4l2_open里調用*/1. open2. ioctl(4, VIDIOC_QUERYCAP/

24、*37 都是在get_device_capabilities里調用*/3. for(ioctl(4, VIDIOC_ENUMINPUT/ 列舉輸入源4. for(ioctl(4, VIDIOC_ENUMSTD / 列舉標準(制式, 不是必需的5. for(ioctl(4, VIDIOC_ENUM_FMT / 列舉格式6. ioctl(4, VIDIOC_G_PARM7. for(ioctl(4, VIDIOC_QUERYCTRL / 查詢屬性(比如說亮度值最小值、最大值、默認值/*810都是通過v4l2_read_attr來調用的*/8. ioctl(4, VIDIOC_G_STD / 獲得當

25、前使用的標準(制式, 不是必需的9. ioctl(4, VIDIOC_G_INPUT10. ioctl(4, VIDIOC_G_CTRL / 獲得當前屬性, 比如亮度是多少/*未發現在哪兒調用*/11. ioctl(4, VIDIOC_TRY_FMT / 試試能否支持某種格式/*12通過v4l2_setformat調用*/12. ioctl(4, VIDIOC_S_FMT / 設置攝像頭使用某種格式/* 1316在v4l2_start_streaming*/13. ioctl(4, VIDIOC_REQBUFS / 請求系統分配緩沖區14. for(ioctl(4, VIDIOC_QUERYB

26、UF / 查詢所分配的緩沖區mmap15. for (ioctl(4, VIDIOC_QBUF / 把緩沖區放入隊列16. ioctl(4, VIDIOC_STREAMON / 啟動攝像頭/* 17里都是通過v4l2_write_attr來調用的*/17. for (ioctl(4, VIDIOC_S_CTRL / 設置屬性ioctl(4, VIDIOC_S_INPUT / 設置輸入源ioctl(4, VIDIOC_S_STD / 設置標準(制式, 不是必需的/*v4l2_nextframe > v4l2_waiton */18. v4l2_queue_allv4l2_waitonfor

27、 (select(5, 4, NULL, NULL, 5, 0 = 1 (in 4, left 4, 985979ioctl(4, VIDIOC_DQBUF / de-queue, 把緩沖區從隊列中取出/ 處理, 之以已經通過mmap獲得了緩沖區的地址, 就可以直接訪問數據ioctl(4, VIDIOC_QBUF / 把緩沖區放入隊列總結如下:應用程序通過VIDIOC_REQBUFS請求系統分配緩沖區,用VIDIOC_QUERYBUF來查詢系統分配的緩沖區,再用VIDIOC_QBUF把緩沖區放到驅動程序某個隊列里面,調用VIDIOC_STREAMON啟動攝像頭。調用select函數來查詢有沒有

28、數據,如果驅動程序有了數據,就會把應用程序喚醒,應用程序通過調用VIDIOC_DQBUF來獲得緩沖區的信息并處理它,處理完之后再放回隊列中。xawtv的幾大函數:1. v4l2_open2. v4l2_read_attr/v4l2_write_attr3. v4l2_start_streaming4. v4l2_nextframe/v4l2_waiton2.4 簡化vivi的驅動程序應用程序使用ioctl,最終會使用的驅動程序的ioctl,驅動程序vivi.c的ioctl詳細列表如下:static const struct v4l2_ioctl_ops vivi_ioctl_ops = .vi

29、dioc_querycap = vidioc_querycap,.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,.vidioc_reqbufs = vidioc_reqbufs,.vidioc_querybuf = vidioc_querybuf,.vidioc_qb

30、uf = vidioc_qbuf,.vidioc_dqbuf = vidioc_dqbuf,.vidioc_s_std = vidioc_s_std,.vidioc_enum_input = vidioc_enum_input,.vidioc_g_input = vidioc_g_input,.vidioc_s_input = vidioc_s_input,.vidioc_queryctrl = vidioc_queryctrl,.vidioc_g_ctrl = vidioc_g_ctrl,.vidioc_s_ctrl = vidioc_s_ctrl,.vidioc_streamon = vi

31、dioc_streamon,.vidioc_streamoff = vidioc_streamoff,#ifdef CONFIG_VIDEO_V4L1_COMPAT.vidiocgmbuf = vidiocgmbuf,#endif;這些ioctl有些是必須的,有些不是必須的,下面先列出結果。攝像頭驅動程序必需的11個ioctl/ 表示它是一個攝像頭設備.vidioc_querycap = vidioc_querycap,/* 用于列舉、獲得、測試、設置攝像頭的數據的格式*/.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,.vidioc_g_

32、fmt_vid_cap = vidioc_g_fmt_vid_cap,.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,/* 緩沖區操作: 申請/查詢/放入隊列/取出隊列*/.vidioc_reqbufs = vidioc_reqbufs,.vidioc_querybuf = vidioc_querybuf,.vidioc_qbuf = vidioc_qbuf,.vidioc_dqbuf = vidioc_dqbuf,/ 啟動/停止.vidioc_streamon

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論