框架数据流
框架代码执行过程是这样的:上电复位、微处理器对所有寄存器和计数器以及设备结构进行初始化,然后进入如下的循环:
1.检查主机USB端口是否存在状态改变(设备插入或去除)。
2.检查TD处理器,并获得两个SIE上运行的所有TD状态信息。
3.查看运行设备驱动程序列表并执行每个程序的运行函数。
检查主机USB端口以了解状态变化需要检查变量的改变,如果发生变化,可通过端口变化中断处理程序设定变量。如果端口发生改变,将执行枚举代码进行处理。
通过集线器至主机的中断传输完成相连集线器变化值检查,如果发生设备添加或去除,它们将像上面那样枚举出来。发现新设备时,需要找到设备驱动程序然后装入。根据设备寻找设备驱动程序的方法有很多种,框架代码将首先尝试将某驱动程序与某设备的供应商ID以及产品ID进行匹配,但只有存在特定的制造商且特定设备在特定驱动程序中运行这种方法才有效。如果没有实现匹配,框架代码会尝试对设备的种类和子类进行匹配,这可以利用更普通的驱动程序与设备匹配。
设备插入和去除检查还有两项额外的任务。如果连接的设备是集线器,则必须对其端口进行检查,以查看它们是否带有设备。如果去除的设备是集线器,那么所有与之连接的设备也必须去除。
通过中断传输还可以检查来自相连键盘和鼠标设备的新数据,这些传输每10毫秒种发生一次,由TD处理器安排时序。任务完成后,TD处理器将传输控制转给回调函数,这时可提取键盘和鼠标数据,并送至应用层。
构建应用
现在介绍如何构建一个简单的控制键盘和鼠标的嵌入式USB设计,该方案使用基于处理器的USB主机控制器,处理器的代码包含框架和应用固件。首先要做的是确定希望支持设备的数量和类型,确定设备数量后,可据此分配URB和驱动程序空间,通过修改名为fwxcfg.h的“个性化”文件完成URB分配。
每个键盘、鼠标或集线器均需要一个URB来处理传输中重复出现的中断。此外,在枚举和其它USB控制传输过程中,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添加进项目形成文件,其余事务由框架处理。
本文小结
尽管与PC相比,USB主机系统在计算资源和经验方面存在不足,但开发人员仍然可以较为简单地将USB功能加入到嵌入式系统中。现有多种用于实现这种功能的USB主机IC可供选择,用户可购买或自行开发USB主机堆栈和实时操作系统。