发新帖我要提问
123
返回列表
打印
[STM32F1]

STM32Cube的USB_device软件库说明

[复制链接]
楼主: 而服务器人
手机看帖
扫描二维码
随时随地手机跟帖
41
而服务器人|  楼主 | 2024-3-30 23:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
音频内核文件 usbd_audio (.c, .h)
  usbd_audio (.c, .h)此驱动为音频内核。它管理音频数据传输并控制请求。它不直接处理音频硬件 (由底层驱动管理)。

使用特权

评论回复
42
而服务器人|  楼主 | 2024-3-30 23:08 | 只看该作者
底层硬件接口通过它们相应的驱动结构体管理:

typedef struct
{
  int8_t (*Init)(uint32_t  AudioFreq, uint32_t Volume, uint32_t options);
  int8_t (*DeInit)(uint32_t options);
  int8_t (*AudioCmd)(uint8_t *pbuf, uint32_t size, uint8_t cmd);
  int8_t (*VolumeCtl)(uint8_t vol);
  int8_t (*MuteCtl)(uint8_t cmd);
  int8_t (*PeriodicTC)(uint8_t cmd);
  int8_t (*GetState)(void);
} USBD_AUDIO_ItfTypeDef;


使用特权

评论回复
43
而服务器人|  楼主 | 2024-3-30 23:08 | 只看该作者
每个音频硬件接口驱动都应该提供一个类型为USBD_AUDIO_ItfTypeDef的结构体指针。(下边的章节会写该结构体所指向的函数和变量)。如果给定的存储器接口不支持某功能,则相应的字段置为 NULL 值。

usbd_audio_if (.c, .h)
  usbd_audio_if (.c, .h)此驱动管理底层音频硬件。 usbd_audio_if.c/.h 驱动管理音频输出接口 (从 USB 到音频扬声器 / 耳机)。用户可调用底层编解码器驱动(即 stm324xg_eval_audio.c/.h)以进行基本的音频操作 (播放 / 暂停 / 音量控制…)。
此驱动提供了结构体指针:

/** AUDIO_IF Interface callback. */
extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_fops_FS;

使用特权

评论回复
44
而服务器人|  楼主 | 2024-3-30 23:09 | 只看该作者
usbd_audio_if (.c,.h)文件中函数说明。


使用特权

评论回复
45
而服务器人|  楼主 | 2024-3-30 23:09 | 只看该作者
通过下列状态列表来获得当前音频播放器的状态:

使用特权

评论回复
46
而服务器人|  楼主 | 2024-3-30 23:09 | 只看该作者
怎样使用此驱动:
  此驱动使用了硬件驱动的抽象层(即 HW 编解码器、I2S 接口、I2C 控制接口 …)。此抽象通过底层 (即 usbd_audio_if.c)执行,您可根据您的应用以及相应的硬件对其修改。
若要使用此驱动:
通过文件 usbd_conf.h,您可配置:

音频采样率 (定义 USBD_AUDIO_FREQ)
  在启动时调用函数 USBD_AUDIO_Init(),配置所有必要的固件和硬件部件(特定应用的硬件配置函数也由此函数调用)硬件部件由底层接口 (即usbd_audio_if.c)管理,可由用户根据 应用需要修改。
整个传输由下述函数管理 (用户不需为输出传输调用任何函数):

usbd_audio_DataIn()和usbd_audio_DataOut()使用收到的或发送的数据更新音频缓冲。对于输出传输,当收到数据时,它们会被直接复制到音频缓冲中,写缓冲 (wr_ptr)增加。
  音频控制请求由函数 USBD_AUDIO_Setup() 和USBD_AUDIO_EP0_RxReady() 管理。这些函数会将音频控制请求路由至底层 (即 usbd_audio_if.c) 。在当前版本中,仅管理了SET_CUR 和 GET_CUR 请求,仅用于静音控制。

使用特权

评论回复
47
而服务器人|  楼主 | 2024-3-30 23:09 | 只看该作者
音频的已知限制
  如果配置了低音频采样率(将USBD_AUDIO_FREQ定义为24 kHz以下),则在暂停/重新开始 / 停止操作时可能导致噪声问题。这是由于在停止 I2S 时钟和发送静音指令到外部编解码器之间的软件时序调节。
  支持的音频采样率为:96 kHz到24 kHz(此驱动不支持非整数kHz值,例如11.025 kHz、22.05 kHz 或 44.1 kHz)。对于 1000 Hz 的整数倍数频率,主机会在每帧 (1 ms)发送 整数个字节。当频率不是 1000Hz 的整数倍时,主机会在每帧发送非整数个字节。实际上,这是通过发送不同大小的帧来管理的 (即对于 22.05 kHz,主机将发送 19 帧的 22 字节和一帧的 23 字节)。音频内核不会管理此大小差别,多余的字节会一直被忽略。建议设置高采样率和标准采样率,以得到最好的音频质量 (即 96 kHz 或 48 kHz)。请注意,最大允许的音频频率为 96 kHz(此限制的原因是评估板上使用的编解码器。STM32 I2S 单元可达到 192 kHz)。

使用特权

评论回复
48
而服务器人|  楼主 | 2024-3-30 23:10 | 只看该作者
通信设备类 (CDC)
添加自定义类
库大小优化
  在本节中,我们回顾一些基本技巧,涉及怎样优化 USB 设备库之上开发的应用大小。
  缩小 USB 样例是一个重要的目标,尤其对于具有较少 Flash/RAM 内存的 STM32 产品 (如STM32 L0 和 F0)来说尤其重要。

降低堆和栈大小设置 (在连接 (linker)文件中)
栈为程序存储的内存区,例如:

本地变量
返回地址
函数参数
编译器临时量
中断上下文
  如果您的连接器配置保留了大量的堆和栈,而您的应用并不需要,您可以决定其合适的大小。

尽可能使用局部变量,而不用全局变量
  如果一个变量仅在一个函数中使用,那么应在函数内将其声明为局部变量。

使用特权

评论回复
49
而服务器人|  楼主 | 2024-3-30 23:10 | 只看该作者
常量应在闪存中分配
  建议将永不变化的所有常量全局变量分配至只读区。例如,使用 C 关键字 “const” 将 USB 描述符声明为常量。
例如:

使用特权

评论回复
50
而服务器人|  楼主 | 2024-3-30 23:11 | 只看该作者
使用静态内存分配,而不是 malloc
  USB 设备库为类处理结构体使用动态内存分配以支持多实例 (在双核工作情况下),这意味着我们可以将同一 USB 类用于 USB 的两个实例 (HS 和FS)。
  使用动态分配的第二个原因是当 USB 不再使用时,可释放内存。然而,动态内存分配会增加一些空间上的开销,主要是 ROM 内存。因此,对于低内存 STM32设备,当不需要多实例支持时,建议使用静态分配。在这种情况下,需要声明静态缓冲,大小为类处理结构体的大小。

下面是一个实现样例:

在 usbd_conf.h 文件中,定义内存静态分配和程序;
USBD_static_malloc() 和 USBD_static_free()
#define MAX_STATIC_ALLOC_SIZE 4 /* HID */ 类类类类类类
#define USBD_malloc (uint32_t *)USBD_static_malloc
#define USBD_free USBD_static_free


在 usbd_conf.c 文件中如下实现:
/**
  * @brief  Static single allocation.
  * @param  size: Size of allocated memory
  * @retval None
  */
void *USBD_static_malloc(uint32_t size)
{
  /* static uint8_t mem[sizeof(USBD_AUDIO_HandleTypeDef)]; */
  /* USER CODE BEGIN 4 */
  /**
  * To compute the request size you must use the formula:
    AUDIO_OUT_PACKET = (USBD_AUDIO_FREQ * 2 * 2) /1000)
    AUDIO_TOTAL_BUF_SIZE = AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM with
        Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure
    that it is an even number and higher than 3
        AUDIO_OUT_PACKET_NUM = 80
  */
  static uint8_t mem[512];
  /* USER CODE END 4 */
  return mem;
}

/**
  * @brief  Dummy memory free
  * @param  p: Pointer to allocated  memory address
  * @retval None
  */
void USBD_static_free(void *p)
{

}

使用特权

评论回复
51
而服务器人|  楼主 | 2024-3-30 23:11 | 只看该作者
常见问题
1. 怎样在运行时修改设备和字符串描述符 ?
  在 usbd_desc.c 文件中,可使用 Get Descriptor 回调修改设备和字符串相关的描述符。 应用可使用 switch case 语句,返回应用索引相关的正确描述符缓冲。

2. 大容量存储类怎样支持超过一个逻辑单元 (LUN) ? (略)
3. 端点地址在哪里定义 ?
  端点地址在类驱动的头文件中定义。例如,对于 MSC 演示,IN/OUT 端点地址如下定义在 usbd_msc.h 文件中:

#define MSC_EPIN_ADDR 0x81 For Endpoint 1 IN
#define MSC_EPOUT_ADDR 0x01 For Endpoint 1 OUT

使用特权

评论回复
52
而服务器人|  楼主 | 2024-3-30 23:11 | 只看该作者
USB 设备库可配置为在高速或全速模式运行吗?
  是的,库可处理 USB OTG HS 和 USB OTG FS 内核,如果 USB OTG FS 内核仅能工 作于全速模式, USB OTG HS 可工作于高速或全速模式。若要选择合适的 USB 内核,用户必须在编译预处理器内增加下列宏定义 (在样例提供的预配置项目中已经完成):

- "USE_USB_HS" 当使用 USB 高速 (HS)内核时
- "USE_USB_FS" 当使用 USB 全速 (FS)内核时
- "USE_USB_HS" 和 "USE_USB_HS_IN_FS" 当在 FS 模式使用 USB 高速(HS)内核时

使用特权

评论回复
53
而服务器人|  楼主 | 2024-3-30 23:12 | 只看该作者
怎样在 USB 设备类驱动中更改所用的端点?
若要更改端点或增加一个新端点,请:
a) 使用 USBD_LL_OpenEP() 执行端点初始化。
b) 对于在 USBD_LL_Init() 函数中使用这些 API 的 usb_conf.c 文件,配置新定义端点的 TX 或 Rx FIFO 大小。

对于 STM32F2 和 STM32F4 系列 (FS 和 HS 内核):
HAL_PCD_SetRxFiFo();
HAL_PCD_SetTxFiFo();

  Rx 和 Tx FIFO 的总大小应该小于所用内核的总 FIFO 大小(对于 USB OTG FS 内核,为 320 x 32 比特;对于 USB OTG HS 内核,为 1024 x 32 比特)。

对于 STM32F0、 STM32L0、 STM32F1 和 STM32F3 系列 (仅 FS 内核):
HAL_PCD_PMA_Config();

使用特权

评论回复
54
而服务器人|  楼主 | 2024-3-30 23:12 | 只看该作者
USB 设备库与实时操作系统 (RTOS)兼容吗 ?
  是的,USB 设备库可与 RTOS 共用使用,CMSIS RTOS 封装的作用是对 OS 内核抽象。

使用特权

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

本版积分规则