USB主机控制器的设计
扫描二维码
随时随地手机看文章
摘要:讨论在SoPC(System on a Programmable Chip)系统中设计USB主机接口设备的一般方法,着重阐述主机控制器的驱动程序开发。利用Xilinx公司的EDK软件在ML405开发板上搭建一个基于PowerPC的片上系统,设计EZ-Host的USB主机控制器的Linux驱动程序,使系统具有USB主机功能,能够和各种USB设备进行通信,实现SoPC系统上基于Linux的USB接口的扩展,对于开发其他USB主控制器驱动具有一定借鉴意义。
关键词:USB;USB主机控制器;EZ-Host;Linux;SoPC
USB具有简单、标准的连接方式、支持热插拔等诸多优点,因此已成为流行的接口技术。USB是典型的主/从结构的总线标准,即只有USB主机才能与USB设备连接。USB总线与计算机系统的接口部分是主机控制器,它可以被看作一个硬件、固件和软件的综合体。主机控制器实现主机与设备之间的电气和协议层匹配,主要包括:串并转换、帧起始、数据处理、协议使用、传输错误处理、远程唤醒、根Hub、主机系统接口等功能。USB设备之间通过USB Hub连接,主机控制器和USB设备之间一般通过根Hub相连。通常主机控制器提供与根Hub相关的状态查询和控制单元。当有设备插入时,在枚举过程中,主机控制器驱动通过查询和控制单元应答设备伪装成一个Hub,所以通常称此Hub为虚拟根Hub。
这里利用EDK软件搭建一个基于PowerPC的片上系统,实现了SoPC系统上基于Linux的USB接口的扩展,使系统具有USB主机功能,能够和各种USB设备进行通信。
1 开发环境
目前Linux 2.6内核中的USB支持3种主控制器接口:通用主控制器接口(UHCI)、开放控制器接口(OHCI)及增强主机控制接口(EHCI)。在嵌入式系统中,如果处理器集成有USB主机控制器,则可直接引出USB主控端口;而未集成USB主机控制器的处理器则需使用USB主控器件,从总线上扩展USB主机接口。
这里所采用的开发环境是Xilinx公司的ML405开发板。开发板上核心FPGA采用Xilinx的XC4VFX20-FF672器件,其内置1个PowerPC硬核,2个以太网MAC层控制器。开发板上还带有64 MB的DDR SDRAM,10/100/1000以太网端口、带主机/设备端的USB接口器件(CY7C67300)等。
EZ-Host(CY7C67300)是Cypress半导体公司的全速低耗多端口主机/外设控制器,该器件可方便接至高性能CPU上完成USB主机控制器端的功能;拥有16位RISC指令处理器,可作为协处理器使用或单独使用;同时支持USB的OTG协议,拥有2个可独立配置并各带有2个端口的USB串行接口引擎(SIE);既可用作主机,又可用作外设,并支持多达4个主机端口。另外,该器件拥有一个可编程I/O接口模块,可供各种接口编程使用,可编程实现HPI、HSS、SPI等接口模式。当EZ-Host控制器作为USB主机控制器时,一般采用HPI主机端接口(Host Port Interface)接口模式。
2 硬件设计
Xilinx公司提供一个IP核opb_epc外设控制器(external peripheral controller),为OPB总线与外部同步或异步外围设备之间的数据传送提供一个通用接口,可方便实现处理器对于外设的控制。一个opb_epe最多可接4个外设,且每个外设可独立配置成同步或异步模式,其时序参数(如建立时间、保持时间、访问时间周期等)都可由用户设置。opb_epc通过OPB总线接收处理器的读写指令,在相应外设接口产生相应
的访问周期,从而实现处理器对外围设备的控制。这里使用opb_epc模块作为控制器,实现PowerPC与EZ-Host的主机控制器的接口通信,嵌入式硬件系统架构如图l所示。
[!--empirenews.page--]
ML405板上的EZ-Host控制器工作在异步模式。因此opb_epc需配置为支持异步外设模式。这里使用PowerPC控制USB接口,因此EZ-Host工作于协处理器模式。并通过HPI接口与外设控制器opb_epc相连。
3 驱动程序设计
3.1 USB主机端的软件结构
Linux USB主机驱动协议栈由3部分组成:USB主机控制器驱动(HCD)、USB驱动(USBD)和各种不同的USB设备类驱动,如图2所示。
USB设备类驱动(如插入主机的U盘、鼠标、键盘等设备驱动)是最终与应用程序交互的软件模块,负责建立虚拟连接、配置,与设备进行通信,将数据集成一个USB请求块(URB),然后通过USB驱动(USBD)提供的编程接口将URB发送到USBD。USBD部分是整个USB主机驱动的核心。
USBD完成以下工作:USB设备的枚举和配置,根据需要装载或卸载设备驱动程序,向上为设备驱动程序提供编程接口,向下为主机控制器驱动提供编程接口,实现与设备驱动程序、主机控制驱动程序的通信。
处于最底层USB主机控制器驱动(HCD)是USB主机直接与硬件交互的软件模块。HCD作为底层硬件的驱动程序,一方面控制和管理底层硬件,负责将USB事务发送给USB主机控制器,并最终将串行数据发送到电缆上;另一方面为上层的USB系统软件提供统一接口HCI(Host ControllerInterface),将各种不同的HC映射到USB系统。HC一般都集成有Root Hub的功能,HCD也要实现Root Hub Port访问。
USBD部分由操作系统实现,一般不需要用户修改。USB设备类驱动,对于常用的设备Linux内核中有较成熟的驱动。针对特定的主机控制器硬件应该实现HCD部分,以解决基本的通信问题。故这里主要介绍EZ-Host主机控制器驱动(HCD)的设计。
3.2 EZ-Host主机控制器驱动(HCD)设计
开发过程主要针对EZ-Host主机控制器编写USB主机控制器驱动程序。该驱动程序是嵌入式Linux开发平台下USB协议栈和EZ-Host主机控制器的一个接口,其作用类似于Linux中由Intel制定的UHCI标准,其硬件设计比较简单,但软件较为复杂。
USB主机控制器的驱动(HCD)在USB子系统中的功能主要有:硬件初始化,为上层(USBD)提供调用接口,管理根Hub,完成数据传输以及中断处理。根据主机控制器驱动(HCD)在整个USB子系统中的功能,可将EZ-Host HCD分为HCD接口、HCD初始化、数据传输、中断处理、读写操作、主机协议等模块。HCD接口模块表现为一套API函数,通过这一套API函数使HCD与USBD进行通信。图3为EZ-Host主机控制器驱动模块结构。
1)初始化。该初到始化涉及到复位EZ-Host控制器,并将其初始化到一个已知的状态;初始化必要的USB数据结构并为其分配空间;注册USB host driver和USB host bus interface到USB host core;注册USB host core的中断服务程序;为每一个主端口建立一个虚拟根Hub,并且注册根hub到USBhost eore。2)中断处理。EZ-Host主控制器中断采用电平触发,当中断服务程序注册到USB子系统后,EZ-Host主控制器开始处理中断。3)传输数据。传输处理程序在初始化的过程中注册到USB主端子系统,它由USB host core唤醒并配置外围设备,发送块数据,或确认块数据的接收。4)接收数据。接收处理程序处理数据包的接收,它由中断处理程序唤醒。数据接收处理程序询问EZ-Host主控制器是否有接收错误,如果没有错误,则接收处理程序从EZ-Host主控制器的缓冲区中提取数据并将数据存储到一个数据结构,然后接收程序将数据传送到USB host eore,等待进一步处理。5)主机协议实现。HCD从Linux USB协议栈接收并解析USB请求,然后建立基于该请求的USB交互(transactions),该交互被合理调度安排并发送到USB总线上。
3.3 HCD的关键接口设计
实际工作过程中,应用程序通过文件系统接口访问相应的USB设备类驱动程序和USBD;USB设备类驱动程序则通过USBD提供的相关接口(USBDI)将数据请求包传递给USBD;USBD通过HCD提供的接口(HCI)进一步将数据包传递给HCD;HCD最终将数据发送到USB总线。
主机控制器驱动中,最重要的接口是主机控制器驱动HCD与USBD之间的接口。在Linux内核中,用usb_hcd结构体表示USBD接口,用来描述主机控制器(HC)的基本信息、硬件资源、状态描述和用于操作主机控制器的hc_driver等。其中usb_hcd中的hc_driver成员非常重要,它包括具体用于操作主机控制器的钩子函数。在Linux内核中,使用如下函数创建HCD:
struct USB_hcd*USB_create_hcd(const stroct hc_driver*driver,struct device*dev,char*bus_name);
struct hc_driver可看作USBD模块定义的需要底层主机控制器驱动实现的接口,通过实现这些接口,USBD可将更上层软件的请求传递给HCD以及HC,HC及HCD完成后,也会通过这些接口通知USBD。[!--empirenews.page--]
这里在EZ-Host主控制器驱动中定义一个结构体structusb hcd c67x00_hcd,用于描述EZ-Host的基本信息、硬件资源、状态描述,定义struct hc_driver c67x00_hc_driver来描述用于操作主机控制器的钩子函数,其结构体如图4所示。
c67x00_hub_start()启动HCD主控制器,c67x00_hub_irq()实现其中断控制处理,c67x00_hub_status_data(),c67x00_hub_control()实现对虚拟根集线器的控制,c67x00_hub_enqueue(),c67x00_hub_dequeue()实现对USB请求(URB)进行排队,对URB进行调度。根据hcd和endp-oint的信息,安排URB的schedule到e67x00,该URB的传输完成后,会调用urb->complete()通知USBD。
4 测试结果
在ML405开发板上实现了USB主机控制器的开发,使系统具有USB主机功能。在开发板上分别插入USB键盘、USB鼠标、U盘进行测试,内核识别信息输出如图5所示。
从图5中可看出,系统可以方便与大容量存储类(MassStorage类)USB接口、人机接口类HID(Human Interfaee Device)USB接口进行通信,进行正常读写操作,实现了系统的SB接口扩展。
5 结束语
详细介绍在SoPC平台上进行USB主机控制器的硬、软件设计。针对EZ-Host器件,详细介绍其USB主控制器的Linux驱动开发过程及主要的接口设计,对于USB的主机控制器的驱动开发有一定参考价值。设计的重点和难点主要集中在主机控制器器件的驱动程序开发的环节上,但Linux作为开源系统,在开发设备驱动程序时有着其他嵌入式系统不可比拟的优势,大量的开放源码无疑可以大大加快开发的进程并使得其应用更加的广泛。因此,USB作为一种新型的高速外设总线,在嵌入式Linux领域有着广阔的应用前景。