转自: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数据结构【转】的更多相关文章

  1. 20.Linux-USB鼠标驱动

    在上一章分析完USB总线驱动程序后, 接下来开始写一个USB驱动: 本节目的: 将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键 参考/drivers/hid/usbhid ...

  2. USB设备驱动概述

    USB设备驱动 ·  )USB Hub:每个USBHost控制器都会自带一个USB Hub,被称为根(Root)Hub.这个根Hub可以接子(Sub)Hub,每个Hub上挂载USB设备.一般PC有8个 ...

  3. 8.1 编写USB鼠标驱动程序,并测试

    学习目标:编写USB鼠标驱动程序,并测试(将USB鼠标的左键当作L按键,将USB鼠标的右键当作S按键,中键当作回车按键). 一.怎么写USB设备驱动程序?步骤如下: 1. 首先先定义全局变量usb_d ...

  4. 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 ...

  5. USB设备---URB请求快

    1.urb 结构体USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结构 ...

  6. urb的处理流程

      USB分析 2013年11月11日 16:06:24 阅读数:1807 转载自:http://blog.csdn.net/aaa6695798/article/details/4776202 很久 ...

  7. urb传输的代码分析【转】

    转自:http://blog.csdn.net/zkami/article/details/2503829 urb传输的代码分析 如需引用,请注明出处blog.csdn.net/zkami 作者Zhe ...

  8. USB设备---URB请求块

    1.urb 结构体 USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结 ...

  9. 12.1、USB驱动——描述符、URB、管道

    大家常说,一个设备通常有多个配置,配置通常有多个接口,接口通常有多个端点.接口代表逻辑上的设备,比如声卡分为 录音和播放.访问设备时,访问的是某个接口(逻辑设备).除了端点0之外,每个端点只支持一个传 ...

随机推荐

  1. Android 中的一些特殊目录与文件

    用作命令的二进制文件位于/system/bin/与/system/xbin/下 应用数据位于/data/data/, 原始安装文件位于/data/app/(Play商店中非免费应用位于/data/ap ...

  2. K-均值聚类——电影类型

    K-均值聚类 K-均值算法试图将一系列样本分割成K个不同的类簇(其中K是模型的输入参数),其形式化的目标函数称为类簇内的方差和(within cluster sum of squared errors ...

  3. 9.5web service基础知识

    Web服务基础 用户访问网站的基本流程 我们每天都会用web客户端上网,浏览器就是一个web客户端,例如谷歌浏览器,以及火狐浏览器等. 当我们输入www.oldboyedu.com/时候,很快就能看到 ...

  4. Spark-Streaming 常用流式计算算子

    UpdateStateByKey 使用说明:维护key的状态. 使用注意:使用该算子需要设置checkpoint 使用示例: object UpdateStateByKeyTest { def mai ...

  5. 树莓派Raspberry Pi 3安装步骤

    一.需要的硬件 1.Raspberry Pi 3(Model B+)树莓派.购买>https://item.jd.com/29225467867.html 2.输出5V/2A的电源 3.SD卡( ...

  6. Android学习记录(6)—将java中的多线程下载移植到Android中(即多线程下载在Android中的使用)③

    在这一节中,我们就来讲多线程下载以及断点续传在android中怎么使用,前两节是为本节做准备的,没有看前两节的同学,最好看完前面的两篇文章再来看这篇.其实在android端的应用和java基本上是差不 ...

  7. NOIP 2018 总结

    NOIP 2018 总结 提高组: 应得分 \(100 + 100 + 40 + 100 + 50 + 44 = 434\). 考后期望得分 \(100 + 100 + 20 + 100 + 50 + ...

  8. python之while/for循环

    一.while循环 (一)循环语句 while 后面接判断语句,在返回结果时有以下几种语句: 1.break 仅适用于循环语句,意思是结束最近的循环 2.continue 仅适用于循环语句,意思是跳到 ...

  9. 解决display:inline-block;行内块元素出现空白空隙问题

     给他的父元素加:font-size:0px;,   ul { font-size:0px;} li { font-size:16px;}

  10. day06_06 字典操作01

    1.0 字典操作 dic1 = {'name':'alex'} dic1['age'] = 18 print(dic1) #>>>{'age': 18, 'name': 'alex' ...