APP下载

基于STM32的USB HID接口多功能控制器设计

2020-09-14王晓东

唐山学院学报 2020年3期
关键词:描述符固件端点

王晓东

(唐山学院 计算机科学与技术系,河北 唐山 063000)

1 概述

USB总线协议是由Intel,Compaq,Microsoft等七家公司共同制定的串行接口标准[1],协议内部包含完善的主从机通讯机制,支持从高速视频传输到低速查询传输多种通讯模式,传输速率高,从USB1.1协议发展到USB3.0协议,速度已达到5.0 Gbps,而且支持设备的带电热插拔,因此支持USB总线协议的设备使用起来十分方便,被广泛应用在通用计算机和边缘计算领域。如文献[2]作者使用Windows的DDK开发工具,基于USB总线的HID人机接口协议,开发了一种USB接口自动测试设备。但对于工业系统开发者和厂商来说,USB驱动程序开发过程十分复杂,在Windows环境下需要使用WDK或者DDK开发工具,并且随着操作系统的升级,开发工具和驱动程序也需要随之升级,另外,商业开发USB设备驱动还需要缴纳认证费用,增加经济负担。因此大多数的工业控制器仍然使用串口或者USB转串口的方式通讯,正常速度为几十kbps到几百kbps,效率较低。计算机的USB接口HID(Human Interface Device)类协议[3]负责人机接口设备如鼠标、键盘和游戏杆等和计算机交互操作。USB HID接口权限自由度高,特别是鼠标类设备具有操作系统最高权限,其每个操作信号、每组数据都可以在用户许可的情况下发出或者接收,应用开发用户可以调用HID接口的API函数支持人机接口类别的设备。

STM32系列硬件是专为要求高性能、低成本、低功耗的嵌入式应用设计的ARM Cortex内核处理器,其内部自带flash和RAM,接口资源丰富,并自带USB物理收发器,因此使用单芯片即可构建完整的智能物联网仪器仪表的核心模块[4-5]。STM32处理器性价比很高,适合于工业和民用测控领域使用,文献[6]即使用STM32搭建低成本的测量装置,实现了高精度的电量测量。STM32处理器的通讯功能强大,在STM32处理器内部集成了USB收发器,支持USB HID通讯协议,使用USB HID接口每次最多可发送1 024个字节,对于USB2.0硬件,最大速度可以达到24.576 MB/s,足以满足中等性能工业控制器的需求。有学者使用USB HID技术开发了专用的鼠标[7]、键盘[8]和手势输入设备[9],但是由于没有主机数据输出,仅有单向数据输入功能,不能用于控制器。

本设计基于STM32构建了一个使用USB HID协议的多功能控制器,数据传输工作采用中断传输方式,主机和控制器(从机)之间建立相互独立的写入和读出管道,上位机控制软件直接调用HID接口的API函数实现对下位机硬件的读写控制。

2 系统硬件原理和组成

基于STM32的USB HID接口控制器的硬件系统结构如图1所示。控制器选择STM32F103作为系统主处理器,其工作频率为72 MHz,采用ARM CortexM3内核,功耗约为0.1 W,其内部集成了两个AD采样器,可以直接接收0~3 V的模拟输入电压,支持USB全速设备。主处理器通过定时器中断输出3.3 V的PWM信号,PWM信号经过光电隔离后输出给控制驱动电路。本设计使用LED驱动电路进行验证,由于驱动电路工作在高电压、大电流状态下,因此PWM信号必须隔离输出。在控制器系统集成多路光电隔离的GPIO信号,用于外部开关控制,系统中MAX3232作为UART串口驱动,用于调试接口和功能扩展。

图1 USB HID接口控制器的硬件系统结构图

控制器USB HID接口部分的实际电路图如图2所示。STM32F103的PA11和PA12分别连接USB总线的DM和DP端,在DP端上拉1.5 kΩ电阻用于全速设备检测热插拔事件,如果DP端直接上拉到3.3 V电压,因从机的上电延迟,会导致枚举失败,因此USB总线的上拉电阻接到STM32F103处理器的IO端口PB10,当控制器启动,在固件main函数中将PB10拉高,从而等待USB插入事件,开始进行枚举。

图2 USB HID接口电路图

3 USB HID接口多功能控制器设备固件软件设计

参考USB HID协议,USB HID接口控制器和主机之间需建立两种传输管道:控制传输管道和中断传输管道。控制传输管道用于设备枚举,从设备上传设备描述符、配置描述符以及HID描述符等信息,下发Get请求和Set请求,在设备资源方面占用默认的端点0。因为本控制器属于自定义的HID设备,首先需要重新定义HID报表描述符,在报表描述中增加和修改数据输入和输出报告,修改通讯数据包的字长、字数目、传输方向、最大值和最小值。HID报表描述符完成后,在HID描述符填充HID报表描述符信息(长度、类别)。控制器使用中断传输进行实际的负载数据传输,其内部分配两个中断类型的端点,分别用于数据接收和发送。

3.1 控制器USB HID接口枚举和工作过程

控制器USB HID接口主从机枚举工作和交互过程如图3所示。主机检测到从机接入后,开始标准设备枚举过程,包括请求和接收设备描述符、设置从机地址、请求和接收配置描述符三个步骤。通过标准设备枚举过程,主机获得控制器的设备描述符、配置描述符、接口描述符和端点描述符。标准设备枚举之后,进行HID类设备枚举,主机向从机发送Get HID类描述符请求,然后收到HID类描述符和报表描述符。在控制器全部枚举后,系统进入正常的工作状态,在Windows环境下主机通过调用ReadFile和WriteFile实现和从机之间收发数据。在Linux环境下可以调用libusb库实现USB HID通讯。HID设备定义了6个HID类请求,在STM32固件程序的Setup阶段中断函数中响应这些请求命令,根据HID请求发送相应的HID类描述符。

图3 控制器USB HID接口主从机枚举工作和交互过程

3.2 控制器固件的HID类描述符定义及专用的数据结构和对象变量

对于自定义的USB总线HID设备,必须重新构建Report报表描述符[3]。图4是控制器HID协议报表描述符的基本结构,包括输入报告和输出报告,有效数据报文包含8个字单元,每个字单元由8个二进制位(1个字节)组成。报表描述符定义好后在HID设备的接口描述符和端点描述符进行传输方式定义,接口描述符的bNumEndpoints,bInterfaceClass和bInterfaceProtocol字段分别定义控制器端点数目、HID设备类别以及HID交互协议。

图4 控制器USB HID接口协议报表描述符的基本结构

控制器STM32硬件的固件程序使用三个数据结构处理USB通讯事务,分别是:①DEVICE_INFO,保存USB请求命令和通讯状态信息;②DEVICE_PROP,USB通讯过程的回调函数,包括控制传输Setup阶段处理,Stage IN和OUT事务处理,获得设备、配置和字符描述符处理;③USER_STANDARD_REQUESTS,一组标准请求回调函数指针,用于定制上位机的标准请求,可编写相应的函数实例化这些指针,也可以设置成NOP_Process系统函数。本控制器系统函数均设置成NOP_Process。控制器固件程序使用STM32开发库定义以上三个数据结构的实例化对象指针变量pInformation,pProperty,pUser_Standard_Requests处理USB通讯。在STM32的USB总线的中断处理USB_LP_CAN1_RX0_IRQHandler中调用CTR_LP中断服务函数,中断服务函数内部这三个指针指向结构体对象完成控制传输过程。

3.3 控制器固件软件主控程序设计

多功能控制器固件主控程序流程如图5所示。控制器分别使用中断模式的端点1(管道EP1)、端点2接收和发送数据。在端点1的中断服务中如果接收到一串长度和格式符合要求的数据,即作为一条控制消息,将其放入一个消息队列。在主程序中使用一个while循环任务作为后台主线程程序,主线程程序首先检测消息队列是否为空,如果不为空,则从队列中读取一条控制消息,对控制消息进行CRC校验,如果CRC校验成功,则将控制消息里命令参数赋值给控制寄存器,然后在后续的过程中根据控制寄存器的值运行PWM控制程序、AD采样程序、GPIO读写程序等子模块。

图5 多功能控制器固件主控程序流程图

4 上位机对USB HID控制器读写程序设计

针对本USB HID接口多功能控制器,上位机软件使用API函数实现USB HID功能,在Windows环境下可以调用hid.lib,hidclass.lib,hidparse.lib和setupapi.lib四个接口库完成,而在Linux环境下可使用libusb调用libusb-1.0.so.0.1.0库完成。限于篇幅,以下介绍Windows环境下上位机实现USB HID功能编程的方法。

在Windows环境下编程时程序中需要hidsdi.h和setupapi.h两个头文件。调用这两个头文件必须按照C语言的调用规则。Windows环境下上位机对USB HID接口控制器读写流程如图6所示。首先找到HID设备的GUID,调用后获得HID设备的指针,然后找到单个HID设备的信息,调用后使用CreaeFile函数按照设备路径打开,设备打开后读出设备属性,然后根据设备属性找到设备属性中符合控制器ID(VID和PID)的设备,针对满足条件的设备重新使用CreateFile函数调用两次,建立读写句柄hReader和hWriter。以上过程是通过调用hidsdi.h和setupapi.h头文件里面的HidD_GetHidGuid,SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiEnumDeviceInterfaceDetail等一系列API函数实现的。设备检测过程中,因为USB从机设备最多有127个,因此设备遍历检测计数设置为127,即可保证全部HID设备属性被检测到。在主机的读写进程中直接调用ReadFile和WriteFile函数实现对控制器的读写,hReader和hWriter句柄是关键参数。

图6 上位机对USB HID接口控制器读写流程图

5 实验验证

在验证实验中,USB HID接口控制器和主机之间的数据流管道配置如图7所示。主机通过EP0端点的控制传输方式对控制器进行枚举和初始化;设备的端点1(管道EP1)用于接收主机实际控制信息,端点2(管道EP2)用于设备数据读出,EP1,EP2工作采用中断传输方式。控制器数据包的大小采用8个字节,控制器和主机之间采用短数据包的形式保证控制器响应的敏捷性,每个控制输出事务和状态读取的输入事务均包含8个字节的有效数据。

图7 控制器和主机之间数据流管道配置

实验验证用的处理器型号是STM32F103C8T6。图8是USB HID接口控制器实际硬件电路和系统测试实验图。外部测试硬件使用一个LED光源,通过PWM接口控制LED恒流源驱动器输出。

(a)实际硬件电路

图9是示波器显示的USB HID接口控制器PWM信号输出的实际波形,其中(a)为50%占空比,(b)为80%占空比,硬件根据控制要求改变PWM信号的占空比。图10是控制器通过PWM信号控制LED光源获得的实验数据,横坐标为PWM信号的占空比(ratio),其范围从0.05到1.0(较小数据没有显示),纵坐标为LED工作电流值。LED的驱动电路使用LM3409恒流源驱动芯片,在实验过程中上位机向控制器下发占空比(ratio)和频率参数,然后控制器根据这两个参数生成PWM信号,PWM信号控制LED光源驱动芯片输出的开关,从而调节LED光源的亮度。选择2 kHz和8 kHz的PWM信号频率进行测试,由图10可知,当选择较高频率(8 kHz)PWM信号时,LED调节的范围较大,较小的占空比也有电流输出,LED电流输出最小值可以小于1 mA,可见控制器可以很方便地实现一个宽范围的控制过程。控制器硬件平均工作电流为135 mA,功耗低、性能稳定,数据测试过程中上位机输出100%成功。系统经过24 h长时间测试,能够稳定运行。

(a)通道1(50%的占空比)

图10 控制器通过PWM信号控制LED光源图示(改变占空比获得电流输出)

6 结论和展望

本文提出了一种基于STM32硬件的USB HID接口多功能控制器设计方案,主机和USB设备之间采用控制管道、读管道和写管道等相互独立的多个传输管道实现控制数据的读写。通过重新定义USB HID报表描述符和设备与主机之间的双向通讯控制流程,实现了可编程变频PWM信号控制、GPIO读入和输出、模拟量AD采集多种功能。实验验证的结果表明,系统使用灵活,反应快速,可以稳定运行。

此控制器可以在跨平台操作系统的主机下使用,安装和部署方便,且免驱安装,可用于机器视觉系统、生产测试、工业测控自动化、仪器仪表、边缘计算、可穿戴设备等领域,具备运算处理能力强、功耗小、使用和维护成本低等优点,而且为应对智能传感器大数据控制的需求,此控制器可以通过增加USB接口设置、修改包长、升级USB协议版本来满足数据流传输的要求,因此具有良好的应用价值。

猜你喜欢

描述符固件端点
例谈求解“端点取等”不等式恒成立问题的方法
基于AKAZE的BOLD掩码描述符的匹配算法的研究
不等式求解过程中端点的确定
欧洲共同语言参考标准在中国高校学术英语写作教学适用性的研究:可理解性,可行性和有用性
基于深度学习的局部描述符
一种基于PCIE总线的改进分散集聚DMA的设计
基于固件的远程身份认证
谷歌公司推出计算机固件分析工具帮助用户阻止恶意软件入侵
基丁能虽匹配延拓法LMD端点效应处理
英特尔发布免费固件引擎