UEFI开发探索72- YIE002USB开发板(01 开篇)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

最近把USB的各个方面都研究了一遍,也在UEFI下实现了USB设备的访问。趁着这热乎劲,我计划把USB HID通信的知识,集合到一个新的开发板中进行介绍,也即我目前正在考虑设计的YIE002。

虽然YIE002的开发板还在规划中,我使用其他的开发板,已经打通了USB的通道了。只等着YIE002开发打样回来,把嵌固件代码移植过去就行了。

因为涉及到三个平台的开发(Windows、UEFI以及嵌入式平台),开发中需要记忆的知识点有点多。虽然现在对这些知识还比较清楚,时间长了后,有些细节容易忘记。因此,本篇开始进行YIE002的各类软件实验。

后续的篇章中,会交叉进行YIE001和YIE002的实验。两者的区别在于,YIE001主要是基于PCIE总线的,而YIE002则使用的是USB总线。

1 YIE002开发板计划

首先简单介绍下YIE002的开发板计划。 如图1所示,是我规划的YIE002开发板。

图1 YIE002构想图

YIE002设计成U盘类似的形状,方便直接插在电脑上进行实验。主要想实现的目标如下:

1) 使用开发板的单片机,实现USB HID设备,允许各种操作系统上的软件与其通讯;

2) 实现UEFI下与YIE002通讯(通过USB HID通道);

3) 实现Windows/Linux下与YIE002通讯(通过USB HID通道);

4) 可通过上位机(UEFI/Windows/Linux)上的软件,通过设计好的USB数据包,控制YIE002上的LED灯;

5) 开发板本身提供生成随机数的功能,上位机可通过USB通道得到生成的随机数。

第5条的灵感来源于开源项目ChaosKey,其地址为:https://altusmetrum.org/ChaosKey/。这是一个可产生真随机数的小设备,我觉得比较有意思,准备在YIE002中实现类似的功能。

总而言之,是希望利用YIE002,深入学习USB协议,掌握在单片机上构建USB设备的知识,以及学会编写UEFI、Windows、Linux下访问USB HID设备的上位机程序。

2 编程规划

从YIE002的架构来说,应该首先介绍如何编写固件程序。不过由于目前开发板还处于概念阶段,预计从设计、打样到焊接出来,至少得到2个月后了,毕竟我主要是用业余时间在鼓捣这些。

因此,我选择从自己最熟悉的Window编程开始谈论这个课题。毕竟Windows平台的开发工具比较完善,调试也比较方便。

为什么会选择使用USB HID设备来进行开发呢?

主要是因为,不管是Windows/Linux系统,还是UEFI,都提供了HID API,不需要再额外再去写驱动来管理硬件设备。不管是Windows驱动还是Linux驱动,都需要花费不少的时间去学习。

有兴趣的网友,可以去查下张佩的CY001开发板。他介绍了如何为CY001编写驱动以及上位机程序,详细的过程和代码在《竹林蹊径-Windows驱动开发》中提供了。

我在日常的开发中,总是需要在各种平台上传输少量的数据。如果所开发的设备,在各个系统平台进行驱动程序的维护,这个工作量就太大了。

比如开发板YIE001采用的是PCIE总线,在操作系统下与之通信,是必须要编写PCIE驱动的(我的代码是写好了,暂不安排计划,议题偏离UEFI探索太多了)。

因此,USB HID是非常好的选择,各个操作系统都提供了驱动支持,省去了编写和维护驱动程序的麻烦。比较适合传输少量数据、速率要求不高的场合,很容易在各种操作系统下编写上位机程序。

针对YIE002的编程规划如下:

1) Windows系统下编写USB HID上位机程序;

2) 编写MCU固件程序,建立通信通道,并构建控制硬件资源(主要是LED灯和获取随机数)的数据协议;

3) UEFI下编写USB HID上位机程序;

4) Linux下编写USB HID上位机程序。

在编写这些代码的过程中,会夹杂着讨论USB协议以及HID协议。为方便通信,USB HID设备与上位机的传输长度为16字节,如图2所示。

图2 YIE002通信示意图

所有的编程,都是围绕着这个架构来进行的。

3 代码概述

我们知道,HID设备有三种类型的报告可以使用:Input Report(至少一个)、Output Report(可选)和Feature Report(可选)。与之对应的,HID类相关的命令为Set Report和Get Report。

上位机可以通过这两个命令,与HID设备中设定的数据进行通信。也就是说,三种类型的报告用来告诉上位机,设备本身所具有的属性;上位机和HID设备之间,可通过Set Report和Get Report进行数据交互。

HID设备的固件中,必须实现这两个命令对应的操作。上位机中,也必须调用操作系统提供的API,向HID设备发送命令(USB协议中,主机发送命令)。对于UEFI系统来说,所提供的API就是之前常用的Protocol。

实际上,在上位机和HID设备的通信中,可以通过三种方式进行(以下是针对Stm32所开发的USB HID设备,在Windows系统上运行上位机):

1) 上位机使用函数ReadFile()/WriteFile()进行读写,在开发板YIE002上,对应固件代码中的USBD_HID_DataOut()/USBD_HID_DataIn();

2) 上位机使用函数HidD_SetOutputReport()和HidD_GetInputReport(),对应固件代码中的处理HID类命令Set Report和Get Report的代码;

3) 上位机使用函数HidD_SetFeature()和HidD_GetFeature(),对应固件代码中的处理HID类命令Set Report和Get Report的代码;

第2种和第3种方式中,固件代码的位置是一样的。第2种方式使用的是Input Report和Output Report,第3种方式使用的是Feature Report。在实际应用中,可以对报告设置不同的报告ID,以方便程序区分。

在我设计的例子中,特意将这三种报告都设为了16字节,而且没有设置Report ID,并且使用了同一16字节的缓冲区。因此,在上位机访问的时候,将入口参数中的Report ID设为0就可以了。

如果想区分第2种和第3中访问方式,就必须在设计报告描述符的时候,就将Report ID设计好。固件代码中,也得区分处理不同的报告。同样的,上位机访问时,就必须指定Report ID了。

更多的细节,在后续的章节中将陆续展开描述。下一篇,如编程规划中所介绍的,开始介绍Windows系统下的访问USB HID设备的编程。

1,596 total views, 1 views today

发表评论

电子邮件地址不会被公开。