USB协议及认知

1.USB的拓扑结构决定了主机控制器就是最高统帅,没有主机控制器的要求设备永远不能主动发数据。所以主机控制器在USB
的世界里扮演着重要的角色,它是幕后操纵者。

2.数据包的发送, 这个过程包含很多信息, 一切的工作都是主机控制器给我们做的.
(USB Host控制器主要介绍这两种, EHCI, OHCI). EHCI主要针对高速的USB设备; 如果要操作全速和低速可以考虑OHCI。

3.USB 设备和主机的接口就是USB Host,一个主机可以支持多个USB Host. 控制所有的USB设备的通信。

4."控制器的主要工作是什么? 把数扔出去,把数拿回来。绝对不应该偷偷加工数据."

5.主机控制器控制总线上包的传输,使用1ms(全速/低俗)或125us(高速)的帧。在每帧的开始时,主机控制器产生一个帧开始包(SOF: Start of Frame)。

6.SOF包用于同步帧的开始和跟踪帧的数目。包在帧中被传输,或由Host到Device(out事务),或由Device到Host(in事务)。传输总是
由Host发起(轮询传输)。回此每条USB总线只能有一个Host。每个包的传输都有一个状态阶段同(同步传输除外),数据接收者可以
在其中返回ACK(应答接收),NAK(重试),STALL(错误条件)或什么也没有(混乱数据阶段,设备不可用或已经断开)。

7.主机控制器驱动(driver)的工作:
让主机控制器工作起来,发挥它的潜力。 让控制器发数据、收数据 。主机控制器主要包含以下几步:
7.1 按照主机控制器的要求组织结构体
7.2 将结构体在合适的时间、放在合适的地方
7.3 trigger(触发)
7.4 等待完成信号
主机控制器Driver开发过程就是上面这几步。

8.一个port 多个主人,OHCI的角色是companion,伴侣。地位低点。EHCI处理不了再给它处理。

9.关于端口逻辑这块需要特别注意,Driver设计者要注意:当前端口正在属于谁。当端口被OHCI所拥有时,你插入个高速设备怎么办?
没办法!在没有插入设备时,就不应该让OHCI拥有这个端口。只有EHCI控制器才能识别出设备是全速、高速还是低速。

10."别人经验: 未亲自测试: 一个端点号可同时设置为输入、输出的!只有Endpoint 0可以双向传输,因为它是控制端口。其它端口都是单向的."

11.把一个Linux设备当作USB从设备应该怎样写驱动?
如果选择较常用的设备类,如 HID、CCID、Mass Storage,就不用写 PC 端的驱动程序。
还有一种常见的做法,将设备端写成 CDC 类 USB 转串口模式,PC 端只要实现串口通讯就可以了。
一般来说,设备端必须要有硬件实现的 USB 接口。通过它,依照 USB 规范写通讯协议处理代码就可以了。

12.USB设备包括配置(configuration)、接口(interface)和端点(endpoint),USB设备绑定到接口上,而不是整个USB设备。

13."USB通信最基本的形式是通过端点(USB端点分中断、批量、等时、控制四种,每种用途不同);USB端点只能往一个方向传送数据,"

14.我们可以这样认为:设备通常具有一个或者更多的配置,配置经常具有一个或者更多的接口,接口通常具有一个或者更多的设置,接口没有或具有一个以上的端点。

15.驱动程序把驱动程序对象注册到USB子系统中,稍后再使用制造商和设备标识来判断是否已经安装了硬件。

16.USB核心使用一个列表(是一个包含制造商ID和设备号ID的一个结构体)来判断对于一个设备该使用哪一个驱动程序.

17.在写一个设备驱动程序之前,我们还要了解以下两个概念:模块和设备文件。模块:是在内核空间运行的程序,实际上是一种目标对象文件,
没有链接,不能独立运行,但是可以装载到系统中作为内核的一部分运行,从而可以动态扩充内核的功能。模块最主要的用处就是用来实现设备驱动程序。

18.Linux下对于一个硬件的驱动,可以有两种方式:直接加载到内核代码中,启动内核时就会驱动此硬件设备。另一种就是以模块方式,编译生成一个.ko文件
(在2.4以下内核中是用.o作模块文件,我们以2.6的内核为准,以下同)。当应用程序需要时再加载到内核空间运行。所以我们所说的一个硬件的驱动程序,
通常指的就是一个驱动模块。

19.设备文件:对于一个设备,它可以在/dev下面存在一个对应的逻辑设备节点,这个节点以文件的形式存在,但它不是普通意义上的文件,它是设备文件,
更确切的说,它是设备节点。其中指定了主设备号和次设备号。主设备号表明了某一类设备,一般对应着确定的驱动程序;次设备号一般是区分不同
属性;例如不同的使用方法,不同的位置,不同的操作。这个设备号是从/proc/devices文件中获得的,所以一般是先有驱动程序在内核中,才有设备
节点在目录中。

20.写一个USB的驱动程序最基本的要做四件事:驱动程序要支持的设备、注册USB驱动程序、探测和断开、提交和控制urb(USB请求块)(当然也可以不
用urb来传输数据,下文我们会说到)。

21.USB系统架构实际就是包括USB主控制器,USB HUB总线,USB 设备3部分,而域、包、事务、传输类型、描述符与数据流模型把它们联系组成一个整体,
保证它们之间的正常运作。

22.USB设备系统: USB设备按功能分为两部分:集线器(Hub)和功能部件。

23.USB主机和USB设备之间的数据传输共有四种类型:控制传输、批量传输、中断传输和同频传输。
与之对应,USB主机和USB设备之间有四种事务:控制事务、批量事务、中断事务和同步事务。
USB协议中共定义了以下四种描述符:设备描述符; 配置描述符; 接口描述符; 端点描述符.

24. 每个设备至少支持控制端点0。USB设备应该支持三类端点:控制端点、输入端点和输出端点。

======================================================================================================================
1.通用串行总线(USB,Universal Serial Bus)是一种非常实用的通信接口,其应用日益广泛。有三种方法可以使运行Linux操作系统的嵌入式系统支持USB接口,
本文将对这三种方法逐一进行介绍。

2.基于Linux的USB设备与USB主机一般有以下三种通信方式:1.一些功能最完备结构也最复杂的设备采用用户定制内核模块来实现在标准USB总线上运行复杂的
高级协议,而由USB主机上相应的用户驱动程序和应用来完成连接。2.另一些基于Linux的USB设备则利用USB总线来实现与主机上所运行的某个应用的简单
的点对点串行连接。主机上的应用虽然利用了主操作系统所提供的USB编程接口,但表面看来却似乎是在通过一个典型的串口进行通信。3.最后,还有些
设备以主计算机作为网关,将USB设备连接到办公局域网或互联网上,从而使USB设备看起仿佛构成了一个以太网。这种方法专业性较强,但通常可行,是
主机驱动程序使该方法成为可能。

在这三种方法中,您可以根据预留给开发的时间长短和期望USB接口在嵌入式应用中所扮演的角色来决定选用那一种方法比较恰当。为了帮助您做出正确的
选择,下一节将向您介绍这三种方法分别应用于基于Linux的USB设备时的情况,但首先让我们对USB接口做一个大致介绍。

3.Linux 上的USB驱动程序包含两类:
1.Linux操作系统中包含了USB主机控制器的驱动程序,因而USB键盘、数码相机以及其他一些USB设备都可以在一个运行Linux操作系统的桌面工作站上使用。
2.Linux中还包含了一组USB设备控制器的驱动程序,有了这些控制器驱动程序,基于Linux的嵌入式系统就能利用USB接口来与主计算机(运行Linux或其他操作系统)通信。

4.大多数USB通信的实现过程都是双端的。主机利用一个内核模块或驱动程序来与USB设备通信,而USB设备则通过其自身的驱动程序来与主机通信。根据主机
和USB设备所采用的通信风格的不同,驱动程序可以很简单明白,也可以很复杂,很具挑战性。

5."重点,重点,重点,!!!-----》USB设备端通信过程"

5.1 USB设备端通信过程
1. 通过编写内核模块添加USB接口。
2. 向一个基于Linux的设备中添加USB接口的第一种方法是编写一个用户定制的Linux内核模块,这也是可实现最完备功能的一种做法。采用这种方法时通常
需要针对主机的操作系统(Windows, Linux等)开发相应的驱动程序。
3. 一旦在设备中实现了用户定制的内核模块,就可以使该设备完成相当复杂的功能,例如仿真一个文件系统,从而允许嵌入式应用将其USB主机当作一个远程存
储设备。除此以外,采用这种方法之后,设备还可以具备存储转发(store-and-forward)的功能,因而能够在与USB主机的连接建立之前对来自嵌入式应用的
数据流进行缓冲。

5.2 USB主机端通信过程
1.有些很好的主机端USB驱动程序的例子是随主流Linux操作系统的发布而提供的,位于The Linux Kernel Archives (kernel.org)发布的原始内核源代码中。其中,
Handspring Visor 模块(drivers/usb/serial/visor.c)是一个编写得更清晰,也更易理解的模块,它同时也是USB 主机端模块(drivers/usb/usb-skeleton.c)的模板。


6."重点,重点,重点,!!!-----》利用USB实现高速串行通信"

6.1 USB设备端通信过程;
1. 为了达到最实用的效果,我们可以将USB总线简单地看作一个高速串口,然后,在一些嵌入式设备和应用中,我们就可以用USB接口来模拟串口。StrongARM处
理器的Linux内核就提供了一个名为usb-char的USB设备驱动程序,它所完成的恰好就是用USB模拟串口的功能。
2. 当需要与USB 主机通信时,Linux操作系统中的USB设备应用只是简单地打开一个与其usb-char设备节点的连接(连接类型为字符型,major number 为10, minor
为240),然后就开始读写数据。在与USB 主机的连接建立之前,read()和write()操作均返回一个错误信息。一旦连接建立好,并且设备查询完成之后,USB
接口就开始象一个点对点的串口一样与主机进行通信。
3. 这种进行USB数据传送的方法非常简单有效,因而usb-char设备模块发布之后一直很受欢迎。而且,该模块还为通过其他方法进行USB通信提供了一个参考。

6.2 USB主机端通信过程:
1. 对于运行Linux操作系统的USB 主机,与usb-char相应的USB 主机模块叫做usbserial。大多数Linux版本中都包含了该模块,但它并不总能自动加载。通常应
在主机与USB设备之间的连接建立之前利用modprobe 或insmod加载该模块。
2. 笔者并未考虑在运行Win32或其他类型操作系统的主机上已有类似usbserial的模块。但用于这些主机上的任何USB驱动程序,只要能够进行bulk-in 和
bulk-out数据传输,就很可能是一个近乎完整的驱动程序,只需进行一定的产品调整,并添加与产品绑定的厂商ID。
3.Linux主机上还有另一种类似usbserial模块的库,叫做libusb (参见libusb.sourceforge.net)。该库通过低级的内核系统调用而不是通过usbserial模块来
完成USB数据传输,因而在Linux kernel版本上更容易设置和使用。同时,该库还能提供大量实用的调试功能,十分利于对USB链接上运行的复杂的通信协议进行调试。


7."重点,重点,重点,!!!-----》利用USB实现以太网连接"

7.1 USB 设备端通信过程
1. 如果利用USB连接来实现高速串口并非您所希望,那么您还可以将所有USB连接用作一个以太网。不论在主机端还是在设备端,Linux均有模块能实现这一功能。
iPAQ(掌上电脑)的Linux内核就独一无二地采用了这种通信策略,因为iPAQ硬件中既没有可访问的串口也没有专门的网络接口。
2. StrongARM Linux内核中,有一个叫做usb-eth的模块(arch/arm/mach-sa1100/usb-eth.c),它利用USB作为物理媒介,模拟出一个虚构的以太网设备。一旦这种
网络接口创建起来之后,就可以为它分配IP地址,并且外部环境均将其作为一个普通的以太网硬件对待。一旦USB 主机连接建立起来,usb-eth模块就允许USB设备
“浏览”因特网,ping其他的IP地址,甚至通过DHCP、HTTP、NFS或者远程网“交谈”,以及收发电子邮件。简而言之,任何能够在真正的以太网接口上运行的应用都可
以原封不动地在usb-eth 上运行,因为这些应用无法识别它们所使用的其实并非真正的以太网硬件。

7.2 USB 主机端通信过程
1. 相应的,在运行Linux操作系统的主机一端,可用来在USB上实现以太网连接的内核模块叫做usbnet。安装了该模块之后,一旦主机与USB设备的连接建立起来,
它就会创建一个虚拟的以太网接口,在主机一端的内核模块以及用户应用看来,这个虚拟的接口与真正的以太网接口别无二致。主机端的应用可以通过拼一个USB
设备的IP地址来检查该设备是否已经连上,如果拼操作成功,那么就表示设备已经连接成功。
2.最近出现了一种针对Win32主机的usbnet风格的驱动,叫做Bahia网络驱动,关于该驱动的详细信息请访问www.bahia21.com/download.htm。

原文地址:https://www.cnblogs.com/yyx1-1/p/6543665.html