可以使用USB2.0接口进行全双工通讯么,双方都可以主动发送么?
2017-11-12 18:47
232 查看
origin: https://www.zhihu.com/question/22134264
时国怀
RTOS开发
USB 2.0协议要求设备必须一个是Host另一个是Device,所有的请求都必须由Host发起,Device自己决定是否要给予正确的回应。有一个特例就是OTG,理论上USB-OTG是允许Host和Device互相切换的,但驱动特别复杂,也没有明确的设备可以在连接的状态下动态切换。
所以你如果两块ARM芯片用USB通信,就必须要一个做Host,另一个做Device,Host负责供电和发起请求。Device不可以主动发起请求。不要被协议规范的字眼迷惑,Interrupt传输也是由Host发起的,不是Device发起的。
如果为了简单起见,建议用串口,RS232既简单由好用。一个简易的USB协议栈也要几十K的binary code,折合代码也得上千行了。
------------------------补充------------------------
USB2.0是半双工传输,总线上的信号可以理解为:主机发送请求->设备回应请求,这种模型。
USB2.0 EHCI控制器需要设置一堆控制器,需要设置伴侣芯片(1.1控制器)或者embinedTT(大概叫这个名字),要设置传输队列,USB协议栈不适合简单通信模型,USB驱动部分比网卡驱动复杂很多倍,虽然网络协议栈很大,但网卡驱动很简单,一个C源文件,几百行就可以搞定,但一个USB控制器驱动需要几个C源文件,上千行代码。
---------------------再次补充---------------------
不建议用USB协议栈的原因是:
1、传输距离短,USB协议规范是5米,5米的话RS232也是满足的,相比以太网100米来说5米简直太短了。
2、带宽一般,虽然2.0号称是480Mbps,实际能利用的带宽大概只有80%左右,并且还要进行封装,如果换成千兆以太网,性能会好很多。
3、协议栈太复杂,相关文档很难找到。对比而言网络控制器的开发就简单多了。
关于开发协议栈,我多说点:
USB开发分为3部分:控制器开发、协议栈开发、驱动开发。其中最难的部分是控制器开发,USB2.0是传输协议规范,并不是控制器技术规范。而控制器本身又需要大量代码,以EHCI控制器为例,仅仅这个驱动,写出来就够难受的了,无数的寄存器,还要在内存里建立复杂的数据结构才能完成传输。而激活了控制器是不够的,你需要在控制器驱动之上编写支持USB2.0规范的协议栈代码,包括URB支持、USBD支持、各种描述符的解析等等,这些比网络协议栈复杂多了。并且网络协议栈的RFC很好找,中文的也很好找,但USB的中文规范翻译的都不太好。
当你搞定了EHCI和USB2.0传输,那么你还要在你的协议栈之上增加设备驱动,这个驱动就简单多了,但要根据你的传输模型来设计,比设计一个TCP传输模型要复杂多了。
以上工作全完成,需要几万行代码,编译完成以后需要200K-1M左右的内存来运行。
然后,一切都完成了吗?不,你只完成了一半。
USB同网络协议栈的区别就是分host协议栈和device协议栈,二者是完全不同的,因为你是要互连,所以另外一个板子上就要开发device协议栈,device协议栈相对比较轻量级,但同样需要开发成本,一个标准的device协议栈需要50K-200K的运行内存,开发代码应该不少于一万行。
然后,你两个板子就可以互连通信了。
你以为这样就完事了?还没完。
支持device协议栈的板子很少,USB控制器不是对等的,两个EHCI控制器无法互连,而支持device协议栈的设备都不是标准的EHCI控制器,多数情况下这些板子就根本不带有EHCI控制器,这种板子开发USB2.0会更难,因为你根本找不到开发手册,比如一般的MHCI或者SHCI控制器,只有很少很少的资料。而且我就没见过中文的USB Device Stack规范。
那么你想想你的开发成本吧,先要学习标准的USB2.0规范,搞清楚EHCI是怎么回事,然后去研究一些偏门的设备,研究MHCI/SHCI是怎么回事,再在上面分别实现USB Host Stack和Device Stack,之后还要在这之上设计不同的两个通讯用的驱动,需要1M的运行内存,几万行代码,你觉得这样的开发成本可以接受吗?
为什么我建议用网络或者RS232,因为这是对等的协议,两个设备的驱动开发完全一致,区别只是上层的部分的一点点内容,并且资料很多,很容易找到可以移植的代码。
----------------------------------------------------
USB各种规范的规模(全英文):
《Universal Serial Bus Specification Revision 2.0》- USB2.0协议规范,650页
《Enhanced Host Controller Interface Specification for Universal Serial Bus》 - EHCI规范,155页
《Universal Host Controller Interface (UHCI) Design Guide》 - USB UHCI(1.1)规范,47页
《On-The-Go Supplement to the USB 2.0 Specification》 - OTG规范,53页
还有若干class device规范我就不列出来了,MHCI的规范我没有找到,应该也不会太少,相比网络协议栈的RFC,这方面的中文资料实在是太少了。
编辑于 2013-12-03
知乎用户
找不到用USB的理由。
同一块board上的芯片吗?
还不如直接用GPIO自己写一个协议来得快。
或者GPIO模拟IIC。
不同board,走Ethernet,你要传得远可以把报文发到交换机上,然后电转光,选择太多。
就算是不带系统,IP栈也比USB栈要高效。
需要供电?PoE走起。
抗干扰?USB太不给力了。
编辑于 2013-12-04
Kaiser Li
现代人都是复杂的,要知道并容忍这点。
不知道你的信息量有多大,芯片间通讯,一般都使用SPI 、UART 、IIC。SPI和UART可以实现全双工,但 IIC 不行。 但是IIC(I2C)用的线少。各有优缺点,USB的好处在于热拔插和使用范围广,但是真的不适合芯片间通讯。
编辑于 2013-12-02
时国怀
RTOS开发
USB 2.0协议要求设备必须一个是Host另一个是Device,所有的请求都必须由Host发起,Device自己决定是否要给予正确的回应。有一个特例就是OTG,理论上USB-OTG是允许Host和Device互相切换的,但驱动特别复杂,也没有明确的设备可以在连接的状态下动态切换。
所以你如果两块ARM芯片用USB通信,就必须要一个做Host,另一个做Device,Host负责供电和发起请求。Device不可以主动发起请求。不要被协议规范的字眼迷惑,Interrupt传输也是由Host发起的,不是Device发起的。
如果为了简单起见,建议用串口,RS232既简单由好用。一个简易的USB协议栈也要几十K的binary code,折合代码也得上千行了。
------------------------补充------------------------
USB2.0是半双工传输,总线上的信号可以理解为:主机发送请求->设备回应请求,这种模型。
USB2.0 EHCI控制器需要设置一堆控制器,需要设置伴侣芯片(1.1控制器)或者embinedTT(大概叫这个名字),要设置传输队列,USB协议栈不适合简单通信模型,USB驱动部分比网卡驱动复杂很多倍,虽然网络协议栈很大,但网卡驱动很简单,一个C源文件,几百行就可以搞定,但一个USB控制器驱动需要几个C源文件,上千行代码。
---------------------再次补充---------------------
不建议用USB协议栈的原因是:
1、传输距离短,USB协议规范是5米,5米的话RS232也是满足的,相比以太网100米来说5米简直太短了。
2、带宽一般,虽然2.0号称是480Mbps,实际能利用的带宽大概只有80%左右,并且还要进行封装,如果换成千兆以太网,性能会好很多。
3、协议栈太复杂,相关文档很难找到。对比而言网络控制器的开发就简单多了。
关于开发协议栈,我多说点:
USB开发分为3部分:控制器开发、协议栈开发、驱动开发。其中最难的部分是控制器开发,USB2.0是传输协议规范,并不是控制器技术规范。而控制器本身又需要大量代码,以EHCI控制器为例,仅仅这个驱动,写出来就够难受的了,无数的寄存器,还要在内存里建立复杂的数据结构才能完成传输。而激活了控制器是不够的,你需要在控制器驱动之上编写支持USB2.0规范的协议栈代码,包括URB支持、USBD支持、各种描述符的解析等等,这些比网络协议栈复杂多了。并且网络协议栈的RFC很好找,中文的也很好找,但USB的中文规范翻译的都不太好。
当你搞定了EHCI和USB2.0传输,那么你还要在你的协议栈之上增加设备驱动,这个驱动就简单多了,但要根据你的传输模型来设计,比设计一个TCP传输模型要复杂多了。
以上工作全完成,需要几万行代码,编译完成以后需要200K-1M左右的内存来运行。
然后,一切都完成了吗?不,你只完成了一半。
USB同网络协议栈的区别就是分host协议栈和device协议栈,二者是完全不同的,因为你是要互连,所以另外一个板子上就要开发device协议栈,device协议栈相对比较轻量级,但同样需要开发成本,一个标准的device协议栈需要50K-200K的运行内存,开发代码应该不少于一万行。
然后,你两个板子就可以互连通信了。
你以为这样就完事了?还没完。
支持device协议栈的板子很少,USB控制器不是对等的,两个EHCI控制器无法互连,而支持device协议栈的设备都不是标准的EHCI控制器,多数情况下这些板子就根本不带有EHCI控制器,这种板子开发USB2.0会更难,因为你根本找不到开发手册,比如一般的MHCI或者SHCI控制器,只有很少很少的资料。而且我就没见过中文的USB Device Stack规范。
那么你想想你的开发成本吧,先要学习标准的USB2.0规范,搞清楚EHCI是怎么回事,然后去研究一些偏门的设备,研究MHCI/SHCI是怎么回事,再在上面分别实现USB Host Stack和Device Stack,之后还要在这之上设计不同的两个通讯用的驱动,需要1M的运行内存,几万行代码,你觉得这样的开发成本可以接受吗?
为什么我建议用网络或者RS232,因为这是对等的协议,两个设备的驱动开发完全一致,区别只是上层的部分的一点点内容,并且资料很多,很容易找到可以移植的代码。
----------------------------------------------------
USB各种规范的规模(全英文):
《Universal Serial Bus Specification Revision 2.0》- USB2.0协议规范,650页
《Enhanced Host Controller Interface Specification for Universal Serial Bus》 - EHCI规范,155页
《Universal Host Controller Interface (UHCI) Design Guide》 - USB UHCI(1.1)规范,47页
《On-The-Go Supplement to the USB 2.0 Specification》 - OTG规范,53页
还有若干class device规范我就不列出来了,MHCI的规范我没有找到,应该也不会太少,相比网络协议栈的RFC,这方面的中文资料实在是太少了。
编辑于 2013-12-03
知乎用户
找不到用USB的理由。
同一块board上的芯片吗?
还不如直接用GPIO自己写一个协议来得快。
或者GPIO模拟IIC。
不同board,走Ethernet,你要传得远可以把报文发到交换机上,然后电转光,选择太多。
就算是不带系统,IP栈也比USB栈要高效。
需要供电?PoE走起。
抗干扰?USB太不给力了。
编辑于 2013-12-04
Kaiser Li
现代人都是复杂的,要知道并容忍这点。
不知道你的信息量有多大,芯片间通讯,一般都使用SPI 、UART 、IIC。SPI和UART可以实现全双工,但 IIC 不行。 但是IIC(I2C)用的线少。各有优缺点,USB的好处在于热拔插和使用范围广,但是真的不适合芯片间通讯。
编辑于 2013-12-02
相关文章推荐
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- ]使用C#进行点对点通讯和文件传输(发送接收部分)
- (微信API接口开发) 使用HttpWebRequest进行请求时发生错误:基础连接已关闭,发送时发生错误处理
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- Factory 定义一个接口,客户可以使用这个接口创建一个对象.同时,我们还可以控制对那个类进行实例化
- 使用C#进行点对点通讯和文件传输(通讯基类部分+发送接收
- 华数费用350元/年电视费,能够使用技术让所有用户华数接口进行打造成多用户电子自由协议通讯接口。
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- C#中使用SendMessage进行进程通信,可以发送字符串。
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- Spring Boot实战之Filter实现使用JWT进行接口认证 jwt(json web token) 用户发送按照约定,向服务端发送 Header、Payload 和 Signature,
- SSE:服务器发送事件,使用长链接进行通讯
- 使用C#进行点对点通讯和文件传输(发送接收部分)
- [转]使用C#进行点对点通讯和文件传输(发送接收部分)
- 使用SendMessage方法对窗体上的控件进行截图,该方法的思想就是把控件的句柄拿到,对控件发送WM_PAINT消息,并且把希望得到图形对象的句柄当作wParam参数传过去,这样就可以在图形对象得到想要得图形。
- 五星-原型模式常使用于以下场景--而JAVA中的任何类只要实现了Cloneable标识接口,就可以使用clone方法来进行对象的拷贝
- SSE:服务器发送事件,使用长链接进行通讯