透彻理解USB总线应用之枚举
Hello,大家好,今天我们来讨论一下USB总线中的枚举(Enumeration),首先简单介绍一下USB系统的基本架构,它由USB主机、USB设备与USB电缆(本文忽略它)组成,如下图所示:
最常见的主机就是电脑了,现在很多有USBOTG(On-The-Go)功能的手机也可以做主机,无需过多赘述。USB设备实在太多了,例如,手机、MP4、U盘、移动硬盘、打印机、扫描仪等等,当然,作为工程师的你还可能会购买其它一些使用USB接口的仪器,例如逻辑分析仪,示波器等等。无论USB设备的具体形式是怎么样的,按照功能都可以分为两大类,其中之一就是USB功能设备。刚刚提到的USB设备都属于这类,它们都各自提供了一些特定的功能,例如,U盘就是存储数据,示波器就是采集数据。
另外一类USB设备就是USB集线器(USB Hub),它的功能与网络集线器相同,把一个USB接口扩展多个USB接口。例如,学校一个寝室有很多人,每个人都有一台电脑,但网线只有一根,怎么办?用网络集线器就可以解决这个问题,如下图所示
我们只需要特别留意:USB系统的数据或指令传输都是由主机启动的,USB设备只是根据主机的要求进行被动响应。在任意时刻,USB系统仅允许存在一个USB主机。
------------------------------------------------------------------------------------------------------
好的,现在有一个问题得先弄明白:为什么在电脑同一个USB接口依次插入鼠标、键盘或其它USB设备,电脑都能够正确地识别它的功能呢?这就是枚举的功劳。为了形象地理解枚举,我们来看一个面试对话场景:
------------------------------------------------------------------------------------------------
面试官:我看你的简历上说对三极管有比较深入的了解,那么请形象地讲讲三极管的放大原理。
你:好的,你可以把三极管的三个区比作三个国家,然后…..
面试官:这个故事是你自己总结的吗?
你:不瞒你说,是通过微信公众号《电子制作站》学来的。
面试官莞尔一笑:是嘛 ,难怪我怎么觉得这么熟悉,那另外一篇关于上下拉电阻的文章你看过没有?
你:必须的呀!
面试官:那你说说拉电流与灌电流的区别?
你:拉与灌只是电流方向不同而已,具体到电路结构,就是…..
…..
面试官:好的,我觉得你的水平确实不错,至少基础非常扎实,不愧是关注《电子制作站》微信公众号的老粉,值得信赖….
….
然后你就顺利进入了该公司,拿到了一个代表你是公司员工的工牌….
----------------------------------------------------------------------------------------------------------
在以上面试过程中,面试官首先提出一个问题,根据面试者的反馈后再跳到另一个知识点,依此循环,继而完成全面考察面试者业务水平的目的,最后才决定是否符合公司的录用标准,这其实就是一个枚举的过程。在面试的场景中,你就是USB设备,面试官就是USB主机,所以简单的说,枚举就是“识别”的同义词。
同样的道理,当USB鼠标插入到电脑时,电脑也需要询问关于它的一些信息,以确定它到底是个什么东东。电脑当然是不能说话的,它只是会发送一些命令,USB设备必须对这些命令进行响应,不然枚举就会失败(问你话咋一声不吭呢?面试失败!)。当然,USB设备必须进行正确响应,乱来也会导致枚举失败(回答问题怎么牛头不对马嘴呢?面试失败!)。当然,即便枚举成功了,也不一定代表USB设备能用,枚举成功只是万里长征的第一些。(你小子面试时能说会道,做起实事来却完全不顶用,明天卷铺盖滚蛋吧,赶紧从我眼前消失!失败中的失败!!)
概括来讲,如果我们开发自己的USB设备,关键的两个步骤是必须进行的。
其一:让USB设备按照USB协议正确回应主机的命令,以成功完成枚举。
其二:在枚举成功后,把数据按正确的格式进行传输。
有些人想:虾米?还要响应命令呐,粗看了一下,貌似很复杂,玩不了,回家洗洗睡了!哈哈,必须得打击你一下,USB底层的实现确实有点复杂,但幸运的是,通常厂商都会把底层核心的东西做好了打包成库,我们只要修改一些应用方面的数据即可。也就是说,如果你只是使用USB总线传输数据,底层的东西你没机会(也不需要)去修改。
那到底需要修改什么才能成功完成枚举呢?其实道理跟我们工程师做项目一样!例如使用单片机控制新的器件时,第一步需要做的就是了解新器件的基本原理,包括通讯时序、寄存器的定义、硬件电路的连接要求等等。器件厂家为了方便用户使用,通常都会准备好相应的数据手册(datasheet),它包含了用户应用该器件的所有信息。
同样的道理,如果把你当成一台电脑,当USB鼠标插入USB接口时,你又是怎么知道它是鼠标,而不是键盘或其它设备呢?很明显,你(电脑)也需要数据手册之类能够描述插入设备所有信息的媒介,对不对?USB协议中定义的描述符(descriptor)就是这个目的。
描述符在C语言实现层面通常就是结构体(Structure),应用上就是多个有一定关联的信息的集合体。例如,我要定义一个员工的描述符,它应该包含姓名、性别、年龄、工号等等信息,如下所示:
也就是说,USB描述符就是用来描述相应的USB设备具体是什么,有什么特点,能做什么(是不是真的能做就不知道了),所以在源代码编程自定义USB设备时,我们最先开始的工作就是:找到厂商提供的固件(firmware)或示例程序中描述符对应的位置,再根据USB协议的规定进行合适的修改。如果修改正常,厂商提供的固件会自动根据主机发送的命令提交你修改描述符信息,这样主机才能正确识别(会提示你插入了新设备,可以正常使用了),至于它具体能不能起到什么功能,就是枚举成功之后再去讨论的事了,先通过面试这一关才能发挥咱们的才干呐!
USB协议定义了很多描述符,结构也远比前面的员工信息要复杂的多,我们将在下一篇文章中继续讨论,么么哒~~
透彻理解USB总线应用之枚举的更多相关文章
- Linux驱动之USB总线驱动程序框架简析
通用串行总线(USB)是主机和外围设备之间的一种连接.USB总线规范有1.1版和2.0版,当然现在已经有了3.0版本.USB1.1支持两种传输速度:低速为1.5Mbps,高速为12Mbps.USB2. ...
- EDK II之USB总线驱动的实现框架
本文简单介绍一下UEFI中USB驱动的实现框架: 下图是USBD向上层驱动提供的接口: 1.从图中我们可以看出,USBDI的实现主要通过调用HCDI实现 和 访问USB_INTERFACE结构体(该结 ...
- Linux下的USB总线驱动(一)
版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127 一.USB理论 1. USB概念概述 USB1.0版本速度1.5Mbps(低速USB) USB1 ...
- 回调函数透彻理解Java
http://blog.csdn.net/allen_zhao_2012/article/details/8056665 回调函数透彻理解Java 标签: classjavastringinterfa ...
- USB总线介绍
•USB 1.0出现在1996年的,速度只有1.5Mb/s1998年升级为USB 1.1,速度也提升到12Mb/s,称之为”full speed” •USB2.0规范是由USB1.1规范演变而来的.它 ...
- USB总线标准
1.USB总线类型: OHCI(Open Host Controller Interface)是支持USB1.1的标准,但它不仅仅是针对USB,UHCI(Universal Host Controll ...
- linux usb总线驱动(一)
目录 linux usb总线驱动框架 USB 介绍 传输类型 控制器接口 2440接口 基本流程 alloc_dev choose_address hub_port_init usb_get_devi ...
- 透彻理解Spring事务设计思想之手写实现
前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),D ...
- Spark2.1.0——深入理解事件总线
Spark2.1.0——深入理解事件总线 概览 Spark程序在运行的过程中,Driver端的很多功能都依赖于事件的传递和处理,而事件总线在这中间发挥着至关重要的纽带作用.事件总线通过异步线程,提高了 ...
随机推荐
- 记一次 .NET 某HIS系统后端服务 内存泄漏分析
一:背景 1. 讲故事 前天那位 his 老哥又来找我了,上次因为CPU爆高的问题我给解决了,看样子对我挺信任的,这次另一个程序又遇到内存泄漏,希望我帮忙诊断下. 其实这位老哥技术还是很不错的,他既然 ...
- [Linux] Linux命令行与Shell脚本编程大全 Part.1
终端 tty(teletypewriters):控制台,早期计算机通过电传打字机作为输入设备 Console:控制台终端,即显示器 Ctrl+Alt+T:图形界面终端 Ctrl+Alt+F2:tty2 ...
- 好好好重要常用必备linux命令
查看当前目录下文件个数: $find ./ | wc -l 以上这个命令用到的频率如此之高,以至于我们需要为它建立一个快捷命令方式: 在.bashrc 中设置命令别名: alias lsl='ls - ...
- Gtkperf介绍
Gtkperf使用说明一.Gtkperf介绍GtkPerf是一种应用程序设计,测试基于GTK +的性能.问题的关键是建立共同的测试平台,运行预先基于GTK +工具(开放comboboxes ,切换按钮 ...
- shell进阶之tree、pstree、lsof命令详解
一.tree命令详解: 主要功能是创建文件列表,将所有文件以树的形式列出来 -a 显示所有文件和目录. -A 使用ASNI绘图字符显示树状图而非以ASCII字符组合. -C 在文件和目录清单加上色彩, ...
- Java public 和 private 访问修饰符
何为封装 从事面向对象编程的 Java 程序员,不可能不知道封装,它是面向对象编程的精髓,非常重要. 那什么是封装?字面意思就是把摆在外面的东西包起来. 一句话,封装就是对外隐藏内部细节. 那为何要封 ...
- Markdown 使用文档
MarkDown 简介 Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的语法十分 ...
- MyBatis 高级查询之一对一查询(九)
高级查询之一对一查询 查询条件:根据游戏角色ID,查询账号信息 我们在之前创建的映射器接口 GameMapper.java 中添加接口方法,如下: /** * 根据角色ID查询账号信息 * @para ...
- C# DeepClone 深拷贝
常规利用反射进行克隆 public static T CloneModel<T>(T oModel) { var oRes = default(T); var oType = typeof ...
- IDEA debug ConcurrentLinkedQueue时抽风
1. 介绍 如标题所见,我在使用IDEA debug ConcurrentLinkedQueue的Offer方法时,发生了下面的情况. 代码如下: ConcurrentLinkedQueue<s ...