⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux系统下usb摄像头驱动开发 - top大杂烩 - csdnblog.htm

📁 Understanding of software development methodologies and concepts, experience with full product lifec
💻 HTM
📖 第 1 页 / 共 5 页
字号:
style="COLOR: #333333; LINE-HEIGHT: 150%">带宽,帧速不高,不易满足实时监控等要求。本文首先介绍在</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">Linux</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">系统下</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">摄像头驱动编制的一般方法,然后说明在此基础上如何提高帧速。</SPAN></SPAN></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%" align=left><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">设备驱动程序完全符合通用设备驱动的准则,不同的是内核提供了一些特别的</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">API</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">函数,方便驱动注册、销毁自己,例如</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">usb_reSister()</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">和</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">usb_dereSister()</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">;</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">2</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">.</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">4</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">版的内核还提供了对于</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">hotplug</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">的支持。<SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%"> </SPAN></SPAN></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%" align=left><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%"></SPAN>&nbsp;</DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%" align=left><STRONG><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">1</SPAN></STRONG><STRONG><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">.</SPAN></STRONG><STRONG><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">1 USB</SPAN></STRONG><STRONG><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">摄像头驱动的一般编写方法</SPAN></STRONG></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%" align=left><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">摄像头属于视频类设备。在目前的</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">Linux</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">核心中,视频部分的标准是</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">Video for Linux(</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">简称</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">V4L)</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">。这个标准其实定义了一套接口,内核、驱动、应用程序以这个接口为标准进行交流。目前的</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">V4L</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">涵盖了视、音频流捕捉及处理等内容,</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">摄像头也属于它支持的范畴。</SPAN></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%" align=left><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">因此,</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">摄像头的驱动应当与内核提供的视频驱动挂钩。即首先在驱动中声明一个</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">video_device</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">结构,并为其指定文件操作函数指针数组.</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">fops</SPAN><SPAN 
style="COLOR: #333333; LINE-HEIGHT: 150%">,向系统注册。在应用程序发出文件操作的相关命令时,核心根据这些指针调用相应函数,并将该结构作为参数传递给它们。这样,就完成了驱动和核心之间的通信。例如:</SPAN></DIV>
<P>
<TABLE 
style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: #f3f3f3; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" 
cellSpacing=0 cellPadding=0 border=1>
  <TBODY>
  <TR>
    <TD 
    style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" 
    vAlign=top width=568>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">static struct 
      video_device vdev_template</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">=</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">{……}</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">;</SPAN></DIV>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">/</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">/声明</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">video_device</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">,指出挂接驱动</SPAN></DIV>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">static struct 
      file_operations ov511_fops</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">=</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">{……}</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">;</SPAN></DIV>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">//声明本驱动的文件操作函数指针</SPAN></DIV>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">struct 
      video_device*vdev</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">=</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">video_devdata(file)</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">;</SPAN></DIV>
      <DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">//从文件指针中提取出</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">video_device</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">结构</SPAN></DIV>
      <DIV style="LINE-HEIGHT: 150%">&nbsp;</DIV></TD></TR></TBODY></TABLE></P>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">在</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">video_device</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">结构中,有一个私有指针</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">priv</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">,可以将它指向一块保留内存。在这块内存中,保存着本驱动、本设备的相关初始化信息。这块内存的申请、初始化、指针指向等工作都是在</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">驱动的枚举函数</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">.probe</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">中完成。这样,在枚举函数将控制权返还给系统后,因为内核不销毁保留内存,所以驱动仍然保留着自己的信息。这点与</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">Windows</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">系统中</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">WDM</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">驱动有异曲同工之处。当然,在驱动卸载函数中,应当将申请的各块内存全部释放。</SPAN></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%"></SPAN>&nbsp;</DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">1</SPAN></STRONG><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">.</SPAN></STRONG><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">2 
</SPAN></STRONG><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">使用双</SPAN></STRONG><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN></STRONG><STRONG><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">轮流通信</SPAN></STRONG></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">众所周知,</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USBl</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">.</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">1</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">总线标准定义了控制、中断、批量、等时等四种管道。对于时间性极强但是准确度要求不高的视频捕捉应用来说,摄像头应当使用等时传输方式。为了尽可能快地得到图像数据,应当在</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">中指定</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB_ISO_ASAP</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">标志。</SPAN></DIV>
<P>
<TABLE 
style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BACKGROUND: #f3f3f3; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" 
cellSpacing=0 cellPadding=0 border=1>
  <TBODY>
  <TR>
    <TD 
    style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent" 
    vAlign=top width=568>
      <DIV style="LINE-HEIGHT: 150%"><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">urb-&gt;transfer_flags</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">=</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB_ISO_ASAP</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">;//尽可能快地发出本</SPAN><SPAN 
      style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN></DIV></TD></TR></TBODY></TABLE></P>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">Linux</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">系统中任何</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">传输都通过</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">实现。为提高速度,可以考虑扩大</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">的缓冲,这样可以降低每个</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">事务中握手信息所占比例,提高有效数据的传输速度。但是受限于总线带宽和具体的</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">设备芯片,单纯扩大</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">的缓冲不能无限制地解决问题。具体分析一下</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">USB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">传输在操作系统中的实现:每次传输都要包括</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">的建立、发出、回收、数据整理等阶段,这些时间不产生有效数据。因此可以建立两个</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">,在等待一个</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">被回收时,也就是图像正在被传感器采集时,处理、初始化另一个</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">,并在回收后立刻将其发出。两个</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">交替使用,大大减少了额外时间。工作流程如图</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">1</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">所示。<IMG alt="" 
src="Linux系统下USB摄像头驱动开发 - Top大杂烩 - CSDNBlog.files/tu1.bmp"></SPAN></DIV>
<DIV style="TEXT-INDENT: 22.5pt; LINE-HEIGHT: 150%"><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">这个过程是在</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">URB</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">的完成例程中实现的,有两点需要注意:首先处理再次初始化的代码时间不能长,否则会造成完成例程的重人,如果确实来不及,可以在完成例程中设定标志,例如</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">“</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">数据采集好</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">”</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">旗语,由应用程序使用阻塞</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">ioctl()</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">来查询该旗语并做处理;其次由于</SPAN><SPAN 
style="FONT-SIZE: 10.5pt; COLOR: #333333; LINE-HEIGHT: 150%">CPU</SPAN><SPAN 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -