ESP32S3 BLE_HID的编程实现

ESP32S3 BLE_HID的编程实现

BLE是低功耗蓝牙,HID是Human Interface Device,也就是人机接口设备。

主要用于无线连接并传输用户输入数据(如按键、触控、手势等)。


核心概念

  1. BLE(Bluetooth Low Energy)
    • 蓝牙4.0及以上版本引入的技术,专为低功耗设计,适合电池供电设备(如键盘、鼠标)。
    • 传输数据量小、连接速度快,功耗仅为传统蓝牙的1/10~1/100。
  2. HID(Human Interface Device)
    • 源自USB HID标准,定义了键盘、鼠标、游戏手柄等设备的通用通信协议。
    • BLE HID将这一协议无线化,无需物理线缆即可实现设备交互。

与传统蓝牙HID的区别

特性传统蓝牙HIDBLE HID
功耗较高极低
连接速度较慢快(毫秒级)
兼容性依赖传统HID协议基于GATT,更现代
适用设备需较高数据速率(如音频)低频输入设备(按键、点击)

协议实现

  • HID Service
    通过GATT(通用属性协议)定义服务,包含以下关键特性:
    • Report Map:描述设备功能(如按键映射)。
    • Input/Output Report:传输实际输入/输出数据。
    • Protocol Mode:切换Boot Protocol(兼容BIOS)或Report Protocol(标准模式)。

代码源自esp-idf例程ble_hidd_demo

执行流程

1image-20250502195507712初始化NVS:(Non-Volatile Storage,非易失性存储)是 ESP-IDF 提供的一种存储机制,用于在设备的闪存中保存数据,即使设备断电后数据也不会丢失。nvs 通常用于存储配置信息、蓝牙配对信息等。释放经典蓝牙模式的内存
2image-20250502195543790初始化BLE控制器->启用蓝牙控制器,设置为BLE模式->初始化Bluedroid协议栈->启用Bluedroid协议栈->初始化HID(Human Interface Device)配置文件
3image-20250502195630852注册回调函数到GAP(Generic Access Profile)模块->注册回调函数到GAP(Generic Access Profile)模块-> 注册回调函数到HID模块->设置BLE安全参数->创建HID任务(用户或自动执行)
4image-20250502195651917BLE广播(等待设备连接esp32s3的低功耗蓝牙)->设备连接BLE->触发连接事件 ->开始配对BLE
5image-20250502195722975设备成功配对BLE ->设置连接成功标志位 ->进入人机交互任务
6image-20250502195729782HID任务循环 ->判断连接状态 -> 发送指令(操作)+数据
配置项目

ble_hidd_demo_main.c:此文件是演示如何使用 HID 的示例(您可以使用它连接到智能手机作为消费者设备,然后使用按钮来增加或减少音量等,或者连接到 Windows 10 PC 作为键盘或鼠标)

hidd_le_prf_int.h:此头文件包含一些与 HID 配置文件相关的定义。

esp_hidd_prf_api.h & esp_hidd_prf_api.c:这些文件包含 HID 配置文件的 API

当您使用 HID 配置文件时,只需添加 esp_hidd_prf_api.h 包含文件,并使用 esp_hidd_prf_api.c 文件中定义的函数发送 HID 数据。

hid_dev.h & hid_dev.c:这些文件定义了 HID 规范相关的定义

hid_device_le_prf.c:此文件是 HID 配置文件的定义文件,它包含 HID 配置文件的主要功能。它主要包含如何创建 HID 服务。如果您发送和接收 HID 数据并将数据转换为键盘键、鼠标和消费者值,则将其转发到应用程序。

整体执行流程

蓝牙初始化:

在主函数中,会初始化蓝牙堆栈并注册 GAP 事件回调函数。

事件处理:

当蓝牙事件发生时,回调函数会根据事件类型执行相应的逻辑。

HID 功能演示:

hid_demo_task 任务会在系统初始化完成后运行,可能会模拟键盘、鼠标或其他 HID 设备的行为。

如果文章对你有所帮助,可以帮我点一下左下角推荐该文,万分感谢

博主目前在广州,深圳找实习。

如有大佬(HR,BOSS)能推荐实习,恳请私信小弟,给个机会,帮帮小弟,万分感谢!!!


__EOF__

原创作者: tianwuyvlianshui 转载于: https://www.cnblogs.com/tianwuyvlianshui/p/18857780
<think>好的,我现在需要帮助用户解决关于ESP32-S3使用ESP-IDF框架自定义修改USB HID报告描述符的问题。首先,我需要回顾之前的对话历史,确保我理解用户的背景和需求。 用户之前询问了`hid_report_desc.h`头文件的来源,我回答了该文件通常是自定义的,并提到了相关的库和组件,如`esp_tinyusb`和`tinyusb`。现在用户的新问题是关于如何自定义修改USB HID报告描述符的具体步骤,需要完整的教程。用户提供的引用内容涉及ESP32HID配置、蓝牙GATT协议、ESP32-S3的硬件连接和服务器端设计,以及经典蓝牙开发中的HID设备例程。这些引用可能为用户提供背景信息,但用户的核心需求是修改HID报告描述符的具体步骤。 首先,我需要明确ESP-IDF框架中HID报告描述符的配置方式。根据之前的回答,HID报告描述符是开发者自定义的,通常通过头文件定义数组。接下来,我需要整理步骤,确保涵盖环境配置、描述符创建、代码修改、配置调整、编译验证以及可能的问题排查。 用户可能需要知道如何创建自定义的描述符文件,如何将其包含到项目中,如何配置ESP-IDF的组件(如启用USB和HID支持),以及如何在代码中引用这个描述符。此外,验证步骤和常见问题(如编译错误或设备无法识别)的解决方法也是重要的。 需要注意引用中的信息是否相关。例如,引用[1]提到ESP32配置自定义HID设备,引用[4]讨论了HID设备在USB和蓝牙中的应用,这可能对用户有帮助,但用户现在专注于USB HID,所以可能需要更具体的指导。引用[3]提到ESP32-S3BLE HID控制,但用户的问题是关于USB HID,所以这部分可能不直接相关,但需要注意区分USB和蓝牙HID的不同配置。 需要确保步骤详细且符合ESP-IDF的最新版本,特别是v4.4及以上,因为之前的回答提到了`esp_tinyusb`组件。用户可能需要检查他们的IDF版本,并确认组件的正确配置。另外,用户可能需要示例代码片段,例如如何定义报告描述符数组,如何在初始化代码中设置描述符。 在问题排查部分,需要涵盖常见的错误,如描述符格式错误、配置未启用、内存不足等。引用中提到的资源,如ESP-IDF文档和TinyUSB示例,可以作为扩展学习资源推荐给用户。 最后,需要确保回答结构清晰,分步骤说明,并包含代码示例和配置示例,帮助用户逐步实现自定义HID报告描述符的修改。同时,相关问题部分需要引导用户深入可能遇到的后续问题,如多接口配置、报告描述符语法等。</think>### ESP32-S3 ESP-IDF USB HID 报告描述符自定义修改完整指南 --- #### **一、环境准备** 1. **ESP-IDF 版本要求** - 必须使用 **ESP-IDF v4.4 或更高版本**(因 `esp_tinyusb` 组件从该版本开始集成) - 验证方法: ```bash idf.py --version ``` 2. **启用 USB 和 HID 支持** - 运行配置工具: ```bash idf.py menuconfig ``` - 配置路径: ``` Component config → TinyUSB → Enable TinyUSB driver → HID Class Support ``` - 勾选 `CONFIG_TINYUSB_HID_ENABLE` - 设置 `CONFIG_TINYUSB_HID_BUFSIZE`(建议 512 字节) --- #### **二、自定义 HID 报告描述符** 1. **创建描述符文件** - 在工程 `main` 目录下新建 `hid_report_descriptor.h`,内容示例(键盘描述符): ```c #pragma once #include <stdint.h> // HID 键盘报告描述符(8字节输入报告) const uint8_t hid_report_descriptor[] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xA1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Key Codes) 0x19, 0xE0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xE7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0xC0 // END_COLLECTION }; ``` 2. **绑定描述符到 USB 配置** - 在 `main.c` 中初始化 USB HID: ```c #include "hid_report_descriptor.h" void app_main(void) { const tinyusb_config_t tusb_cfg = { .device_descriptor = NULL, .configuration_descriptor = hid_report_descriptor, .configuration_descriptor_len = sizeof(hid_report_descriptor), .string_descriptor = NULL, .external_phy = false }; ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); // 其他初始化代码... } ``` --- #### **三、工程配置与编译** 1. **修改 `CMakeLists.txt`** ```cmake # 添加组件依赖 set(COMPONENTS esp_tinyusb) # 包含自定义头文件路径 include_directories(${CMAKE_CURRENT_LIST_DIR}/main) ``` 2. **编译与烧录** ```bash idf.py build idf.py -p PORT flash monitor ``` --- #### **四、验证与调试** 1. **设备枚举检查** - 连接 ESP32-S3 至 PC,通过 `dmesg`(Linux)或 **设备管理器**(Windows)查看是否识别为 HID 设备 - 预期输出:`HID-compliant device` 或类似描述 2. **报告描述符解析工具** - 使用 **USBlyzer** 或 **Wireshark** 抓取 USB 数据包,验证描述符格式 - 关键检查点: - 报告长度是否匹配 - Usage Page/Usage 定义是否符合协议 --- #### **五、常见问题解决** | 问题现象 | 解决方案 | |------------------------------|--------------------------------------------------------------------------| | 编译报错:未找到描述符符号 | 检查头文件是否被正确包含,确认 `hid_report_descriptor` 定义为 `const` 类型 | | PC 无法识别设备 | 1. 确认 `CONFIG_TINYUSB_HID_ENABLE` 已启用<br>2. 检查 USB D+/D- 接线 | | 报告数据格式错误 | 使用 [HID Descriptor Tool](https://www.usb.org/document-library/hid-descriptor-tool) 验证描述符语法 | --- #### **六、扩展应用** 1. **复合 HID 设备** - 同时实现键盘+鼠标:合并两者的报告描述符,通过 `COLLECTION` 定义多接口 - 示例代码片段: ```c const uint8_t hid_report_descriptor[] = { // 键盘描述符部分... 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xA1, 0x01, // COLLECTION (Application) // 鼠标描述符部分... }; ``` 2. **动态报告修改** - 通过 `tud_hid_report()` 函数在运行时更新报告内容: ```c void send_hid_report() { uint8_t report_data[8] = {0}; report_data[2] = 0x04; // 模拟按下 &#39;a&#39; 键 tud_hid_report(0, report_data, sizeof(report_data)); } ``` --- #### **七、关键参考资源** 1. **官方文档** - [ESP-IDF USB HID 开发指南](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/api-reference/peripherals/usb_device.html#hid-class) - [USB HID 协议标准文档](https://www.usb.org/document-library/device-class-definition-hid-111) 2. **工具推荐** - **HID Descriptor Tool**:可视化生成报告描述符 - **Bus Hound**:USB 数据抓取与分析 --- ### 相关问题 1. 如何实现 ESP32-S3HID 复合设备(键盘+摇杆)? 2. USB HID 报告描述符中如何定义特征报告(Feature Report)? 3. ESP-IDF 中如何优化 HID 设备的响应延迟? [^1]: ESP-IDF USB 设备类编程手册 [^2]: USB HID 1.11 协议规范
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值