urb数据结构【转】
转自:http://blog.csdn.net/myarrow/article/details/7025065
版权声明:本文为博主原创文章,未经博主允许不得转载。
一、 transfer_flags
/*
* urb->transfer_flags:
*
* Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb().
*/
#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */
#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame ignored */
#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */
#define URB_NO_SETUP_DMA_MAP 0x0008 /* urb->setup_dma valid on submit */
#define URB_NO_FSBR 0x0020 /* UHCI-specific */
#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */
#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt needed */
#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
#define URB_DIR_IN 0x0200 /* Transfer from device to host */
#define URB_HCD_DRIVER_TEST 0xFFFF /* Do NOT hand back or free this URB */
#define URB_DIR_OUT 0
#define URB_DIR_MASK URB_DIR_IN
1. URB_SHORT_NOT_OK
这个标记只对用来从IN 端点读取数据的urb 有效,意思就是说如果从一个IN 端点那里读取了一个比较短的数据包,就可以认为是错误的。那么这里的
short 究竟short
到什么程度?之前说到端点的时候,就知道端点描述符里有一个叫wMaxPacketSize
这样的东东,指明了端点一次能够处理的最大字节数。每个端点描述符里的wMaxPacketSize
所表示的最大字节数都包括了哪些部分?是整个packet的长度么?我可以负责任的告诉你,它只包括了Data
包里面数据字段,俗称datapayload,其它那些七大姑八大姨什么的都是协议本身需要的信息,和TCP/IP 里的报头差不多。
wMaxPacketSize 与short 有什么关系? 关系还不小, short
不short 就是与wMaxPacketSize 相比的,如果从IN 端点那儿收到了一个比wMaxPacketSize
要短的包,同时也设置了URB_SHORT_NOT_OK
这个标志,那么就可以认为传输出错了。本来如果收到一个比较短的包是意味着这次传输到此为止就结束了,你想想data payload 的长度最
大必须为wMaxPacketSize
这个规定是不可违背的了,但是如果端点想给你的数据不止那么多,怎么办?就需要分成多个wMaxPacketSize 大小的data payload
来传输,事情有时不会那么凑巧,刚好能平分成多个整份,这时,最后一个data payload 的长度就会比wMaxPacketSize
要小,这种情况本来意味着端点已经传完了它想传的,释放完了自己的需求,这次传输就该结束了,不过如果你设置了URB_SHORT_NOT_OK
标志,HCD 这边就会认为错误发生了。
2. URB_ISO_ASAP
这个标志只是为了方便等时传输用的。等时传输和中断传输在spec 里都被认为是periodic
transfers,也就是周期传输,咱们都知道在usb
的世界里都是主机占主导地位,设备是没多少发言权的,但是对于等时传输和中断传输,端点可以对主机表达自己一种美好的期望,希望主机能够隔多长时间访问自己一次,这个期望的时间就是这里说的周期。当然,期望与现实是有一段距离的,如果期望的都能成为现实,咱们还研究usb干吗。端点的这个期望能不能得到满足,要看主机控制器答应不答应。对于等时传输,一般来说也就一帧(微帧)一次,主机那儿也很忙,再多也抽不出空儿来。那么如果你有个用于等时传输的urb,你提交给HCD
的时候,就得告诉HCD 它应该从哪一帧开始的,就要对下面要说的那个start_frame 赋值,也就是说告诉HCD
等时传输开始的那一帧(微帧)的帧号,如果你留心,应该还会记得前面说过在每帧或微帧(Mircoframe)的开始都会有个SOF Token
包,这个包里就含有个帧号字段,记录了那一帧的编号。这样的话,一是比较烦,还要去设置这个start_frame,你说烦不烦,二是到你设置的那一帧的时候,如果主机控制器没空开始等时传输,你说怎么办,要知道usb
的世界里它可是老大。于是,就出现了URB_ISO_ASAP,它的意思就是告诉HCD
啥时候不忙就啥时候开始,就不用指定什么开始的帧号了,是不是感觉特轻松?所以说,你如果想进行等时传输,又不想标新立异的话,就还是把它给设置了吧。
3. URB_NO_TRANSFER_DMA_MAP & URB_NO_SETUP_DMA_MAP
这两个标志都是有关DMA 的,什么是DMA?就是外设,比如咱们的usb 摄像头,和内存之间直接进行数据交换,把CPU 给撇一边儿了。
一般来说,都是驱动里提供了kmalloc 等分配的缓冲区,HCD 做一定的DMA
映射处理,DMA
映射是干吗的?外设和内存之间进行数据交换,总要互相认识吧,外设是通过各种总线连到主机里边儿的,使用的是总线地址,而内存使用的是虚拟地址,它们之间本来就是两条互不相交的平行线,要让它们中间产生连接点,必须得将一个地址转化为另一个地址,这样才能找得到对方,才能互通有无,而DMA
映射就是干这个的。为了分担点HCD 的压力,于是就有了这里的两个标志,告诉HCD
不要再自己做DMA 映射了,驱动提供的urb 里已经提供有DMA 缓冲区地址,为领导分忧解难是咱们这些小百姓应该做的事情。具体提供了哪些DMA
缓冲区?就涉及到下面的transfer_buffer,transfer_dma,还有setup_packet,setup_dma 这两对儿了。
4. URB_ZERO_PACKET
这个标志表示批量的OUT 传输必须使用一个short packet
来结束。批量传输的数据大于批量端点的wMaxPacketSize 时,需要分成多个Data 包来传输,最后一个data payload
的长度可能等于wMaxPacketSize,也可能小于,当等于wMaxPacketSize 时,如果同时设置了URB_ZERO_PACKET
标志,就需要再发送一个长度为0 的数据包来结束这次传输,如果小于wMaxPacketSize
就没必要多此一举了。你要问,当批量传输的数据小于wMaxPacketSize
时那?也没必要再发送0 长的数据包,因为此时发送的这个数据包本身就是一个short packet。
5. URB_NO_INTERRUPT
这个标志用来告诉HCD,在URB 完成后,不要请求一个硬件中断,当然这就意味着你的结束处理函数可能不会在urb 完成后立即被调用,而是在之后的某个时间被调用,咱们的usb core 会保证为每个urb 调用一次结束处理函数。
二、transfer_buffer & transfer_dma & transfer_buffer_length
管道的一端是主机上的缓冲区,一端是设备上的端点,这三个家伙就是描述主机上的那个缓冲区的。transfer_buffer 是使用kmalloc 分配的缓冲区,transfer_dma 是使用usb_buffer_alloc分配的dma
缓冲区,HCD 不会同时使用它们两个,如果你的urb
自带了transfer_dma,就要同时设置URB_NO_TRANSFER_DMA_MAP
来告诉HCD 一声,不用它再费心做DMA 映射了。transfer_buffer 是必须要设置的,因为不是所有的主机控制器都能够使用DMA
的,万一遇到这样的情况,也好有个备用。transfer_buffer_length指的就是transfer_buffer
或transfer_dma 的长度。
三、setup_packet & setup_dma
同样是两个缓冲区,一个是kmalloc分配的,一个是用usb_buffer_alloc分配的,不过,这两个缓冲区是控制传输专用的,记得struct
usb_ctrlrequest不?它们保存的就是一个struct
usb_ctrlrequest结构体,如果你的urb设置了setup_dma,同样要设置URB_NO_SETUP_DMA_MAP标志来告诉HCD。如果进行的是控制传输,setup_packet是必须要设置的,也是为了防止出现主机控制器不能使用DMA的情况。
四、start_frame
如果你没有指定URB_ISO_ASAP 标志,就必须自己设置start_frame,指定等时传输在哪帧或微帧开始。如果指定了URB_ISO_ASAP,urb 结束时会使用这个值返回实际的开始帧号。
五、interval
等时和中断传输专用。interval
间隔时间的意思,什么的间隔时间?就是上面说的端点希望主机轮询自己的时间间隔。这个值和端点描述符里的bInterval
是一样的,你不能随便儿的指定一个,协议里对你能指定的值是有范围限制的,对于中断传输,全速时,这个范围为1~255ms,低速是为10~255ms,高速时为1~16,这个1~16
只是bInterval 可以取的值,实际的间隔时间需要计算一下,为2 的(bInterval-1)次方乘以125 微妙,也就是2
的(bInterval-1)次方个微帧。对于等时传输,没有低速了,等时传输根本就不是低速端点负担得起的,有多大能耐就做多大事,人有多大胆地有多大产的时代早就已经过去了,对于全速和高速,这个范围也是为1~16,间隔时间由2
的(bInterval-1)次方算出来,单位为帧或微帧。这样看来,每一帧或微帧里,你最多只能期望有一次等时和中断传输,不能再多了,你只能期望房价涨的慢点,要是希望它跌下去,那要求就太过分了,它可是经济的柱子,要是倒了,那不是陷国人的生活于困境么,所以咱们要爱国啊,要送钱给ZF
还有任小强们啊同志们。
六、context
驱动设置了给下面的结束处理函数用的。比如可以将自己驱动里描述自己设备的结构体放在里边儿,在结束处理函数里就可以取出来。
complete
一个指向结束处理函数的指针,传输成功完成,或者中间发生错误的时候就会调用它,驱动可以在这里边儿检查urb
的状态,并做一些处理,比如可以释放这个urb,或者重新提交给HCD。就说摄像头吧,你向HCD 提交了个等时的urb
从摄像头那里读取视频数据,传输完成的时候调用了你指定的这个结束处理函数,并在里面取出了urb
里面获得的数据进行解码等处理,然后怎么着?总不会这一个urb 读取的数据就够你向mm
表白了吧,你的爱慕之情可是犹如滔滔江水连绵不绝,所以需要获得更多的数据,那你也总不会再去创建、初始化一个等时的urb
吧,即使再穷极无聊的人也不会那么做,明显刚刚的那个可以继续用的,只要将它再次提交给HCD
就可以了。这个函数指针的定义在include/linux/usb.h
typedef void (*usb_complete_t)(struct urb *);
urb数据结构【转】的更多相关文章
- 20.Linux-USB鼠标驱动
在上一章分析完USB总线驱动程序后, 接下来开始写一个USB驱动: 本节目的: 将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键 参考/drivers/hid/usbhid ...
- USB设备驱动概述
USB设备驱动 · )USB Hub:每个USBHost控制器都会自带一个USB Hub,被称为根(Root)Hub.这个根Hub可以接子(Sub)Hub,每个Hub上挂载USB设备.一般PC有8个 ...
- 8.1 编写USB鼠标驱动程序,并测试
学习目标:编写USB鼠标驱动程序,并测试(将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键). 一.怎么写USB设备驱动程序?步骤如下: 1. 首先先定义全局变量usb_d ...
- Linux usb 3. Host 详解
文章目录 1. 简介 2. Usb Core 驱动设备模型 2.1 Usb Device Layer 2.1.1 device (struct usb_device) 2.1.2 driver (st ...
- USB设备---URB请求快
1.urb 结构体USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结构 ...
- urb的处理流程
USB分析 2013年11月11日 16:06:24 阅读数:1807 转载自:http://blog.csdn.net/aaa6695798/article/details/4776202 很久 ...
- urb传输的代码分析【转】
转自:http://blog.csdn.net/zkami/article/details/2503829 urb传输的代码分析 如需引用,请注明出处blog.csdn.net/zkami 作者Zhe ...
- USB设备---URB请求块
1.urb 结构体 USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结 ...
- 12.1、USB驱动——描述符、URB、管道
大家常说,一个设备通常有多个配置,配置通常有多个接口,接口通常有多个端点.接口代表逻辑上的设备,比如声卡分为 录音和播放.访问设备时,访问的是某个接口(逻辑设备).除了端点0之外,每个端点只支持一个传 ...
随机推荐
- selenium+PhantomJS 抓取淘宝搜索商品
最近项目有些需求,抓取淘宝的搜索商品,抓取的品类还多.直接用selenium+PhantomJS 抓取淘宝搜索商品,快速完成. #-*- coding:utf-8 -*-__author__ =''i ...
- Git-补丁文件交互
版本库间的交互是通过git push和/或git pull命令实现的,这是Git最主要的交互模式,但并不是全部.使用补丁文件是另外一种交互方式,适用于参与者众多的大型项目进行分布式开发. 创建补丁 G ...
- Java线程和多线程(八)——Thread Dump
Java的Thread Dump就是列出JVM中所有激活状态的线程. Java Thread Dump Java Thread Dump在分析应用性能瓶颈和死锁的时候,是非常有效的. 下面将介绍多种不 ...
- struts2官方 中文教程 系列三:使用struts2 标签 tag
避免被爬,先贴上本帖地址:struts2 官方系列教程一:使用struts2 标签 tag http://www.cnblogs.com/linghaoxinpian/p/6901316.html 本 ...
- 发送广播重新挂载SD卡,使图库可以及时显示自己保存的图片(无需手机重启)
我们或许经常会遇到这种情况,明明保存了图片,但是当你打开图片时,却没有找到这张图片,手机重启之后才能看到.这是因为SD卡并没有重新挂载,图库也无法把这张图片加载进去,解决这个问题非常简单,只需要我们模 ...
- iOS 中 AFNetworking HTTPS 的使用
由于我们公司由HTTP转HTTPS,出现了一系列问题特此记录下. 一.HTTPS 二.App Transport Security 三.iOS 中用HTTPS 注意的问题 四.使用 AFNetwork ...
- Redmine部署到Windows Azure
有幸,今天可以尝试将Redmine部署到Windows Azure中,记下点滴,方便大家查阅 步骤一:Windows Azure中安装Ubuntu VM 遇到的问题,创建VM时会提示云服务.云存储订阅 ...
- Flash文件在asp页面无法播放,网页上面的Flash文件在火狐浏览器不播放
第一个问题:Flash文件放到asp页面以后无法播放. 解决方法:用浏览器打开页面->F12,选择Network,如下图: 然后刷新页面,如下图: 点击左侧状态是404的文件,如图: 可以发现F ...
- DOS程序员手册(五)
第8章磁 盘 学习编程语言,常常是从基本的输入和输出入手的(正如第5.6和第7章曾介绍的一 样).到目前为止,我们不仅学习了怎样输入和输出数据,还学习了如何进行数据操作 ...
- Git上手:四种常见的Git协同工作方式
1.集中式工作流 适用人群:开发小团队(4-5人),习惯使用SVN工具的小团队. 工作方式:团队组长创建远程仓库,创建一个master分支,组员可读可写. 每个开发人员都git clone远程仓库到本 ...