如何Step by Step实现USB host-我的实战经验

[复制链接]
 楼主| usb007 发表于 2008-7-22 17:58 | 显示全部楼层 |阅读模式
<br />前些时候做了一个项目,其中要实现USB的功能,包括U盘的读写和使用USB鼠标键盘。经过一段时间的调试终于完工了。现在将一些关键的调试点记下来,一方面大概整理一下自己思路,另一方面希望能给正在做类似工作的兄弟们一些参考,希望对大家能有所帮助。<br /><br />我的系统是linux&nbsp;2.6,USB的主控制器采用了爱普生的S1R72V17,USB的驱动代码由爱普生公司提供。在开始工作之前,我先从爱普生的网站上下载了相关的资料,包括这款芯片的datasheet和硬件设计文档以及软件移植文档。<br /><br />(资料下载网址:http://www.epson.jp/device/semicon_e/product/interface/index.htm)<br /><br />在这个项目的过程中,我的主要工作是完成硬件的设计和调试,并且将爱普生提供的linux&nbsp;2.6的驱动移植到我的系统中。<br /><br />USB的硬件系统设计比较简单(参考下图),通过地址数据总线和CPU相连,另外USB控制器有一个中断信号要接入CPU系统。S1R72V17需要3个不同的电压分别是3.3v,&nbsp;1.8v和5v。另外一部分电路是关于USB的接口电路,包括差分信号线对和过流保护电路。除此之外72v17还需要一个时钟,这个时钟可以由12M的晶体提供也可以由24M或者48M的有源晶振提供。<br />http://space.**/upload/2008/7/22/d649d836-ed9d-4ad3-b9ca-504a7b7dc05f.JPG<br />在硬件电路设计过程中,比较关键的是总线的接法以及差分信号线对的走线。72V17有3种总线访问模式,分别是8bits模式、16bits&nbsp;BE模式以及16bits&nbsp;strobe模式,BE模式需要CPU端提供WBEL和WBEH信号来分别访问高低字节,strobe模式需要CPU端提供WRH和WRL信号来分别访问高低字节。差分信号线对的布线需要注意以下几点:<br /><br />1&gt&nbsp;差分阻抗90欧<br /><br />2&gt&nbsp;DM/DP尽量短,使得信号传输延时保持在1ns以下<br /><br />3&gt&nbsp;两条线必须平行,并且等长<br /><br />4&gt&nbsp;这两条线下面的PCB层,必须是整块地,不能有分割<br /><br />5&gt&nbsp;避免在这两条线附件走线。尤其是高速信号和时钟信号要远离这对线<br /><br />6&gt&nbsp;如果不能一直走直线,那么可以在拐点出走弧线,以减小信号反射<br /><br />7&gt&nbsp;VBUS线必须远离DP/DM<br /><br />8&gt&nbsp;如果信号线有分叉或者线上有其它器件接入,一定要确保匹配的阻抗<br /><br />9&gt&nbsp;信号线上不要打过孔<br /><br />10&gt&nbsp;推荐使用防静电和浪涌的保护器件<br /><br />爱普生的网站上提供了72V17在linux2.6.14下的驱动代码,以及相应的移植手册。由于我的系统恰好就是2.6.17的版本,加上驱动说明手册比较详细,所以软件移植上去没有费太大力气。其中比较关键的是寄存器访问,其它的只要按照移植手册设置就可以了。<br />http://space.**/upload/2008/7/22/47efd230-53c5-41f1-a89b-5ba6758bf6a9.JPG<br />上图是linux下的USB系统的结构框图,USB&nbsp;core&nbsp;和Class层不需要做改动,而爱普生提供的驱动代码就是usb&nbsp;host&nbsp;controller&nbsp;driver层。<br /><br />下面是驱动文件的说明:<br />http://space.**/upload/2008/7/22/f94ab2ee-d83d-4b66-bce6-b0c26999d614.JPG<br />软件的移植工作量并不大,首先需要改动USB的makefile和kconfig。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在driver/usb/host/Kconfig中加入下面配置<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config&nbsp;USB_V17_HCD<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tristate&nbsp;“S1R72V17&nbsp;HCD&nbsp;support”<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;depends&nbsp;on&nbsp;USB<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default&nbsp;Y<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在driver/usb/Makefile中加入下面的内容<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj-$(CONFIG_USB_V17_HCD)+=host/<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj-$(CONFIG_USB_V17_HCD)+=s1r72v17-hcd.o<br /><br /><br /><br />接着需要改动系统配置,在arch/arm/mach-s3c2410/mach-star.c中加入<br /><br />//for&nbsp;EPSON&nbsp;Start<br /><br />static&nbsp;struct&nbsp;resource&nbsp;s1r72xxx_ohci_resources[]&nbsp;=&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[0]&nbsp;=&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.start&nbsp;&nbsp;=&nbsp;0x28000000,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.end&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;0x2c000000,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flags&nbsp;&nbsp;=&nbsp;IORESOURCE_MEM,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[1]&nbsp;=&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.start&nbsp;&nbsp;=&nbsp;IRQ_EINT5,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.end&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;IRQ_EINT5,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flags&nbsp;&nbsp;=&nbsp;IORESOURCE_IRQ,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br /><br />};<br /><br />static&nbsp;u64&nbsp;v17_dma_mask&nbsp;=&nbsp;0xffffffffUL&nbsp;;<br /><br />static&nbsp;struct&nbsp;platform_device&nbsp;epson_ohci_device&nbsp;=&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&quot;s1r72v17&quot;,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;-1,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.dev&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.dma_mask&nbsp;=&nbsp;&v17_dma_mask,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.coherent_dma_mask&nbsp;=&nbsp;0xffffffffUL,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.num_resources&nbsp;&nbsp;=&nbsp;ARRAY_SIZE(s1r72xxx_ohci_resources),<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.resource&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;s1r72xxx_ohci_resources,<br /><br />};<br /><br />//for&nbsp;EPSON&nbsp;End<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />最后要对Linux系统进行配置,使用make&nbsp;menuconfig进行如下配置。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;HCD&nbsp;driver<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device&nbsp;Drivers&nbsp;-&gt<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USB&nbsp;support&nbsp;&nbsp;-&gt<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt*&gt&nbsp;V17_HCD&nbsp;support.<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt*&gt&nbsp;USB&nbsp;Mass&nbsp;Storage&nbsp;support<br /><br />&lt&gtUSB&nbsp;Human&nbsp;Interface&nbsp;Device&nbsp;(full&nbsp;HID)&nbsp;support<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;USB&nbsp;HID&nbsp;Boot&nbsp;protocol&nbsp;driver&nbsp;-&gt<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt*&gt&nbsp;USB&nbsp;HIDBP&nbsp;keyboard(simple&nbsp;boot)&nbsp;support<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt*&gt&nbsp;USB&nbsp;HIDBP&nbsp;Mouse&nbsp;(simple&nbsp;boot)&nbsp;support<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device&nbsp;Driver&nbsp;-&gt<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Block&nbsp;devices<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt*&gt&nbsp;Low&nbsp;Performance&nbsp;USB&nbsp;Block&nbsp;driver<br /><br />&nbsp;http://space.**/upload/2008/7/22/a9509abc-33fb-42f4-8a11-389ab8137e1f.JPG<br /><br />如果寄存器访问没有问题的话就可以进行编译了。<br /><br />OK!&nbsp;将编译好的image文件下到板子上,系统的USB功能就实现了。插上U盘试一试,超级终端将会出现下面的信息。<br /><br />bash-2.05a#&nbsp;hub.c:&nbsp;USB&nbsp;new&nbsp;device&nbsp;connect&nbsp;on&nbsp;bus1/1,&nbsp;assigned&nbsp;device&nbsp;number&nbsp;2&nbsp;usb_get_device_descriptor!!!<br /><br />scsi0&nbsp;:&nbsp;SCSI&nbsp;emulation&nbsp;for&nbsp;USB&nbsp;Mass&nbsp;Storage&nbsp;devices<br /><br />&nbsp;&nbsp;Vendor:&nbsp;Generic&nbsp;&nbsp;&nbsp;Model:&nbsp;USB&nbsp;Flash&nbsp;Drive&nbsp;&nbsp;&nbsp;Rev:&nbsp;%z!Y<br /><br />&nbsp;&nbsp;Type:&nbsp;&nbsp;&nbsp;Direct-Access&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ANSI&nbsp;SCSI&nbsp;revision:&nbsp;02<br /><br />Attached&nbsp;scsi&nbsp;removable&nbsp;disk&nbsp;sda&nbsp;at&nbsp;scsi0,&nbsp;channel&nbsp;0,&nbsp;id&nbsp;0,&nbsp;lun&nbsp;0&nbsp;SCSI&nbsp;device&nbsp;sda:&nbsp;254720&nbsp;512-byte&nbsp;hdwr&nbsp;sectors&nbsp;(130&nbsp;MB)<br /><br />sda:&nbsp;Write&nbsp;Protect&nbsp;is&nbsp;off<br /><br />Partition&nbsp;check:<br /><br />sda:&lt7&gtusb-storage:&nbsp;queuecommand()&nbsp;called<br /><br />sda1&nbsp;sda2&nbsp;sda3&nbsp;sda4<br /><br />使用mount就可以对U盘进行读写了。除此之外USB鼠标和USB键盘也可以工作。
lpf336 发表于 2008-7-22 18:00 | 显示全部楼层

好贴

  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

1

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部