基于OHCI的USB主机.doc_第1页
基于OHCI的USB主机.doc_第2页
基于OHCI的USB主机.doc_第3页
基于OHCI的USB主机.doc_第4页
基于OHCI的USB主机.doc_第5页
已阅读5页,还剩123页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

这几天,做裸机USB方面!网上代码资料很很少!在51CTO博客上找到了一篇很好的文章,分享给到家!他用的AT91RM9200芯片地址:/393579/328233赵春江的CSDN博客也有关于USB的:/zhaocj/article/details/6083162他用的S3C2440,我也是!以下是我复制下来的,并加了链接!其中,标题文字为网页链接!前面标号为,本word中的链接,希望给各位带来方便!基于OHCI的USB主机我的基于OHCI的USB主机系列文章已经完毕了,我觉得需要建立一个目录,以便需要的人可以迅速找到所需要的文章。本文档的目标就是建立一个该系列文章的目录,可能还会对每个部分进行简单介绍。第一部分 概述 基于OHCI的USB主机的背景介绍与总体构架,使读者了解相应的知识背景。1、基于OHCI的USB主机 前言2、基于OHCI的USB主机 背景介绍3、基于OHCI的USB主机 总体构架第二部分 寄存器读写接口 对OHCI规范所要求的寄存器操作接口。纯寄存器操作,与规范和业务无关。1、基于OHCI的USB主机 寄存器层(说明)2、基于OHCI的USB主机 寄存器(初始化)3、基于OHCI的USB主机 寄存器(传输)4、基于OHCI的USB主机 寄存器(复位)5、基于OHCI的USB主机 寄存器(设备连接)6、基于OHCI的USB主机 寄存器(其它)第三部分 OHCI软件接口 基于OHCI规范的底层控制端口和批量端口读写接口。1、基于OHCI的USB主机 OHCI(端点)2、基于OHCI的USB主机 OHCI(传输描述符)3、基于OHCI的USB主机 OHCI(HCCA)4、基于OHCI的USB主机 OHCI(基本流程)5、基于OHCI的USB主机 OHCI(ED结构)6、基于OHCI的 USB主机 OHCI(ED结构说明)7、基于OHCI的USB主机 OHCI(TD结构)8、基于OHCI的USB主机 OHCI(TD结构说明)9、基于OHCI的USB主机 OHCI(设计思路)10、基于OHCI的USB主机 OHCI(自定义数据结构)11、基于OHCI的USB主机 OHCI(控制端口读数据)12、基于OHCI的USB主机 OHCI(控制端口写数据)13、基于OHCI的USB主机 OHCI(批量端口读数据)14、基于OHCI的USB主机 OHCI(批量端口写数据)15、基于OHCI的USB主机 中断寄存器初始化16、基于OHCI的USB主机 中断向量处理17、基于OHCI的USB主机 中断处理程序第四部分 USB设备管理 当USB设备连接到主机上以后,USB主机对其进行的枚举过程。1、基于OHCI的USB主机 USB设备命令介绍2、基于OHCI的USB主机 USB标准请求3、基于OHCI的USB主机 描述符说明4、基于OHCI的USB主机 USB设备枚举过程5、基于OHCI的USB主机 USB设备描述符数据结构6、基于OHCI的USB主机 USB设备其它数据结构7、基于OHCI的USB主机 USB设备常量定义8、基于OHCI的USB主机 USB设备获取描述符通用函数9、基于OHCI的USB主机 USB设备取得设备描述符10、基于OHCI的USB主机 USB设备取得配置描述符11、基于OHCI的USB主机 USB设备设置地址12、基于OHCI的USB主机 USB设备设置配置值13、基于OHCI的USB主机 USB设备设置接口值14、基于OHCI的USB主机 USB设备枚举15、基于OHCI的USB主机 USB设备端口特性清除第五部分 UFI命令 这是U盘读写操作的底层协议接口。1、基于OHCI的USB主机 UFI命令概述2、基于OHCI的 USB主机 UFI命令 USB Mass Storage Class Bulk-Only Transport协议介绍3、基于OHCI的USB主机 UFI查询命令(Inquiry)4、基于OHCI的USB主机 UFI读容量命令(ReadCapacity)5、基于OHCI的USB主机 UFI读扇区命令(Read10)6、基于OHCI的USB主机 UFI写扇区命令(Write10)7、基于OHCI的USB主机 UFI数据结构18、基于OHCI的USB主机 UFI数据结构29、基于OHCI的USB主机 UFI数据结构310、基于OHCI的USB主机 UFI查询代码11、基于OHCI的USB主机 UFI读容量代码12、基于OHCI的USB主机 UFI读扇区代码13、基于OHCI的USB主机 UFI写扇区代码14、基于OHCI的USB主机 UFI读状态代码15、基于OHCI的USB主机 批量端口复位代码16、基于OHCI的USB主机 UFI命令监视代码第六部分 附录 1、随便说几句 关于USB主机系列2、基于OHCI的USB主机 结束语3、AT91RM9200的USB主机官方例程基于OHCI的USB主机 前言 2009-11-11 17:50:25标签:主机 USB 休闲 OHCI 职场 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/225410 很久以前,大概是前年年底吧,因为公司项目的要求,我做了基于OHCI的USB主机访问U盘的程序,用来把系统中产生的一些数据保存到U盘中。本来做的时候就想把其中的一些经验体会发表的,可是工作实在是太忙,而且也的确有点懒,就一直拖到了现在。做访问U盘的USB主机,网上有很多现成的例子,从硬件到软件。可是绝大多数都是使用了专用的USB主机芯片,譬如ISP1160。还有现成的详细资料,譬如周立功公司出品的ARM嵌入式系统软件开发实例系列教程。但是,凡事都怕这个但是,我们公司项目偏偏不使用USB主机芯片,而是直接利用ARM9200芯片自带的接口直接来完成这个功能。当时遇到的困难简直是多如牛毛,再加上智商又低,光是刚开始通过控制端点发送命令的程序就调试了有几个星期。总的来说,当时调试程序大量的时间是花在了底层的代码调试,真正到了磁盘操作、文件系统操作、业务功能实现的时候,所花费的时间反而还少了。毕竟上层的业务逻辑写好了以后,我还通过自己编写的一个简单的单元测试程序进行了一些测试。痛定思痛,我决定还是把调试过程中那些苦恼的日子里总结出来的一些经验分享出来,希望也能为相关的开发人员节省一点时间。毕竟网上基于OHCI的USB主机访问U盘的资料实在是太少了。我看了看我的那个程序的设计文档,足足有100页,当然这里面也包含了部分的代码,不过好在当时就写下了设计文档,可以让我的这个系列文章轻松不少。基于OHCI的USB主机 背景介绍使用AT91RM9200作为主控CPU,利用该芯片的USB主机接口访问U盘,根据接收的上层命令把相应数据保存到U盘的指定文件上。不使用额外的专用USB控制芯片,要求稳定可靠,效率高,不能影响运行在该CPU上的其它程序。AT91RM9200程序加载后直接运行,没有操作系统。以上就是我做的基于OHCI的USB主机的项目背景,这个项目是做什么的不重要,你可以把它想象成任何项目,关键是这个项目要求使用U盘来保存数据。另外,在我们的项目中没有使用任何一款嵌入式操作系统,所有的程序都运行在同一个主循环中,自己来实现任务调度。说到操作系统,其实很惭愧,自从我开始从事嵌入式系统的开发到现在,十几年了,从来没有用过任何操作系统,所有程序都是裸机直接运行。好处是系统简单,一切都在自己的掌握之中,出了问题可以很快得到解决。坏处是系统的移植性差,换了个系统有很多通用的代码需要重新编写。不过我做的那些嵌入式系统现在看来其实都是蛮简单的,用了操作系统可能反而更麻烦,首先得花时间学习操作系统,而且出了问题还要分析确认这问题是不是操作系统的问题,一旦是操作系统的问题还要想办法怎么规避,算了,有那个时间项目早就做完了。没有操作系统,我的程序更加清晰,没有了驱动程序加载、操作系统API调用,反而可以更加清楚地知道如何基于OHCI规范实现USB主机。在开始讲解之前,我想读者应该具备如下的基础知识:1、 USB接口基础知识;2、 USB层通信协议及基本工作流程;3、 USB主机对USB设备的管理流程;4、 OHCI标准 AT91AM9200对USB接口的操作标准;5、 Mass Storage Protocol 对U盘访问的存储控制协议;6、 UFI Command - U盘读写等操作命令;7、 FAT16文件系统;以上内容有一些我会在需要的时候加以说明,更加详细的内容请自行参考相关资料。下面是我做开发过程中参考的一些资料:1、 Open Host Controller Interface Specification for USB 路径/pub/supportinformation/papers/hcir1_0a.exe说明OHCI接口规范,解压后得到Word文档2、 ARM嵌入式系统软件开发实例(一、二) 路径说明周立功等编著,北京航空航天大学出版社3、 USB 2.0应用系统开发实例精选 路径说明廖济林编著,电子工业出版社4、 Universal Serial Bus Mass Storage Class Bulk-Only TransportUSB Bulk-Only协议规范5、 Universal Serial Bus Mass Storage Class UFI Command SpecificationUSB UFI命令规范6、 Microsoft Extensible Firmware Initiative FAT32 File System SpecificationFAT32文件格式,基础部分与FAT16兼容基于OHCI的USB主机 总体构架 2009-11-16 17:46:35标签:构架 mdash 总体 OHCI USB 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/228153 在我们的系统中,USB主机就是用来对U盘进行读写操作,因此在设计和构架上就完全围绕这个目的而进行。整个系统所涉及到的内容比较多,按照嵌入式系统开发的一般原则,采用层次化的体系结构,将系统按照功能划分为若干层次,每一层完成相应的功能。根据系统的业务需要,系统总体构架如下:9业务应用层8文件操作API层7文件系统层6U盘操作命令接口层5UFI命令层4USB设备管理层3OHCI软件接口层2寄存器读写接口层1硬件层这是一个分层的结构,每层完成自己的功能,层与层之间都是通过接口完成,基本上上层应用都只依赖于下一层,对于个别层的功能实现需要依赖其下的2层,这是考虑实现的方便。下面对每一层的功能进行说明:1、 硬件这是系统最底层,直接完成USB协议处理的硬件部分。2、 寄存器读写接口AM9200支持标准的OHCI接口,提供了访问OHCI寄存器的指针(pUhp)和数据交换区(HCCA),本层对该指针和数据交换区的访问进行封装,对外屏蔽了寄存器读写的细节。以后如果移植到非OHCI的系统上,则可以保持在接口不变,对该层进行重新编码即可。3、 OHCI软件接口根据OHCI标准,数据传输都是通过端点描述符(ED)和传输描述符(TD)这两种数据结构来完成的,在进行传输之前需要对ED和TD进行相应的设置,才可以保证数据传输的正确性,本层对ED和TD的操作进行了封装,提供基于OHCI的数据传输接口。关于ED和TD的详细介绍请参考OHCI规范Open Host Controller Interface Specification for USB。4、 USB设备管理根据USB标准,USB设备都需要提供设备描述符、配置描述符、接口描述符和端点描述符等信息,本层代码提供了取得这些描述符的命令。另外,本层还将这些取得描述符的命令组合起来,完成了USB设备的枚举和检测。5、 UFI命令根据Universal Serial Bus Mass Storage Class Bulk-Only Transport和Universal Serial Bus Mass Storage Class UFI Command Specification规范,完成BulkOnly协议的UFI命令,提供扇区读写命令给上层。6、 U盘操作命令接口一方面封装UFI命令层,提供以扇区为单位的磁盘读写命令,譬如diskRead()、diskWrite()等函数,另一方面,调用UFI命令完成U盘枚举和检测,确定逻辑0扇区的编号,为构建文件系统奠定基础。7、 文件系统完成文件系统初始化,得到相关的参数,提供目录查找、簇操作等接口给上层。8、 文件操作库函数仿照C语言的标准文件库函数,提供一套便于上层业务应用所使用的API函数库,包括文件打开、关闭、读写和定位等。9、 业务应用这就是业务逻辑层了,也就是根据接收的计费信息调用相应的文件操作库函数,完成话单保存的功能。采用这样的层次结构,系统具有良好的可维护性和扩展性,只要CPU支持OHCI标准,则本系统就可以不用修改直接使用,如果CPU不支持OHCI标准,则需要将OHCI层的代码进行修改,保持上层的调用接口不变,就可以完成系统移植了。如果需要扩展支持更多的USB设备,则保持OHCI层基本不变或适当扩展(目前的OHCI层代码只支持控制和批量传输,不支持同步和中断传输),添加新的驱动以及上层应用就可以了。在这一篇文章里,我对我们的系统进行总体上的说明,这是为了避免一上来就阐述各种技术细节,导致一叶障目,不见泰山。在本系列文章中,所有的代码都是按照这个构架原则来编写的,记住这个构架,对于理解代码会有很大的帮助。基于OHCI的USB主机 寄存器层(说明) 2009-11-17 17:15:26标签:主机 寄存器 USB mdash OHCI 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/228813 AM9200支持标准的OHCI规范,在其开发文档中对于USB主机部分的说明干脆就直接说参见OHCI规范。阅读AM9200的例程AT91RM9200-BasicUHP代码,发现系统已经提供了访问OHCI寄存器的指针pUhp,使用该指针就可以访问到所有的OHCI寄存器,因此读写寄存器的操作就是对pUhp指针进行操作。按照面向对象的编程思想,将所有寄存器看作是一个对象,对其操作都是通过接口来完成,在外部不会使用到OHCI寄存器。这样对于嵌入式系统来说,性能上稍微受到一些影响(主要是增加了函数调用的开销),但是代码清晰、易于维护。OHCI规范种提供了很多的寄存器,在U盘处理的程序只使用了其中的一部分,如下: 名称功能HcBulkCurrentED该寄存器用于设置批量列表的当前端点变量的地址HcBulkDoneHeadOHCI文档中没有,使用例程中缺省设置。HcBulkHeadED该寄存器用于设置批量列表的第一个端点变量的地址HccaDoneHead存放最近完成传输的TD变量的地址,用于确定TD对列是否发送完毕。HcCommandStatus该寄存器可被HC用来接收HCD发送的指令,也可反映HC的当前状态。HcControl定义了HC的操作模式。HcControlCurrentED该寄存器用于设置控制列表的当前端点变量的地址HcControlHeadED该寄存器用于设置控制列表的第一个端点变量的地址HcFmIntervalHcFmInterval寄存器包含一个14位值FrameInteral,FI(用于表示一帧之内所占用的比特时间,2个连续的SOFs)和一个15位的值 FSLargestDataPacket,PSMPS(用于表示在没有引发调度溢出下可发送或接收全速最大包大小),FI,PSMPS的推荐值为 0x2EDF和0x2778。HcHCCA用来设置HCCA数据区的地址,由于该寄存器的要求,HCCA变量地址的低8位必须为0,例如变量定义为:_align(256) AT91S_UHP_HCCA HCCA;HcInterruptEnable该寄存器的使能位与HcInterruptStatus寄存器中的中断位相对应,用来控制事件产生的硬件中断。HcInterruptStatus该寄存器提供所有事件状态,并将产生硬件中断。HcPeriodicStartThe HcPeriodicStart register has a 14-bit programmable value which determines when is the earliest time HC should start processing the periodic list.HcRhDescriptorA对根集线器特性进行描述的寄存器。HcRhPortStatus1:2用来控制和报告每个端口上的事件。HcRhStatus该寄存器分为两个部分,低字部分为集线器状态域,高字部分为集线器状态更改域。关于上述寄存器的详细说明,请参考OHCI规范Open Host Controller Interface Specification for USB。想看中文说明的,可以参考ARM嵌入式系统软件开发实例(二)(北京航空航天大学出版社,周立功等编著)中的1.7节,虽然不全,但是也包含了上述大部分寄存器的说明。不过我还是建议仔细阅读OHCI规范,毕竟这是第一手的资料。另外例程AT91RM9200-BasicUHP也很重要,这是第一手的代码,是未来继续深入工作的基础。本文出自 “rainman” 博客,请务必保留此出处/393579/228813基于OHCI的USB主机 寄存器(初始化) 2009-11-19 17:37:13标签:OHCI USB 休闲 职场 主机 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/229673 硬件初始化的操作比较简单,主要代码从例程AT91RM9200-BasicUHP中抄过来,另外增加了中断向量初始化的部分。在AM9200中,USB的中断是基于AIC中断的,因此要设置对应的AIC中断。在此之前要设置OHCI的中断寄存器,代码如下:/* USB主机初始化* return 0 - 成功*/short ohciHardInit(void) unsigned int reg; /打开USB主机所使用的时钟 AT91F_UHP_CfgPMC(); AT91C_BASE_PMC-PMC_SCER |= (AT91C_PMC_UHP); / Forcing UHP_Hc to reset pUhp-UHP_HcControl = 0; / Writing the UHP_HCCA pUhp-UHP_HcHCCA = (unsigned int) &HCCA; / Enabling list processing pUhp-UHP_HcControl = 0; / Set the frame interval pUhp-UHP_HcFmInterval = AT91C_FMINTERVAL; pUhp-UHP_HcPeriodicStart = AT91C_PRDSTRT; / Initializing the UHP_HcDoneHead pUhp-UHP_HcBulkDoneHead = 0x00; HCCA.UHP_HccaDoneHead = 0x0000; / Forcing UHP_Hc to Operational State reg = pUhp-UHP_HcControl; pUhp-UHP_HcControl = 0x80; / Enabling port power pUhp-UHP_HcRhPortStatus0 = 0x00000100; pUhp-UHP_HcRhPortStatus1 = 0x00000100; pUhp-UHP_HcRhDescriptorA = OHCI_HC_RHDESCRIPTORA_NPS; pUhp-UHP_HcRhStatus = 0x00010000; / UDP: Connect a pull-up /调试时发现不设置此寄存器则返回的数据有问题 AT91F_PIO_SetOutput(AT91C_BASE_PIOD, AT91C_PIO_PD5); /设置USB Host中断寄存器 pUhp-UHP_HcInterruptEnable = OHCI_HC_INTR_MIE | OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO; pUhp-UHP_HcInterruptStatus = OHCI_HC_INTR_RHSC | OHCI_HC_INTR_UE | OHCI_HC_INTR_WDH | OHCI_HC_INTR_FNO; /设置AIC中断信息 AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_UHP, AT91C_AIC_PRIOR_HIGHEST, AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, AT91F_ASM_UHP_Handler); AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_UHP); return 0;OHCI中的中断寄存器设置了若干中断,实际上有用的就是WDH中断,该中断是TD传输完毕后产生的。通过判断该中断的产生以及配合HCCA判断是否到达TD队列尾,可以确定数据是否传输完毕。代码中的相关常量定义可以在AT91RM9200.h、lib_AT91RM9200.h、 ohci.h这几个头文件中找到,例程AT91RM9200-BasicUHP里面都有的。本文出自 “rainman” 博客,请务必保留此出处/393579/229673基于OHCI的USB主机 寄存器(传输) 2009-11-23 17:10:30标签:OHCI 主机 USB 休闲 职场 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/232493 启动控制传输进行控制传输之前,需要设置好相应的ED和TD参数(参见下一章),启动传输时需要设置OHCI寄存器中的控制传输ED头指针寄存器和控制传输的当前ED指针寄存器,然后设置控制寄存器允许处理控制传输列表,控制状态寄存器有控制传输列表数据需要传输,代码如下:/* 通过Control端口传输数据* param *ed 需要进行数据收发的ED指针* return 0 - 成功*/short ohciCtrlXfer(AT91S_UHP_ED *ed) / Programming the CHED pUhp-UHP_HcControlHeadED = (unsigned int) ed; / Programming the CCED pUhp-UHP_HcControlCurrentED = (unsigned int) ed; / UHP: UHP is now operational and control list processing is enabled pUhp-UHP_HcControl = 0x90; / UHP: Notify the Hc that the Control list is filled pUhp-UHP_HcCommandStatus = OHCI_HC_COMMAND_STATUS_CLF; return 0;启动批量传输启动批量传输的流程与控制传输类似,只不过相应寄存器换为批量传输的寄存器了:/* 通过Bulk端口传输数据* param *ed 需要进行数据收发的ED指针* return 0 - 成功*/short ohciBulkXfer(AT91S_UHP_ED *ed) / 禁止ED pUhp-UHP_HcControl = 0x180; pUhp-UHP_HcCommandStatus = 0x00; / Programming the BHED pUhp-UHP_HcBulkHeadED = (unsigned int) ed; / Programming the BCED pUhp-UHP_HcBulkCurrentED = (unsigned int) ed; / UHP: UHP is now operational and control list processing is enabled pUhp-UHP_HcControl = 0x0A0; / UHP: Notify the Hc that the Bulk list is filled pUhp-UHP_HcCommandStatus = OHCI_HC_COMMAND_STATUS_BLF; return 0;本文出自 “rainman” 博客,请务必保留此出处/393579/232493基于OHCI的USB主机 寄存器(复位) 2009-11-25 16:59:59标签:OHCI 主机 USB 休闲 职场 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/234705 USB端口复位当USB设备连接到某个端口上以后,根据规范,需要对相应USB端口进行复位 ,对于AT91RM9200来说,其实只有一个端口,该端口号固定为0:/* USB端口复位* param port 需要复位的端口* return 0 成功*/short ohciPortReset(unsigned char port) unsigned int reg; / SetPortReset pUhp-UHP_HcRhPortStatusport = (1 UHP_HcRhPortStatusport = (1 20 | 1 4); return 0;按照规范,执行完上述复位操作以后,需要延时若干时间,经过在网上查询资料和实际调试,发现延时时间在100-150ms之间为好。对于嵌入式系统来说,不可能让系统为了等待复位完成而什么事情都不做,因此端口复位和判断复位是否结束需要分别放到两个函数中,在上层代码中进行延时处理。USB端口复位结束对USB端口进行复位后,使用下述代码判断复位是否完成:/* USB端口复位是否结束* return 0 没有结束,0 结束*/short udpIsBusResetOver(void) return pUdp-UDP_ISR & AT91C_UDP_ENDBUSRES;这个地方的代码有点奇怪,明明是对pUhp指针操作进行的复位,结果使用pUdp指针判断复位是否成功,时间太久,我也忘了这是怎么回事,估计是当年从例程里面抄过来的。不过我的上层代码中,调用复位函数后有延时,已经能够确保复位操作是成功的了,因此这个函数就这样不管了。本文出自 “rainman” 博客,请务必保留此出处/393579/234705基于OHCI的USB主机 寄存器(设备连接) 2009-11-27 17:22:24标签:OHCI 主机 USB 休闲 职场 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/235581 读取USB设备连接状态读取HcRhPortStatus寄存器可以得到相应USB端口是否有设备连接,但是在嵌入式系统中,为了增强系统的稳定性,要有适当的算法保证在一段时间内,连续读到设备连接或断开,则才能确定设备的连接状态,下面的函数在定时中断中被调用,用来检测USB设备的连接状况:/* 读取USB设备连接情况*/void ohciReadConState(unsigned short port) ohciConnectState UHP_HcRhPortStatusport & 0x01) ohciConnectState |= 1; if (ohciConnectState = 0xFF) /设备连接 ohciConnectFlag = 0x55; else if (ohciConnectState = 0x00) /设备断开 ohciConnectFlag = 0x00; 定时中断为10ms,上述代码的意思就是连续80ms检测到设备连接或者断开,才能修改设备的连接状态。本文出自 “rainman” 博客,请务必保留此出处/393579/235581基于OHCI的USB主机 寄存器(其它) 2009-11-27 17:23:51标签:OHCI 主机 USB 休闲 职场 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/235582 USB端口关电对USB端口进行关电处理的目的主要有两个,一是安全拔下U盘,防止带电插拔造成数据丢失或错误,另一个是为了再次开电,对U盘内部程序进行复位。/* 断开USB端口的供电*/short ohciHardDisable(void) / Disable port power pUhp-UHP_HcRhPortStatus0 = 0x00000001; pUhp-UHP_HcRhPortStatus1 = 0x00000001; / Disable global power pUhp-UHP_HcRhStatus = 0x00000001; return 0;清除中断状态该程序在中断程序中被调用,在OHCI规范中,设置中断是通过HcInterruptEnable寄存器来完成的,而产生中断以后,中断状态寄存器(HcInterruptStatus)的对应位就会被设置为1,通过查询该寄存器的内容可以得知当前中断产生的原因。但是如果中断状态寄存器的数据不清除的话,AM9200就不会产生新的中断,因此在中断处理程序中需要调用本函数清除中断状态:/* 清除中断状态寄存器的内容,以便能够产生新的中断*/short ohciClearIntrStatus(void) pUhp-UHP_HcInterruptStatus = 0xFFFFFFFF; return 0;说明:按照OHCI规范,在中断状态寄存器的相应位写1,就可以清除对应的中断状态。本文出自 “rainman” 博客,请务必保留此出处/393579/235582基于OHCI的USB主机 OHCI(端点) 2009-11-30 17:34:36标签:主机 USB OHCI mdash 端点 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/236950 OHCI (Open Host Controller Interface),是康柏、微软、国家半导体等公司共同制定的一个USB主机接口规范,它提供一个更抽象的接口来完成USB数据传输工作。在OHCI规范中,最重要的几个概念是端点(EndPoint - ED)、传输描述符(Transport Descriptor - TD)、主机控制器通信区(HCCA)。其中ED负责确定传输类型(控制传输、批量传输、同步传输和中断传输)。TD确定传输参数。HCCA用于确定数据传输是否完毕。下面对上面的概念进行说明,主要是翻译了OHCI规范的相关内容,更详细的内容请参考Open Host Controller Interface Specification for USB 。端点ED(Endpoint Descriptor端点描述符)包含了HC所使用的端点的信息,包括端点地址、传输速度和最大数据包尺寸等内容。另外ED还是TD(传输描述符)链表的锚点。在ED里保存该ED收发数据所使用的TD链表头指针。当HC处理ED并且发现一个合法的TD地址时,HC根据ED内标明的端点以及TD的地址完成数据传输。在USB的规范中规定了4种数据传输类型:控制传输、批量传输、同步传输和中断传输。在OHCI中对应这4种传输类型有4个传输ED列表,主要使用控制寄存器(HcControl)和命令状态寄存器(HcCommandStatus)进行控制。控制和批量传输的ED组成列表,每个ED下面带着需要进行处理的TD,ED包含端点所允许的最大的包大小,控制器硬件完成包的分割。每次传输后都会更新指向数据缓冲区的指针,当起始和终止指针相等时,TD就释放到完成队列(done-queue)。下图是一个典型的链表结构图。在OHCI中,每一帧的时间被分为3块,首先处理批量和端点列表,这段时间由HcPeriodicStart寄存器的设置来控制,然后处理周期性列表(中断和同步列表),处理完毕如果还有时间,则继续处理批量和端点列表,如下图:对于控制和批量传输来说,控制端点比批量端点有更多的总线处理机会。每处理1个批量端点就需要处理N个控制端点,这个N:1的比例叫做控制批量服务比例。HCD通过HcControl寄存器的ControlBulkServiceRatio字段来设置比例,比例的范围从1:1到4:1。HC强制按照控制批量服务比例进行处理,而不考虑相应列表中的控制和批量ED的数量。如果只有1个控制ED在控制列表中,而控制批量服务比例为4:1,则在批量ED被服务之前,该控制ED被服务4次。如果控制或批量列表中没有ED,HC就会跳过对应的列表,而立刻处理其它的列表并且完成需要的ED数量。HC会根据控制批量服务比例继续检查空列表,如果有新的ED,就按照该比例进行处理。本文出自 “rainman” 博客,请务必保留此出处/393579/236950基于OHCI的USB主机 OHCI(传输描述符) 2009-12-02 17:26:14标签:主机 USB 传输 OHCI mdash 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。/393579/237835 传输描述符(TD) 传输描述符(TD)是系统内存的数据结构,被HC用于定义从端点收发数据的缓冲区。TD分为2个类型:通用TD和同步TD。通用TD用于中断、控制和批量端点,同步TD用于同步传输。使用两种不同的TD类型是因为缓冲区类型的不同。对于U盘主机控制器来说,不使用同步传输。 若干个传输描述符组成队列链接到ED上。ED提供传输TD数据所需要的端点地址。HCD把TD增加到队列中,而HC把TD从队列中删除。HC把TD从队列删除后,将其链接到已完成队列,这个过程叫做“释放”。TD的释放原因包括正常释放和错误释放。当TD释放后,释放情况代码被写到TD中,以便HCD确定释放原因。 TD是按照顺序进行处理的。它们被链接到ED上。TD队列的第一个TD指针放在ED的NextTransferDescriptor字段,HC从该TD开始处理队列。当TD被释放,就会从队列中删除,该TD的NextTransferDescriptor字段所指向的下一个TD被转移到队列头。当HC处理ED的时候,只会产生一个事务。HC只有在当前ED的所有TD都处理完毕后才会产生下一个事务。 在每一个事务完成以后就会更新通用TD。有4个字段会被更新:CompletionCode、DataToggleControl、CurrentBufferPointer、ErrorCount。 Dat

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论