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.   

    相關推薦

    v4l2 video備註呼叫過程

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

    v4l2 video備註呼叫過程

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

    、samba服務器配置管理

    samba、文件共享12.1、Samba簡介 Linux和Windows是兩種無論在風格還是在技術上都完全不同的操作系統,它們是兩個對立的陣形。各自都擁有自己的用戶群和市場。但是,要實現這兩種系統之間的資源共享,則需要使用Samba。Samba采用的是C/S工作模式,通過它可以將一臺Linux系統主機配置為

    )easyUI之表單驗證完成登錄頁面

    () 成功 options 表單提交 odi 1-1 java ima 1.4 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    python全棧開發基礎【第二篇】進程池回調函數

    enc 並發執行 exce 核數 exc 為什麽 .py bsp urn 一、數據共享 1.進程間的通信應該盡量避免共享數據的方式 2.進程間的數據是獨立的,可以借助隊列或管道實現通信,二者都是基於消息傳遞的。 雖然進程間數據獨立,但可以用過Manager實現數據共享,事實

    )SpringBoot 置定時任務

    led pack 測試 print clas job imp 固定 dem 一:創建定時任務 創建core→tesks→tesk.java package com.example.demo.core.tasks; import org.springframework.s

    SpringBoot | 第三章:事件的釋出監聽

    前言 今天去官網檢視spring boot資料時,在特性中看見了系統的事件及監聽章節。想想,spring的事件應該是在3.x版本就釋出的功能了,並越來越完善,其為bean和bean之間的訊息通訊提供了支援。比如,我們可以在使用者註冊成功後,傳送一份註冊成功的郵件至使用者郵箱或者傳送簡訊。使用事件其實最

    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

    java基礎()抽象類(Abstract class)介面(interface)

    抽象類(Abstract class): 抽象類概述: 抽象類是對根源的抽象(即對本質的抽象與其他類的本質不同)。 抽象類表示的是這個東西是什麼。比如男人女人,,他們的抽象類就是人,所以繼承也只能繼承一個類(抽象類)(是人那就是人,不能是別的生物) 且如果有抽象的功能(吃,睡…),該

    Effective_STL 學習筆記() 避免原地修改 set multiset 的健

    情況下 刪除元素 一份 pre rpo cast set、map class color 正如所有標準關聯容器,set 和 multiset 保持它們的元素有序,容器的正確行為依賴於它們保持有序,如果改變一個元素的值,新值不在正確的位置,將破壞容器的有序性。 對於

    springcloud():使用Spring Cloud SleuthZipkin進行分散式鏈路跟蹤

    Spring Cloud Sleuth 一般的,一個分散式服務跟蹤系統,主要有三部分:資料收集、資料儲存和資料展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分散式系統,資料儲存可分為實時資料和全量資料兩部分,實時資料用於故障排查(troubleshooting),全量資料用於系統優化;資

    springcloud+springboot():使用Spring Cloud SleuthZipkin進行分散式鏈路跟蹤

    Spring Cloud Sleuth 一般的,一個分散式服務跟蹤系統,主要有三部分:資料收集、資料儲存和資料展示。根據系統大小不同,每一部分的結構又有一定變化。譬如,對於大規模分散式系統,資料儲存可分為實時資料和全量資料兩部分,實時資料用於故障排查(troubleshooting),全量資料用於系統優化

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

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

    Scrum立會報告+燃盡圖(十二月十一日總第四次):貢獻分配收集使用者報告

    此作業要求參見:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2484 專案地址:https://git.coding.net/zhangjy982/QuJianBang.git Scrum立會master:楊金銘 一、小組介紹 組長:付佳

    MIT 線性代數導論 第二講:矩陣對角化

    本講的主要內容 對角化矩陣的概念以及方法 計算矩陣的冪的對角化方法 幾個例子 對角化矩陣、計算矩陣的冪 對於一個有 nnn 個不同特徵向量(其實就是說所有的特徵值均不同)的矩陣 AAA,講它的 nnn 個特徵向量組成一個矩陣 SSS ,如果我們計算 ASAS

    討喜的隔離可變性()基於角色模型的侷限性小結

    宣告:本文是《Java虛擬機器併發程式設計》的第五章,感謝華章出版社授權併發程式設計網站釋出此文,禁止以任何形式轉載此文。 截至目前我們所寫的關於角色的例子中,所有角色及其客戶端都運行於同一JVM程序中。但在現實生活中,有一部分開發者認為角色也應該像在Erlang中那樣被用於程序間通訊。而另一

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

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

    Android開發系列():AdapterViewFlipper的功能用法

    AdapterViewFlipper繼承了AdapterViewAnimator,它會顯示一個View元件,可以通過showPrevious()和showNext()方法控制組件顯示上一個、下一個元件。 XML屬性: android:animateFirstView:設定

    ClearCase完全攻略() CCRC客戶端安裝外掛安裝

    CCRC的環境配置說起來簡單,其實折騰人。 安裝問題。 接下來就是Eclipse可能需要提示缺少org.eclipse.draw2d 外掛,所以需要手工安裝GEF這個外掛,下載地址 。注意版本對應。 Clearcase好像版本上下不相容,CCRC2003和7.0的不能

    Java併發程式設計系列之:死鎖、飢餓活鎖

    死鎖發生在一個執行緒需要獲取多個資源的時候,這時由於兩個執行緒互相等待對方的資源而被阻塞,死鎖是最常見的活躍性問題。這裡先分析死鎖的情形: 假設當前情況是執行緒A已經獲取資源R1,執行緒B已經獲取資源R2,之後執行緒A嘗試獲取資源R2,這個時候因為資源R2已經