打印
[STM32F1]

STM32Cube的USB_device软件库说明

[复制链接]
847|53
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32F1 的 USB 特性
  STM32F1 的 USB 外设实现了 USB2.0 的接口和 APB1 总线间的接口。它有以下特性:

符合 USB2.0 全速设备的技术规范
可配置 1 到 8 个 USB 端点
CRC(循环冗余校验)生成/校验,反向不归零(NRZI)编码/解码和位填充
支持同步传输
支持批量/同步端点的双缓冲区机制
支持 USB 挂起/恢复操作
帧锁定时钟脉冲生成

STM32F1的 USB 外设使用标准的 48Mhz 时钟,允许每个端点有独立的缓冲区,每个端点最大为 512 字节缓冲,最大 16 个单向或 8 个双向端点。USB 的传输格式由硬件完成,状态可以由寄存器标记,可以很大程度上简化我们的程序设计。USB模块启动时间tSTARTUP最大为1us, 这个需要在编程时注意。


ST 官方 Cube 库中提供的 官方 USB 协议栈,主要是包含了 USBD 内核 与 USB 各种类。USBD内核 一般是固定的,用户一般不需要修改,但 USBD类,如果用户需要修改或者扩展,比如复合设备或者用户自定义设备,则需要用户自行修改。
  USB 协议栈将所有 USB 类都抽象成一个数据结构:USBD_ClassTypeDef,USBD 内核与USBD 类之间的纽带就是 USBD_ClassType 这个结构体。这个结构体是一个抽象类,定义了一些虚拟函数,比如初始化,反初始化,类请求指令处理函数,端点 0 发送完成,端点 0 接收处理,数据发送完成,数据接收处理,SOF 中断处理,同步传输发送未完成,同步传输接收未完成处理等等;用户在实现自己具体的 USB 类的时候需要将它实例化,USBD_ClassTypeDef 结构体是 USBD 内核提供给外部定义一个 USB 设备类的窗口,而 USB 类文件实际就是实现这个结构体具体实例化的过程。最后将这个具体实例化的对象注册到 USBD 内核的同时,USBD 内核 与 USBD 类也进行了关联。



使用特权

评论回复
沙发
而服务器人|  楼主 | 2024-3-30 22:38 | 只看该作者
USB 设备库
USB 设备库:

• 支持多包传输特性:不需按最大包尺寸划分,即可发送大量数据。
• 支持控制端点上最多 3 个双向传输 (兼容 OHCI 控制器)。
• 无需更改库代码 (只读),使用配置文件更改内核和库配置。
• 包括 32 位对齐数据结构体以处理高速模式中基于 DMA 的传输。
• 支持用户级别的多 USB OTG 内核实例 (配置文件)。

注 :   USB 设备库可与 RTOS 共用或单独使用;CMSIS RTOS 封装的作用是对 OS 内核抽象。
   USB 设备样例不显示消息。

使用特权

评论回复
板凳
而服务器人|  楼主 | 2024-3-30 22:40 | 只看该作者
USB 设备库架构
USB 设备库主要分为三层,应用在这三层之上。

第一层主要包含两部分:内核 和 类驱动 。

• 内核包含四个主要模块:

USB 内核模块:提供本级 API、管理内部 USB 设备库状态机、处理 USB 中断的回调
USB 请求模块:处理 USB 标准协议中第 9 章所规定的请求
USB I/O 请求模块:处理底层 I/O 请求
USB 日志和调试模块:遵循调试级别 USB_DEBUG_LEVEL,输出用户、日志、错误和调试消息。
• USB 设备库包括一组预定义的类驱动,可通过 USBD_RegisterClass () 程序链接至 USB内核。

  USB 设备库为兼容 USB 2.0 的通用 USB 设备栈,与所有 STM32 USB 内核兼容,由于配置封装文件解除了 USB 库与底层驱动的依赖关系,因此它可轻松链接至任何 USB HAL 驱动。




使用特权

评论回复
地板
而服务器人|  楼主 | 2024-3-30 22:40 | 只看该作者
USB OTG 硬件抽象层
  可使用底层驱动将 USB OTG 内核与高层栈连接起来。


底层(底层 USB 驱动)为设备和 OTG 模式提供了通用 API:每种模式中的内核初始化及对传输流的控制
外设控制器驱动 (PCD)层提供了访问设备模式及此模式中处理中断程序的 API。
OTG 控制器驱动 (OTG)层提供了访问 OTG 模式及此模式中处理中断程序的 API。

使用特权

评论回复
5
而服务器人|  楼主 | 2024-3-30 22:44 | 只看该作者
USB 驱动编程手册
5.1 设备初始化
使用 stm32fxxx_hal_pcd.c 文件中的下述函数初始化设备:

HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
1
5.2 端点配置
  USB 内核初始化之后,上层可能调用底层驱动,打开或关闭激活端点,开始传输数据。使用下列两个 API:
//ep_addr、 ep_mps 和 ep_type 分别为端点地址、最大数据传输和传输类型。
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)

使用特权

评论回复
6
而服务器人|  楼主 | 2024-3-30 22:45 | 只看该作者
/* USB Device handle structure */
typedef struct _USBD_HandleTypeDef
{
  uint8_t                 id;
  uint32_t                dev_config;  // dev_config 保存着当前 USB 设备配置
  uint32_t                dev_default_config;
  uint32_t                dev_config_status;
  USBD_SpeedTypeDef       dev_speed;
  USBD_EndpointTypeDef    ep_in[16];
  USBD_EndpointTypeDef    ep_out[16];
  uint32_t                ep0_state;  // ep0_state 控制着状态机
  uint32_t                ep0_data_len;
  uint8_t                 dev_state;  // dev_state 定义了连接、配置和上电状态
  uint8_t                 dev_old_state;
  uint8_t                 dev_address;
  uint8_t                 dev_connection_status;
  uint8_t                 dev_test_mode;
  uint32_t                dev_remote_wakeup;

  USBD_SetupReqTypedef    request;
  USBD_DescriptorsTypeDef *pDesc;
  USBD_ClassTypeDef       *pClass;
  void                    *pClassData;
  void                    *pUserData;
  void                    *pData;
} USBD_HandleTypeDef;

使用特权

评论回复
7
而服务器人|  楼主 | 2024-3-30 22:45 | 只看该作者
//在此结构体中, dev_state 定义了连接、配置和上电状态:
/*  Device Status */
#define USBD_STATE_DEFAULT                              0x01U
#define USBD_STATE_ADDRESSED                            0x02U
#define USBD_STATE_CONFIGURED                           0x03U
#define USBD_STATE_SUSPENDED                            0x04U


/*  EP0 State */
#define USBD_EP0_IDLE                                   0x00U
#define USBD_EP0_SETUP                                  0x01U
#define USBD_EP0_DATA_IN                                0x02U
#define USBD_EP0_DATA_OUT                               0x03U
#define USBD_EP0_STATUS_IN                              0x04U
#define USBD_EP0_STATUS_OUT                             0x05U
#define USBD_EP0_STALL                                  0x06U

#define USBD_EP_TYPE_CTRL                               0x00U
#define USBD_EP_TYPE_ISOC                               0x01U
#define USBD_EP_TYPE_BULK                               0x02U
#define USBD_EP_TYPE_INTR                               0x03U

使用特权

评论回复
8
而服务器人|  楼主 | 2024-3-30 22:46 | 只看该作者
USB 数据传输流程
  PCD 层提供所需的所有 API,可启动及控制传输流,见下列函数:
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)


 PCD 层有一个函数必须被 USB 中断调用:

void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
1
  stm32fxxx_hal_pcd.h 文件包含了库内核层处理 USB 事件时调用的函数原型。

使用特权

评论回复
9
而服务器人|  楼主 | 2024-3-30 22:50 | 只看该作者
本帖最后由 而服务器人 于 2024-3-30 22:52 编辑

USB 设备库概述
  USB 设备库基于通用 USB 底层驱动开发,可在全速和高速模式中工作。
  它实现了USB 2.0版本定义的USB设备库状态机。此模块功能由USB设备库固件包中"Core" 目录下的文件提供 。USB 类模块为类层,与协议规范兼容。




使用特权

评论回复
10
而服务器人|  楼主 | 2024-3-30 22:51 | 只看该作者


USB 设备库描述
6.1.1 USB 设备库流程
处理控制端点 0
  USB 规范定义了四种传输类型:控制传输、中断传输、批量传输和同步传输。USB 主机通过控制端点向设备发送请求(在这种情况下,控制端点为端点 0)。 请求作为 SETUP 包发送到设备。这些请求可分为三类:标准、特定类、特定厂商。因为标准请求对所有 USB 设备都是通用的,所以库可收到和处理控制端点 0上的所有标准请求。
  特定类和特定厂商请求的格式和意义并不对所有 USB 设备通用。
  所有 SETUP 请求都由处于中断模式的状态机处理。 USB 正确传输的末尾会产生一个中断。库代码收到该中断。在中断处理程序中,触发端点被识别。如果事件为端点 0 上的设置,则保存所收到设置的参数且启动状态机。

非控制端点上的事务
  特定类内核使用非控制端点,方法是通过数据 IN 和 OUT 阶段回调,调用一组函数发送或接收数据。

使用特权

评论回复
11
而服务器人|  楼主 | 2024-3-30 22:52 | 只看该作者
SETUP 包的数据结构
  当一个新的 SETUP 包到达时, SETUP 包的所有八个字节都被复制到一个内部结构体USB_SETUP_REQ req,因此在处理期间,下一个 SETUP 包不会覆盖前一个包。此内部结 构体定义为:

typedef  struct  usb_setup_req
{
  uint8_t   bmRequest;
  uint8_t   bRequest;
  uint16_t  wValue;
  uint16_t  wIndex;
  uint16_t  wLength;
} USBD_SetupReqTypedef;

使用特权

评论回复
12
而服务器人|  楼主 | 2024-3-30 22:57 | 只看该作者
标准请求
  下面 USB 规范表中的大多数请求都作为库中的标准请求处理。该表列出了所有标准请求及其库中的有效参数。此表中没有的请求则认为非标准请求。注 : 在列状态中:D = 默认状态; A = 地址状态; C = 配置状态; All = 全部状态。EP: D0-D3 = 端点地址; D4-D6 = 保留为零; D7= 0: OUT 端点, 1:IN 端点。

非标准请求
所有非标准请求都通过回调函数传至特定类的代码。

使用特权

评论回复
13
而服务器人|  楼主 | 2024-3-30 22:57 | 只看该作者
SETUP 阶段
  库传递所有非标准请求到特定类的代码,回调为pdev->pClass->Setup (pdev, req)函数。 非标准请求包括用户解释请求和无效请求。用户解释请求为特定类请求、特定厂商请求,或库认为无效但应用欲解释为有效的请求。
  无效请求为非标准请求、非用户解释请求。因为 pdev->pClass->Setup (pdev, req) 在 SETUP 阶段后、数据阶段前调用,所以用户代码应负责在 pdev->pClass->Setup (pdev, req) 中解析 SETUP 包的内容(req)。若请求无效,则用户代码必须调用 USBD_CtlError(pdev , req),并返回 pdev->pClass->Setup (pdev, req) 的调用者对于用户解释请求,如果请求有数据阶段,用户代码应为后续数据阶段准备数据缓冲;否则用户代码执行请求,返回 pdev->pClass->Setup (pdev, req) 的调用者。

DATA 阶段
  类层使用标准 USBD_CtlSendData 和 USBD_CtlPrepareRx 发送或接收数据,数据传输流由库内部处理,用户不需要将数据切分为 ep_size 大小的包。

使用特权

评论回复
14
而服务器人|  楼主 | 2024-3-30 23:00 | 只看该作者
状态阶段
当从 pdev->pClass->Setup (pdev, req) 回调返回之后,状态阶段由库处理。

  如图7: USB设备库处理流程图中所示,USB编程只需要三个模块:USB库、USB类和主应用。
主应用执行用户定义程序,main.c、stm32fxx_it.c、usbd_conf.c 和 usbd_desc.c 及其头文件为用户开发自己的应用时的主要文件(应用强制),用户可根据应用对其修改 (类驱动) 。

  若需初始化 USB HAL 驱动、 USB 设备库、和板级支持包 (BSP)并启动库,用户需调用这 三个 API ( USB 设备库初始化):

USBD_Init ():此函数初始化设备栈,加载类驱动与描述符地址。设备描述符存储于 usbd_desc.c 和 usbd_desc.h (用于配置描述符类型)文件中。
USBD_RegisterClass():此函数将类驱动链接到设备内核。
USBD_Start():此函数允许用户开启 USB 设备内核。

使用特权

评论回复
15
而服务器人|  楼主 | 2024-3-30 23:00 | 只看该作者
USB 设备数据流程
  因为 USB OTG 内核支持多包特性,所以在需要封装来管理控制端点上的多包特性时, USB 库 (USB 内核和 USB 类层) 通过 IO 请求层处理端点0 (EP0)上的数据处理,当其它端点被使用时,直接从 stm32fxxx_hal_pcd 层处理。下图显示了该数据流方案。

使用特权

评论回复
16
而服务器人|  楼主 | 2024-3-30 23:01 | 只看该作者
具有底层驱动的内核接口
  如前面所述,底层接口层为 STM32Cube HAL 的链接层, USB 设备库用其与STM32Cube HAL 底层驱动接口。
  底层接口实现了底层 API 函数,在 USB 事件后调用库内核回调函数。
在 STM32Cube 解决方案中,因为底层接口的一些部分依赖于板子和系统,所以底层接口的实现作为 USB 设备样例的一部分提供。
下表列出了底层 API 函数:
  注 : 这些 API 由 USB 设备配置文件 (usbd_conf.c)提供。用户应在用户文件中实现,适配到USB 设备控制器驱动。


使用特权

评论回复
17
而服务器人|  楼主 | 2024-3-30 23:01 | 只看该作者
USB 设备库接口模型
  USB 设备库是由通用可移植的 USB 设备内核和类模块构建而成。


使用特权

评论回复
18
而服务器人|  楼主 | 2024-3-30 23:02 | 只看该作者
下面是在 USB 事件后,底层接口调用的设备库回调函数。

使用特权

评论回复
19
而服务器人|  楼主 | 2024-3-30 23:02 | 只看该作者
配置 USB 设备固件库
  可使用 usbd_conf.h 文件配置 USB 设备库。
  usbd_conf.h 为特定的配置文件,用于定义一些全局参数及特定配置。usbd_conf.c 文件为接口文件,用于将上层库与 HAL 驱动和 BSP 驱动链接起来。


注 : 用户可从 STM32Cube 提供的usbd_conf.h 文件开始。此文件也可复制到应用目录,根据应用需求修改。
  注 : 默认情况下,对于 USB 设备样例,库与用户消息并不会显示在 LCD上。
  但是用户可实现自己的消息 (若要将库消息重定向到 LCD 屏幕上,需将lcd_log.c 驱动添加到应用源中)并可选择是否显示,这可通过符合应用要求的方式修改配置文件“usbd_conf.h” 中的 USBD_DEBUG_LEVEL 实现,该文件位于项目的包含目录下,修改方式为:
  0:无日志 / 调试消息
  1:使能日志消息
  2:使能日志和调试消息

使用特权

评论回复
20
而服务器人|  楼主 | 2024-3-30 23:02 | 只看该作者
USB 控制功能
  用户应用可受益于 USB 设备中包含的一些 USB 功能,例如:
  设备复位 当设备从 USB 收到复位信号时,库会复位,并初始化软硬件上的应用。此函数为中断程序的一部分。
  设备挂起 当设备检测到 USB 上的挂起条件,库会停止所有操作,并将系统置于挂起状态(前提条件为 usbd_conf.c 文件中使能了低功耗模式管理)。
  设备重新开始 当设备检测到 USB 上的重新开始信号时,库会恢复 USB 内核时钟并将系统置于空闲状态 (前提条件为 usbd_conf.c 文件中使能了低功耗模式管理)。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

218

帖子

0

粉丝