你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

实战经验 | 基于 STM32U5 创建 USBx_CustomHID 通信

[复制链接]
STMCU-管管 发布时间:2024-4-22 15:20
1. 前言
2 S3 Y- U! o6 I- t4 l# R! I, m某客户在使用 STM32U5 开发一款产品时需要使用到 USB Custom 进行双向通信,并反馈 STM32U5 使用的是 Azure USBx 协议栈,不再支持 ST USB device 库。客户表示只熟悉 ST USB Device 库,对 USBx 协议栈与 API 没有任何使用经验。查阅目前所有 USBx 的例程,发现 目前 USBx 均没有可参考的 Custom HID 双向通信范例,客户希望提供使用 USBx HID 进行双 向通信的例程,这里简单介绍下利用 CubeMx 创建工程的实现过程。
2 I9 n$ b* z. s$ [4 L) N# @# C
, M/ c- v: _0 m$ ^) m
9 k/ f* v) n3 X5 e6 u
2. USB 双向通信的几个基本知识点
5 r: j3 @2 h7 ~% Q+ {* f; F0 O首先,我们回顾一下 USB2.0 设备端与主机通信的基本原理及数据流,如下图所示。
' {3 Z; g! a$ H* K: F

USB 双向通信的几个基本知识点

USB 双向通信的几个基本知识点
设备描述符:向主机提供 USB 版本信息、支持的协议、供应商标识(VID)、产品标识(PID)、及制 造商和产品字符串,支持的配置数量等信息。( \8 {; F) {4 \% h! s0 B
配置描述符:提供特定设备配置的信息,如接口数量、设备由总线供电还是自供电、设备能否启 动一个远程唤醒以及设备功耗。
& `% @: u: P) Q% s+ Y8 h! L接口描述符:对配置描述符中的接口信息进行描述,主要包括了接口号、类型以及该接口中的端 点(Endpoints)数量等信息。 2 [4 }! v3 {2 ?8 v( G. `( Y9 V& E
端点描述符 :用于向主机提供端点信息,主要包括了端点方向(IN/OUT)、传输类型(中断、批量 bluck、同步、控制)以及数据包最大长度等信息。 + R+ e8 z& {; h! [+ T* U
: x5 t2 T# k. B' N% y" |! V' I1 Z
' I% Z8 `9 R9 s7 c
3. USBx HID 设备端 API 介绍 $ J' m; [) k, ]/ c! t
USBx Device 协议栈内部实现了一套复杂的基于事件和消息驱动机制的数据流传输和控制传 输逻辑,用户 Application 只需要使用其提供的 APIs 即可实现 USB 通信。USBx Device Stack 所提供的 APIs 如下:
& a/ l* `+ T- u& D- _  S9 A7 v/ F

系统外设、USB、USBx、Threadx 的添加和基础配置

系统外设、USB、USBx、Threadx 的添加和基础配置

5 m9 y/ V% S1 m; ^. a
- \# I3 t4 W1 v$ J5 L. U5 E4 @. X3 d
4. USBx 实现 Custom HID 双向通信的步骤 ! V& p3 T8 K4 D
(一) 系统外设、USB、USBx、Threadx 的添加和基础配置
8 k3 ~. i$ @5 N下面我们就使用 NUCELO-U575ZI-Q 基于前面所讲的 USBx Device stack APIs 来实现 USB HID 双向通信。使用 STM32CubeMX 创建如下工程,工程基本配置如下。
1 _9 c7 y* ?" [2 {

系统外设、USB、USBx、Threadx 的添加和基础配置

系统外设、USB、USBx、Threadx 的添加和基础配置
USB 和 RCC 时钟系统配置如下:6 g& x7 ], u+ l3 |+ |7 b, n! |- D

USB 和 RCC 时钟系统配置如下

USB 和 RCC 时钟系统配置如下
配置 NUCLEO-U575-Q 为 SMPS 供电模式
6 U' |) w% |+ a0 M$ E2 |; M  o. {

配置 NUCLEO-U575-Q 为 SMPS 供电模式

配置 NUCLEO-U575-Q 为 SMPS 供电模式

. z# j1 r# Z- l+ @

5 h  j# ~+ P: Q配置 USB 引脚及中断功能5 `6 t" b# i7 V( _1 Z+ D5 V0 u

配置 USB 引脚及中断功能

配置 USB 引脚及中断功能
添加 ThreadX RTOS 协议栈 5 Q2 E4 [* Y* f) Q* }

添加 ThreadX RTOS 协议栈

添加 ThreadX RTOS 协议栈
添加 USBx 协议栈支持并配置协议栈1 h, J6 b  D6 W) ^
添加 USBx 协议栈支持并配置协议栈1.png
添加 USBx 协议栈支持并配置协议栈2.png
添加 USBx 协议栈支持并配置协议栈3.png
" k; s; j+ ]# `

+ n5 o- \5 E# X( P设置 MX_USB_OTG_FS_PCD_Init 在 main()中不进行调用,并保存工程并生成代码。' @2 s- Y, @1 Q6 k1 ^3 Q

设置 MX_USB_OTG_FS_PCD_Init 在 main()中不进行调用,并保存工程并生成代码

设置 MX_USB_OTG_FS_PCD_Init 在 main()中不进行调用,并保存工程并生成代码
(二) 代码的添加及修改 # e& X& u' O" I, E
本例程目的是实现 USB Custom HID 双向通信。本例程共使用了 3 个 Endpoint,如下:Eendpoint0(控制类型,IN/OUT)、Endpoint1(中断,IN)、Endpoint2(中断,OUT)。Endpoint0:系统默认控制管理端点,用于 Host 对 Device 传输控制和管理命令,如设备描述 符、配置描述符等系统信息进行配置和查询。1 f) Y/ l! c* W6 c1 _& D
Endpoint1:输入(IN)类型端点,用于向 Host 发送数据,在本例程我们创建了一个应用线程 usbx_cutomhid_thread_entry(),以 1S 为周期向 Host 通过 Endpoint1 发送 64 字节的数据包。 3 S. [* M+ Y, F) ?- x; L& p7 }
Endpoint2:输出(OUT)类型端点,用于当 Host 向 device 发送数据时,USBx Stack 会自动调 用 USBD_Custom_HID_SetReport()的回调函数,通过 Endpoint2 来接收 Host 所发送的数据包。 8 X) e) S( d0 ]" R# K# j0 g+ ^
1. 在 app_usbx_devich.h 中包含如下几个头文件。
0 l% Z. H4 @9 t, _( D$ O' Q
在 app_usbx_devich.h 中包含如下几个头文件1.png 在 app_usbx_devich.h 中包含如下几个头文件2.png
2. 在 app_usbx_device.c 中申明和定义如下结构,其中 ux_app_MsgQueue 消息队列用于实现 USB 的动态管理。
/ l" j) ]/ i, C& X  a" e6 I 在 app_usbx_device.c 中申明和定义如下结构,其中 ux_app_MsgQueue 消息队列用于实现.png 在 app_usbx_device.c 中申明和定义如下结构,其中 ux_app_MsgQueue 消息队列用于实现.png ; x: V7 l5 u: z5 a& f! k
3. 在 ux_device_customhid.h/.c 中添加如下申明和定义,并在相关相关函数内分别依次添加下 图所示代码。其中线程 usbx_cutomhid_thread_entry 用于周期性通过 Endpoint1 向 host 发 送 64 字节数据。0 B, X$ E; Q, i7 _+ j( u
通过 Endpoint1 向 host 发 送 64 字节数据1.png
通过 Endpoint1 向 host 发 送 64 字节数据2.png
通过 Endpoint1 向 host 发 送 64 字节数据3.png
通过 Endpoint1 向 host 发 送 64 字节数据4.png
通过 Endpoint1 向 host 发 送 64 字节数据5.png
通过 Endpoint1 向 host 发 送 64 字节数据6.png
通过 Endpoint1 向 host 发 送 64 字节数据7.png
' c0 ~$ X. a- P- a' W) A

6 U! f5 P3 c1 G2 h3 n1 K9 w. A2 S修改 HID SetReport 函数,接收由 PC 机向 OUT 端点(Endpoint2)发送的数据包。' o$ M# e3 D# r5 s

修改 HID SetReport 函数

修改 HID SetReport 函数
在 usbx_customhid_thread_entry 中实现 IN 端点(Endpoint1)向 PC 机 1S 发送一次数据功能。# s' f* S2 M. g: H8 x9 \

在 usbx_customhid_thread_entry 中实现 IN 端点(Endpoint1)向 PC 机 1S 发送一次数据功能

在 usbx_customhid_thread_entry 中实现 IN 端点(Endpoint1)向 PC 机 1S 发送一次数据功能
添加 HID report 描述符,我们使用 USB 官网 HID 报告描述符工具生成自定义 Custom HID report 描述符,该工具可以到网址 https://www.usb.org/document-library/hid-descriptortool 下载。 6 U. Q! L* f# H4 d
根据 USB 规范一个 HID 报告描述符至少应包括如下条目(Items)。/ J) G& j5 F1 t+ L- ~$ G4 _
根据 USB 规范一个 HID 报告描述符至少应包括如下条目(Items)2.png
根据 USB 规范一个 HID 报告描述符至少应包括如下条目(Items)1.png
(三) 功能测试及验证 2 Q- n; L& R6 ]9 R  P3 R
USB 设备端(Device)发送数据测试,在 usbx_customhid_thread_entry()线程里面每 1S 钟 向 Host 发送一包 64Byte 字节数据,然后我们可以在 PC 机端可以看到已成功收到了数据。
" Y- }4 P, r( Z& E( n% |* {
功能测试及验证1.png 功能测试及验证2.png
USB 设备端(Device)接收数据测试,我们在 PC 通过向端点 2 发送数据。在 STM32U5 上通过调试窗口我们可以看到 USB device 已经成功的接收到了数据。" {! p7 S+ k0 W5 U- k2 C! A

USB 设备端(Device)接收数据测试

USB 设备端(Device)接收数据测试
关于利用 STM32U5 创建 USBx_CustomHID 通信的实现过程就介绍到这里,分享出来供有需要的同仁参考。
; W( l5 H1 q2 p7 a, Q1 j; s4 H4 P' D5 `, [

点评

请问我照着本例配置,用电脑通过usb发送0x00~0x63数据,usb接收到的第21到24位接收到的数据一直是0x00、0x00、0x40、0x84是什么情况?  发表于 2024-10-20 16:15
收藏 评论1 发布时间:2024-4-22 15:20

举报

1个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版