1. 程式人生 > >v4l2 video設備註冊和呼叫過程

v4l2 video設備註冊和呼叫過程

一、 註冊一個video_device裝置
它代表系統/dev/videox裝置節點的實際的物理裝置。
下邊一核心版本2.6.32種成熟的omap2432處理器攝像頭控制器模組驅動為例分析:
下邊的程式碼在driver/media/video/omap24xxcam.c中
1、Video device的操作函式集

  1. staticstruct v4l2_file_operations omap24xxcam_fops = {  
  2.  .ioctl  = video_ioctl2,  
  3.  .poll  = omap24xxcam_poll,  
  4.  .mmap  = omap24xxcam_mmap,  
  5.  .open  = omap24xxcam_open,  
  6.  .release = omap24xxcam_release,  
  7. };  



2、Video device控制操作函式集

  1. staticconststruct v4l2_ioctl_ops omap24xxcam_ioctl_fops = {  
  2.  .vidioc_querycap = vidioc_querycap,  
  3.  .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,  
  4.  .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,  
  5.  .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,  
  6.  .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,  
  7.  .vidioc_reqbufs  = vidioc_reqbufs,  
  8.  .vidioc_querybuf = vidioc_querybuf,  
  9.  .vidioc_qbuf  = vidioc_qbuf,  
  10.  .vidioc_dqbuf  = vidioc_dqbuf,  
  11.  .vidioc_streamon = vidioc_streamon,  
  12.  .vidioc_streamoff = vidioc_streamoff,  
  13.  .vidioc_enum_input = vidioc_enum_input,  
  14.  .vidioc_g_input  = vidioc_g_input,  
  15.  .vidioc_s_input  = vidioc_s_input,  
  16.  .vidioc_queryctrl = vidioc_queryctrl,  
  17.  .vidioc_g_ctrl  = vidioc_g_ctrl,  
  18.  .vidioc_s_ctrl  = vidioc_s_ctrl,  
  19.  .vidioc_g_parm  = vidioc_g_parm,  
  20.  .vidioc_s_parm  = vidioc_s_parm,  
  21. };  

3、註冊函式:omap24xxcam_device_register

  1. staticint omap24xxcam_device_register(struct v4l2_int_device *s)  
  2. {  
  3.  struct omap24xxcam_device *cam = s->u.slave->master->priv;  
  4.  struct video_device *vfd;//定義struct video_device結構體
  5.  int rval;  
  6. 。。。。。。  
  7.  /* initialize the video_device struct */
  8.  vfd = cam->vfd = video_device_alloc();  
  9.  if (!vfd) {  
  10.   dev_err(cam->dev, "could not allocate video device struct\n");  
  11.   rval = -ENOMEM;  
  12.   goto err;  
  13.  }  
  14.  vfd->release = video_device_release;  
  15.  vfd->parent = cam->dev;  
  16.  strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));  
  17. //該video device裝置V4L2操作函式集,在下邊定義,這個通過最頂級字元裝置的響應操作函式呼叫
  18.  vfd->fops   = &omap24xxcam_fops;   
  19.  vfd->minor   = -1;  
  20. //該video device裝置控制操作,和vfd->fops中的ioctl可能重複,下邊進一步分析。
  21.  vfd->ioctl_ops   = &omap24xxcam_ioctl_fops;   
  22.  omap24xxcam_hwinit(cam);  
  23.  rval = omap24xxcam_sensor_init(cam);  
  24.  if (rval)  
  25.   goto err;  
  26. //註冊video device,VFL_TYPE_GRABBER表示註冊的是視訊處理裝置,video_nr=-1表示自動分配從裝置號
  27.  if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {  
  28.   dev_err(cam->dev, "could not register V4L device\n");  
  29.   vfd->minor = -1;  
  30.   rval = -EBUSY;  
  31.   goto err;  
  32.  }  
  33. 。。。。。。。  
  34. err:  
  35.  omap24xxcam_device_unregister(s);  
  36.  return rval;  
  37. }  

二、 呼叫過程
應用程式的read、write、ioctl等操作函式傳到核心層
以ioctl為例作說明:
1、最頂層的呼叫
在driver/media/video/v4l2-dev.c中:

  1. staticint v4l2_ioctl(struct inode *inode, struct file *filp,  
  2.   unsigned int cmd, unsigned long arg)  
  3. {  
  4.  //根據次裝置號從video_device[VIDEO_NUM_DEVICES]陣列中得到當前操作的video device
  5.  struct video_device *vdev = video_devdata(filp);  
  6.  if (!vdev->fops->ioctl)  
  7.   return -ENOTTY;  
  8.  /* Allow ioctl to continue even if the device was unregistered. 
  9.     Things like dequeueing buffers might still be useful. */
  10.  return vdev->fops->ioctl(filp, cmd, arg);  
  11. }  

2、自己實現的操作函式集
根據上邊註冊時填充的fops,vdev->fops->ioctl(filp, cmd, arg)呼叫下邊函式:
(在driver/media/video/omap24xxcam.c)

  1. staticstruct v4l2_file_operations omap24xxcam_fops = {  
  2.  .ioctl  = video_ioctl2,  
  3.  。。。。。  
  4. }  

3、中間層處理呼叫
Video_ioctl2是定義在driver/media/video/v4l2-ioctl.c中的函式:

  1. long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg)  
  2. {  
  3.  char sbuf[128];  
  4.  void    *mbuf = NULL;  
  5.  void *parg = NULL;  
  6.  long err  = -EINVAL;  
  7.  int     is_ext_ctrl;  
  8.  size_t  ctrls_size = 0;  
  9.  void __user *user_ptr = NULL;  
  10. 控制命令處理。。。。。。。。。。  
  11.  /* Handles IOCTL */
  12.  err = __video_do_ioctl(file, cmd, parg);  
  13.  if (err == -ENOIOCTLCMD)  
  14.   err = -EINVAL;  
  15.  if (is_ext_ctrl) {  
  16.   struct v4l2_ext_controls *p = parg;  
  17.   p->controls = (void *)user_ptr;  
  18.   if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))  
  19.    err = -EFAULT;  
  20.   goto out_ext_ctrl;  
  21.  }  
  22.  if (err < 0)  
  23.   goto out;  
  24. 錯誤處理。。。。。。。。。  
  25. }  

4、根據命令呼叫相應的處理函式
下邊就是根據傳入的控制引數,呼叫相應的已經註冊的v4l2_ioctl_ops操作處理

  1. staticlong __video_do_ioctl(struct file *file, unsigned int cmd, void *arg)  
  2. {  
  3. //得到當前操作的video device
  4.  struct video_device *vfd = video_devdata(file);  
  5. //v4l2 控制操作函式集,在video device註冊時賦值。
  6.  conststruct v4l2_ioctl_ops *ops = vfd->omap24xxcam_ioctl_fops;  
  7.  void *fh = file->private_data;  
  8.  long ret = -EINVAL;  
  9. 引數錯誤處理。。。。。  
  1. #ifdef CONFIG_VIDEO_V4L1_COMPAT
  2.  /*********************************************************** 
  3.   Handles calls to the obsoleted V4L1 API 
  4.   Due to the nature of VIDIOCGMBUF, each driver that supports 
  5.   V4L1 should implement its own handler for this ioctl. 
  6.   ***********************************************************/
  7.  /* --- streaming capture ------------------------------------- */
  8.  if (cmd == VIDIOCGMBUF) {  
  9.   struct video_mbuf *p = arg;  
  10.   if (!ops->vidiocgmbuf)  
  11.    return ret;  
  12.   ret = ops->vidiocgmbuf(file, fh, p);  
  13.   if (!ret)  
  14.    dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n",  
  15.       p->size, p->frames,  
  16.       (unsigned long)p->offsets);  
  17.   return ret;  
  18.  }  
  19.  /******************************************************** 
  20.   All other V4L1 calls are handled by v4l1_compat module. 
  21.   Those calls will be translated into V4L2 calls, and 
  22.   __video_do_ioctl will be called again, with one or more 
  23.   V4L2 ioctls. 
  24.   ********************************************************/
  25.  if (_IOC_TYPE(cmd) == 'v' && _IOC_NR(cmd) < BASE_VIDIOCPRIVATE)  
  26.   return v4l_compat_translate_ioctl(file, cmd, arg,  
  27.       __video_do_ioctl);  
  28. #endif
  29.  switch (cmd) {  
  30.  /* --- capabilities ------------------------------------------ */
  31.  case VIDIOC_QUERYCAP:  
  32.  {  
  33.   struct v4l2_capability *cap = (struct v4l2_capability *)arg;  
  34.   if (!ops->vidioc_querycap)  
  35.    break;  
  36.   ret = ops->vidioc_querycap(file, fh, cap);  
  37.   if (!ret)  
  38.    dbgarg(cmd, "driver=%s, card=%s, bus=%s, "
  39.      "version=0x%08x, "
  40.      "capabilities=0x%08x\n",  
  41.      cap->driver, cap->card, cap->bus_info,  
  42.      cap->version,  
  43.      cap->capabilities);  
  44.   break;  
  45.  }  
  46. }  

相關推薦

v4l2 video備註呼叫過程

一、 註冊一個video_device裝置 它代表系統/dev/videox裝置節點的實際的物理裝置。 下邊一核心版本2.6.32種成熟的omap2432處理器攝像頭控制器模組驅動為例分析: 下邊的程式碼在driver/media/video/omap24xxcam.c中

十二 v4l2 video備註呼叫過程

一、 註冊一個video_device裝置 它代表系統/dev/videox裝置節點的實際的物理裝置。 下邊一核心版本2.6.32種成熟的omap2432處理器攝像頭控制器模組驅動為例分析: 下邊的程式碼在driver/media/video/omap24xxcam.c中 1、Video device的操

裝置樹學習之(九)SPI備註過程

開發板:tiny4412SDK + S702 + 4GB Flash 要移植的核心版本:Linux-4.4.0 (支援device tree) u-boot版本:友善之臂自帶的 U-Boot 2010.12 busybox版本:busy

SPI備註過程

開發板:tiny4412SDK + S702 + 4GB Flash 要移植的核心版本:Linux-4.4.0 (支援device tree) u-boot版本:友善之臂自帶的 U-Boot 2010.12 busybox版本:busybox 1.25 目標: 同 i

I2C匯流排備註過程

轉自 http://lhsblog01.blog.163.com/blog/static/1020045192010221103944423/i2c bus i2c匯流排使用 platform_device實現, 匯流排驅動用platform_driver實現. 在註冊i2c_bus時,會把與這個BUS相

QCom MSM平臺顯示屏Framebuffer備註過程

本文是Android Display部分分析的一部分,描述屏Framebuffer設備註冊過程。 QC MSM7xxx/MSM8xxx平臺本身就提供了很多介面的屏的支援,每種屏對應一個驅動檔案。由於QC MSM平臺顯示驅動架構做了絕大部分的工作,驅動一塊新的屏僅需要做很少量的工作。下面的過程是屏Frameb

ISE主備註同步

Synchronize Primary and Secondary Cisco ISE Nodes You can make configuration changes to Cisco ISE only through the Primary PAN. The configuration changes g

WebService—CXF整合Spring實現介面釋出呼叫過程

CXF整合Spring實現介面釋出 釋出過程如下: 1、引入jar包(基於maven管理) <dependency> <groupId>org.apache.cxf</groupId> <artifactId>

Spring Cloud微服務的簡單組成呼叫過程

學習微服務的過程中,很多東西都會忘,所以就畫了一個微服務的圖,其實之前我也畫過微服務的圖,但是沒有這個詳細,希望能幫到正在開始學習微服務的人吧!       其實微服務很簡單就像你去足療店一樣,你不知道怎麼去,第一次,怎麼辦,你求助你的朋友,你的朋友經常去,所以你的

Linux:驅動之字元備註新介面(未完)

驅動之字元設備註冊新介面 目前尚不是最終版本,還望有心人自己學習的時候,把自己整合的知識點相關的答案也好問題也好,或者實踐過程中的一些操作截圖,再或者其他的一些想要分享材料發給筆者郵箱:[email protected],我們一起完善這篇部落格!筆者寫這篇部

Oracle中建立儲存過程呼叫過程(一)

1、定義         所謂儲存過程(Stored Procedure),就是一組用於完成特定資料庫功能的SQL語句集,該SQL語句集經過 編譯後儲存在資料庫系統中。在使用時候,使用者通過指定已經定義的儲存過程名字並給出相應的儲存過程引數 來呼叫並執行

備註、驅動註冊以及雜項備註之間的關係

1.裝置宣告是在平臺檔案/home/leizi/android/iTop4412_Kernel_3.0/arch/arm/mach-exynos/mach-itop4412.c中,如下圖,並且裝置名稱是led_two. 核心編譯之後,s3c_device_leds_ctl

android音量控制曲線呼叫過程

http://blog.csdn.net/newtonnl/article/details/8455136 Android音訊曲線呼叫從ui介面往下設定,根據stream音訊有不同的UI,分為7步,15步,對應到實際的100步。這個轉換過程可以參考AudioPolicy

platform_device_系列函式及其備註的作用

platform_device_系列函式,實際上是註冊了一個叫platform的虛擬匯流排。使用約定是如果一個不屬於任何匯流排的裝置,例如藍芽,串列埠等裝置,都需要掛在這個虛擬總線上。 river/base/platform.c //platform裝置宣告 struct

Presto 標量函式註冊呼叫過程簡述

在[Presto 函式開發](https://note.youdao.com/)一文中已經介紹過如何進行函式開發,本文主要講述標量函式(Scalar Function)實現之後,是如何在Presto內部進行註冊和被呼叫的。主要講述標量函式是因為:三類函式的註冊和呼叫過程略有不同,而實際查詢中呼叫最多的是標量函

(轉)關於Tomcat的點點滴滴(體系架構、處理http請求的過程、安裝配置、目錄結構、置壓縮對中文文件名的支持、以及Catalina這個名字的由來……等)

https 設置 重啟 specific 調用 持久化數據 所在 original apps 轉自:http://itfish.net/article/41668.html 總結Tomcat的體系架構、處理http請求的過程、安裝和配置、目錄結構、設置壓縮和對中文文件名

H5調用備攝像頭系統相

camera 系統相冊 capture 調用 設備 accept 攝像 acc ima 1.調用設備攝像頭 <input type="file" accept="image/*" capture="camera"> 2.調用系統相冊 <inp

函式的呼叫過程詳解———棧幀的建立銷燬

●回顧內容: 函式的定義:函式是一個程式中的部分程式碼,由一個或多個語句組成,它的功能是實現某些特定的任務。函式相對於其他程式碼來說具備相對的獨立性。 函式的呼叫:在某個函式內部,使用另一個函式來完成相關的任務,這個過程叫做函式呼叫。 那麼函式是如何呼叫的呢?分析一段簡單的程式碼:

建立呼叫儲存過程:查詢Stu資料庫中某個同學的選修課程的資訊,包括學號,姓名,課程名稱,成績

CREATE PROCEDURE proc_select--建立儲存過程 @Sno char(10) output,--輸入輸出引數 @Sname varchar(20) out,--輸出引數 @Cno char(4) out,--輸出引數 @grade tinyint

android中的跨程序通訊的實現(一)——遠端呼叫過程aidl

android在設計理念上強調元件化,元件之間的依賴性很小。我們往往發一個intent請求就可以啟動另一個應用的activity,或者一個你不知道在哪個程序的service,或者可以註冊一個廣播,只要有這個事件發生你都可以收到,又或者你可以查詢一個contentProvider獲得你想要的資料,這其