学到这里不容易,先说一段故事吧。

二兄弟住一大楼的第80层,某深夜回家忘看通知(内容今夜停电)。

兄弟俩背着沉重的大背包,在楼底下商量一下,决定一鼓作气,爬楼梯回家。两人抖擞精神,开始爬楼。爬到20楼的时候,开始觉得背包很重了。两人商量,决定把背包存在20楼,到时候再回过头来取。卸下了背包,两个人觉得很轻松,说说笑笑地继续往上爬。

爬到40楼的时候,两人已经很累了,就开始互相抱怨指责。哥哥说:你为什么不看通知啊?弟弟说:我忘了看通知这件事,你怎么不提醒我昵?两个人就这样吵吵闹闹,一路吵到60层。

到了这时候,两人实在疲惫不堪,终于懒得吵了,觉得还是应该安安静静地继续爬楼。当他们终于爬完了最后20层,来到了家门口的时候,两个人互相一看,不约而同想起了一件事:钥匙忘在20楼了,在背包里。

其实,这说的就是人的一生。(故事来源 于丹 《论生与死》)

在struct usb_host_interface结构体,我们把struct usb_host_endpoint *endpoint成员忽略了,下面就看这个结构体。

struct usb_host_endpoint {

struct usb_endpoint_descriptor desc;

struct list_head urb_list;

void *hcpriv;

struct ep_device *ep_dev; /* For sysfs info */

unsigned char *extra; /* Extra descriptors */

int extralen;

};

按照我们做事的原则:避重就轻。先不分析usb_interface_descriptor结构体成员,咱们先分析其他简单的。

urb_list表示端点要处理的urb队列。urb是什么?urb可是usb通信的主角,它包含了执行urb传输所需要的所有信息,若要进行usb通信,就得创建一个urb,并且为它赋好值(专业点就是初始化),交给咱们的usb core,它会找到合适的host controller,从而进行具体的数据传输。设备中的每个端点都可以处理一个urb队列,可以理解为urb是内核里对usb传输数据的封装(或者抽象)。基于urb特殊性,会有专题来分析它。

hcpriv,这是提供给HCD(host controller driver)用的。比如等时端点会在里边儿放一个ehci_iso_stream,什么意思?郑板桥告诉我们要难得糊涂,以后会明白的。

ep_dev,这个字段是供sysfs用的。好奇的话可以去/sys下看一看

[root@localhost ep_00]# pwd

/sys/bus/usb/devices/usb1/ep_00

[root@localhost ep_00]# ls

bEndpointAddress bmAttributes direction subsystem wMaxPacketSize

bInterval dev interval type

bLength device power uevent

[root@localhost ep_00]#

ep_00端点目录下的这些文件从哪儿来的?就是在usb_create_ep_files函数里使用ep_dev创建的。

extra和 extralen,有关一些额外扩展的描述符的,和struct usb_host_interface里差不多,只是这里的是针对端点的,如果你请求从设备里获得描述符信息,它们会跟在标准的端点描述符后面返回给你。

再回头看看desc的结构体struct usb_endpoint_descriptor定义

/* USB_DT_ENDPOINT: Endpoint descriptor */

struct usb_endpoint_descriptor {

__u8 bLength;

__u8 bDescriptorType;

__u8 bEndpointAddress;

__u8 bmAttributes;

__le16 wMaxPacketSize;

__u8 bInterval;

/* NOTE: these two are _only_ in audio endpoints. */

/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */

__u8 bRefresh;

__u8 bSynchAddress;

} __attribute__ ((packed));

这个结构与spec Table 9.13是一一对应的,0号端点仍然保持着它特殊的地位,它没有自己的端点描述符。

bLength,描述符的字节长度。数一下,前边儿有7个字节,后边儿又多了两个字节__u8 bRefresh; __u8 bSynchAddress;那是针对音频设备扩展的,不用管它

bDescriptorType,描述符类型,这里对于端点就是USB_DT_ENDPOINT,0x05,紧接在usb_endpoint_descriptor结构体定义后面。还记得对于接口描述符类型是什么吗?对,值为USB_DT_INTERFACE,也就是0x04。

bEndpointAddress,这个字段描述的信息挺多的,比如这个端点是输入端点还是输出端点,这个端点的地址,以及这个端点的端点号。它的bits 0~3表示的就是端点号,你使用0x0f和它相与就可以得到端点号。不过,开发内核的同志想的都很周到,定义好了一个掩码USB_ENDPOINT_NUMBER_MASK,它的值就是0x0f,当然,这是为了让咱们更容易去读他们的代码,也为了以后的扩展。另外,它的bit 8表示方向,输入还是输出,同样有掩码USB_ENDPOINT_DIR_MASK,值为0x80,将它和bEndpointAddress相与,并结合USB_DIR_IN和USB_DIR_OUT作判断就可以得到端点的方向。使用下面两个定义值表示端点传输方向:

#define USB_DIR_OUT 0 /* to device */

#define USB_DIR_IN 0x80 /* to host */

bmAttributes,属性,总共8位,其中bit1和bit0 共同称为Transfer Type,即传输类型, 00 表示控制,01 表示等时,10 表示批量,11 表示中断。前面的端点号还有端点方向都有配对儿的掩码,这里当然也有,就在struct usb_endpoint_descriptor定义的下面。

/*

* USB types, the second of three bRequestType fields

*/

#define USB_TYPE_MASK (0x03 << 5)

#define USB_TYPE_STANDARD (0x00 << 5)

#define USB_TYPE_CLASS (0x01 << 5)

#define USB_TYPE_VENDOR (0x02 << 5)

#define USB_TYPE_RESERVED (0x03 << 5)

wMaxPacketSize,端点一次可以处理的最大字节数。如果你发送的数据量大于端点的这个值,也会分成多次一次一次来传输。友情提醒一下,这个字段还是有点门道的,对不同的传输类型也有不同的要求,以后可以再说。

bInterval, USB是轮询式的总线,这个值表达了端点一种美好的期待,希望主机轮询自己的时间间隔,但实际上批准不批准是host的事。不同的传输类型bInterval也有不同的意义,以后碰到各个实际的传输类型也可以再说。

usb驱动开发6之端点描述符的更多相关文章

  1. usb驱动开发8之配置描述符

    前面分析了usb的四大描述符之端点描述符,接口描述符(每一个接口对应一个功能,与之配备相应驱动),下面是看配置描述符还是看设备描述符呢??我们知道,设备大于配置,配置大于接口,接口可以有多种设置. 我 ...

  2. usb驱动开发7之接口描述符

    前面struct usb_interface里表示接口设置的struct usb_host_interface被有意的飘过了,咱们在这节主要讲讲这个结构体,同样在include/linux/usb.h ...

  3. USB驱动开发大全【转】

    本文转载自:http://www.360doc.com/content/12/0504/19/8363527_208666082.shtml 编写USB驱动程序步骤:1所有usb驱动都必须创建主要结构 ...

  4. usb驱动开发9之设备描述符

    前面分析了usb的四大描述符之端点描述符,接口描述符(每一个接口对应一个功能,与之配备相应驱动),配置描述符,最后分析设备如何包括这些描述符.首先记住,在usb的世界里,设备大于配置,配置大于接口,接 ...

  5. STM32 USB设备描述符、配置描述符、端点描述符含义

    查了一整天的资料,自己把不懂的全部试了一遍 一下是程序以及注释 /* USB设备描述符*/ const uint8_t CustomHID_DeviceDescriptor[CUSTOMHID_SIZ ...

  6. HarmonyOS USB DDK助你轻松实现USB驱动开发

    HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...

  7. usb驱动开发18之设备生命线

    现在已经使用GET_DESCRIPTOR请求取到了包含一个配置里所有相关描述符内容的一堆数据,这些数据是raw的,即原始的,所有数据不管是配置描述符.接口描述符还是端点描述符都挤在一起,所以得想办法将 ...

  8. usb驱动开发14之设备生命线

    直接看代码吧. /*-------------------------------------------------------------------*/ /** * usb_submit_urb ...

  9. usb驱动开发12之设备生命线

    函数usb_control_msg完成一些初始化后调用了usb_internal_control_msg之后就free urb.剩下的活,全部留给usb_internal_control_msg去做了 ...

随机推荐

  1. JAVA基础学习day14--集合一

    一.集合的出现 1.1.集合简述 面向对象语言对事物的体现都是以对象形式,为了方便对多个对象的操作,就对象对象进行存储,集合就是存仪储对象最常用的一种试 1.2.数组和集合都是容器 数组也存对象,存储 ...

  2. java 进制转换

    class Dec2XXX { public static void main(String[] args) { toBin(6); toHex(6); toOct(6); } /*10to2*/ p ...

  3. androidannotation study(1)---Activity, Fragment,Custom Class & Custom View

    androidannotation 是github上的一个开源项目. 主要是注解机制,可以改善android写代码的效率. Activity 使用 1.@EActivity 注解 可想而知,servi ...

  4. android studio annotation 配置过程

    参考了好些配置,发现总有这样,那样的问题. 环境:androidstudio 1.5 preview 2 sdk 6.0 1.首先新建一个android项目. 过程略 2.配置project的buil ...

  5. windows 2008 r2 下面搭建 iis+sql server +php5.6 环境遇见的一些问题记录一下

    由于web服务器以前在iis下部署有几个网站,现在这个项目开发又是用的php,本来php+mysql+iis应该很简单随便在网上能搜索出来很多,但是,由于以前那个web网站是用的sqlserver数据 ...

  6. 设计模式 --- 单例模式(Singleton)

    一.概念 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如 ...

  7. jQuery 安装方法

    在WEB中使用jQuery有两种安装(引入)方式. 1.直接下载jQuery包放置到工程中,然后用js导入的方式连接到WEB页面中 2.利用CDN的公网资源,如百度.新浪等. 访问 http://cd ...

  8. MongoDB学习笔记——聚合操作之聚合管道(Aggregation Pipeline)

    MongoDB聚合管道 使用聚合管道可以对集合中的文档进行变换和组合. 管道是由一个个功能节点组成的,这些节点用管道操作符来进行表示.聚合管道以一个集合中的所有文档作为开始,然后这些文档从一个操作节点 ...

  9. SQL基础(1)-创建及修改表

    1. 建表语句 CREATE TABLE fdh_client_info ( id varchar2(50) primary key, name varchar2(30) not null, sex ...

  10. Watchdog

    一.简介 Watchdog主要用于监视系统的运行,Linux内核不仅为各种不同类型的watchdog硬件电路提供了驱动,还提供了一个基于定时器的纯软件watchdog驱动. 驱动源码位于内核源码树dr ...