×
嵌入式 > 技术百科 > 详情

USB嵌入式主机控制器设计

发布时间:2023-09-14 发布时间:
|
介绍

过去usb仅应用于个人计算机其在嵌入式系统领域的巨大潜力尚未开发usb在嵌入式系统中的应用包括kvm开关数码相机pda打印机机顶盒及移动电话。

什么是嵌入式系统嵌入式系统被定义为硬件和固件--独立的或作为更大型系统的一部分--通常带有某种操作系统操作系统可以是windows cevxworks或由“自编代码”构成的更简单系统根据上述定义可以认为任何带有处理器的电子装置均可以作为usb嵌入式主机。

嵌入式系统的设计挑战

在基于pc的系统中三种主要部件需要usb操作它们是通常作为pci子系统部分的主机控制器usb堆栈以及usb类驱动器。

主机控制器是集成主板芯片组的部分usb堆栈则包含主板芯片以及uchi通用主机控制器接口ohci开放主机控制器接口的驱动程序以及usb驱动程序(usbd.sys)实现基于pc的usb需要以上所有领域的专门技术。

在usb嵌入式系统中其主要组成部分与pc系统类似这些组成部分为嵌入式主机控制器芯片带ohci堆栈的实时操作系统(rtos)以及专用驱动程序。

现有很多可供选择的主机控制器芯片有些带有处理器有些则以寄存器为基础此处组成部分设备的选择将会影响如下两个层面。

很多公司可提供rtos最好选择一个处理器和与之配合工作的rtos然后在其上添加应用代码如果没有真正的rtos某些控制器带有可构造应用的“框架”以下介绍这种框架的示例以及如何在其上构造应用。

在pc上实现usb时pc具有丰富的可用资源其中包括高达512mb字节的存储器20-60gb的硬盘以及2ghz或速度更快的微处理器此外五年多来windowsmac os以及unix等操作系统一直支持usb世界上有数以百计或数以千计的工程师在设计基于pc的usb应用程序和设备驱动程序。

而另一方面嵌入式系统通常只有不超过64k的存储器以及运行于12mhz - 33mhz范围内的处理器没有硬盘由于usb对于嵌入式系统相对较新因此可能只有为数不多的工程师拥有这方面的经验。

赛普拉斯ez-host控制器

赛普拉斯ez-host器件拥有两个“串行接口引擎”每个引擎包含两个usb端口因此无需使用额外的硬件ez-host便可控制四个usb设备。

ez-host器件具有固件结构可管理大多数usb主机的详细要求该结构的另一个特点是支持网络集线器键盘/集线器组合部件常常出现这样的问题是带有集线器的键盘还是带有键盘的集线器答案是带有键盘的集线器因此要了解位于集线器后的键盘需要提供集线器支持幸好框架代码包含对集线器的支持。

以下章节将介绍框架和某些框架操作示例以及如何将其与应用代码接口。

框架概述

ez-host框架包含所有实现usb主机功能所必需的固件其中包含任务时序设备列举带宽分配以及功率管理。

另一方面应用程序是固件控制专用usb设备并将其数据传递给最终应用。

框架的核心是td处理器td处理器的运作基于称作“任务描述器”(td)的数据结构使用其信息与usb硬件尤其是“串行接口引擎”(sie)进行通信需要注意的是每个sie控制两个端口而且每个sie具有一个td处理器。

ez-host框架使用了多种数据结构实现来其操作这些结构包括td和usb“请求模块”(urb)。

任务描述器是传递给硬件的数据结构包含特定硬件接口如sie的数据字段端口编号终点数收发数据缓冲器长度数据包id编码以及urb结构指示器。

urb包含td所需的逻辑信息该逻辑信息包括usb设备缓冲器安装软件包以及usb设备结构指示器。

在进行usb事务处理时urb含有事务处理分配及其装入的数据结构而后urb提交给td处理器td处理器将urb加入td列表空闲时td处理器处理td列表安排传输时序并将设定好的td传送给ez-host硬件进行处理。

图1所示为基本的usb控制传输该图表为td处理器处理usb传输的示例

图1usb控制传输

为了执行控制转移可以使用框架函数send_request( )send_request( )函数将分配一个传递给td处理器的urb结构。

urb应该包含有关设置状态的信息并且借助参数传递给send_request( )urb需要如下信息。

请求类型 - 表示usb请求类型的字节该字节包含表示传输方向传输类型以及传输接受者的位

请求 - 11种标准usb请求之一这些请求包括

clear_featureget_configurationget_descriptorget_interfaceget_statusset_addressset_configurationset_descriptorset_featureset_interfacesynch_frame

值 - 特殊请求字段

索引 - 特殊请求字段

长度 - 有关数据缓冲器的大小

一旦载入用于urb的设置信息便可将其它设备信息装入urb如地址速度终点数以及传输方向还有表示传输类型的字节和“回调”函数指示器使用回调函数可以在框架内进行某些并行操作可在硬件处理usb操作的同时执行其它任务td需要usb传输类型信息这样框架可以安排正确的传输类型的时序同样地与批量或中断传输相反框架一次只允许进行一个控制传输操作。

装入所有的urb信息之后将urb提交给td处理器td处理器是框架的组成部分它与硬件直接通信处理有关传输的低级详细资料td完成任务后td处理器将项目控制转换为原始调用指定的“回调”函数转换为 send_request( ) 函数 。

图2send_request( )函数

以下的图3所示为调用带回调函数的send_request( )在此例中我们使用控制传输以获得某键盘的国家代码在get_country_code( )函数中可看到send_request( )的调用注意send_request( )调用中的最后一个参数是回调函数在td处理器确定硬件完成此次处理后执行该函数这种情况下回调函数将获得返回的数据缓冲器将其与hid描述器结构相匹配并存取与国家代码相对应的字节此后urb被释放。

图3调用和回调函数

ez-host框架值得注意的最后一个特点是设备驱动程序的使用在执行过程中设备驱动程序将执行三个功能停止启动和运行启动某设备驱动程序时便是运行它的run( )函数该函数对某些数值进行初始化并分配一个用于数据传输的重现urb对于鼠标或键盘该urb将每隔10毫秒发生一次数据传输完成后td处理器将控制转换为 interrupt_in_complete( )函数通过检查urb可以得知数据是来自键盘还是来自鼠标这种回调函数负责将键盘或鼠标数据发送至应用层面以下是用于数据传输的回调函数示例。

图4中断传输回调函数

当某驱动程序停止时其重现urb从td列表中除去并释放此外消息传送至应用层面除去相关的设备如果与停止驱动程序相关的设备是集线器则与该集线器相连的所有设备也被移除并且其驱动程序停止当然如果这些移除的设备中有集线器则与该集线器相连的设备将以同样方式移除。

在驱动程序的运行期间系统可执行各种任务对于集线器的设备驱动程序要检查集线器的端口以了解是否有设备插入和移除键盘和鼠标驱动程序的运行函数不起任何作用。

框架流式

框架代码执行如下上电复位微处理器对所有的寄存器和计数器以及设备结构进行初始化然后进入如下的循环。

1.检查主机usb端口是否存在状态的改变设备插入或移除

2.检查td处理器并获得运行于两个sie上的所有td的状态信息

3.查看运行设备驱动程序列表并执行每个程序的运行函数

检查主机usb端口以了解状态变化这需要检查变量的改变如果发生变化可通过端口变化中断处理程序设定变量如果端口改变将执行枚举代码来处理这个变化。

通过集线器至主机的中断传输完成相连集线器变化值的检查如果发生设备添加或移除它们将像上例那样列举出发现新设备时需匹配其设备驱动程序然后装入匹配设备驱动程序与设备的方法有多种框架代码将首先试着将某驱动程序与某设备的供应商id和产品id进行匹配只有存在特定的制造商而且特定设备在特定驱动程序中运行这种方法才起作用如果没有实现匹配框架代码会试着对设备的种类和子类进行匹配这可实现更普通的驱动程序与设备匹配。

设备插入和移除检查还有两项附加任务如果连接的设备是集线器必须对其端口进行检查以查看它们是否带有设备如果移除的设备是集线器所有与其连接的设备也必须移除。

通过中断传输还可以检查来自相连键盘和鼠标设备的新数据这些传输每10毫秒种发生一次由td处理器安排时序任务完成后td处理器将传输控制转换为回调函数这时可提取键盘和鼠标数据并送至应用层面。

构建应用

下一节将介绍如何构建控制键盘和鼠标的简单嵌入式usb设计。

该方案使用基于处理器的usb主机控制器处理器的代码将包含框架和应用固件首先要做的是确定想要支持设备的数量和类型确定了设备数量后可据此分配urb和驱动程序空间通过修改名为fwxcfg.h的“个性化”文件完成urb分配。

每个键盘鼠标或集线器均需要一个urb来处理其在传输中的复现中断此外在列举和其它usb控制传输过程中urb被分配并随后释放一种好的经验法则是为系统支持的每个设备分配两个urb一个分配urb用于传输中的复现中断另一个则用于任何可能的控制传输这些传输可能发生在设备列举或设备状态检查的过程中虽然每次只能处理一个控制传输框架可将附加传输排列系统支持的urb数量应该等于所支持设备数量的二倍。

接下来需要为键盘和鼠标创建驱动程序由于这些设备的usb功能非常相近所以两个设备可以使用一个驱动程序该驱动程序可称为hid_driver用于人机界面设备的驱动程序下一步是在驱动程序内添加开始停止以及运行函数以及查找驱动程序的设备种类编码还需要将驱动程序函数的名称添加进文件drvrlist.h包含集线器和hid driver的驱动程序声明如下。

#define fwx_driver_list { &hid_driver, &hubclass_driver }

hid_driver启动函数将分配传输中的复现中断以获得键盘和鼠标数据该函数内的编码将获得数据并将数据传给编码应用层停止函数将释放复现中断传输并通知应用层面设备已被移除运行函数将用来检查来自应用代码的输入指令。

接下来需要为列举通报函数添加一些代码列举通报函数是列举代码使用的回调函数用于报告设备列举的状态并处理可能的列举错误该代码可将有关新列举设备的信息传给应用层面。

在这里集线器支持很容易不需要添加任何代码也不需要编写驱动程序因为框架已包含驱动程序所要做的是更改fwxcfg.h中的语句从

#undef fwx_include_hub_support 至 #define fwx_include_hub_support

并将文件hubclass.c添加进项目“形成文件”makefile其余的事务由框架处理。

总结

与pc相比尽管usb主机系统在计算资源和经验方面存在不足开发人员仍然可以很简单地将usb功能加入其嵌入式系统现有数种用于实现此功能的usb主机ic可供选择用户可购买或开发usb主机堆栈和“实时操作系统”。

本文论述如何仅仅使用一个附加ic并且不使用第三方软件来实现usb嵌入式主机usb嵌入式主机框架可处理所有的较低级技术细节赛普拉斯的ez-host usb主机可在不进行额外编码的情况下支持hid设备和集线器该系统目前最多可支持8个设备和两个集线器等级可方便地实现更多设备和更多等级的支持当前代码的大小大约为22k字节设计人员所需做的是为整个系统添加专用代码。


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Semtech的LoRa技术携手Chipsafer将牧场连接至云端