




ESP-IDF 示例模块中英对照清单:
get_started
ESP-IDF 入门指南
新用户快速上手的第一个示例
包含开发环境配置、编译、烧录、调试全流程
帮助用户理解 ESP-IDF 开发流程
2. blink
LED 闪烁示例
最简单的 GPIO 控制示例
控制板载 LED 闪烁
验证开发环境和硬件是否正常工作
3. hello_world
Hello World 示例
基本的串口打印示例
演示日志系统使用
输出 "Hello World!" 到串口终端
Bluetooth 蓝牙示例(总目录)
4. bluetooth
蓝牙示例总目录
包含所有蓝牙相关示例的根目录
分为 Bluedroid 和 NimBLE 两个协议栈
📙 Bluedroid 协议栈示例
5. bluedroid
Bluedroid 协议栈示例目录
基于 ESP-IDF 默认的 Bluedroid 协议栈
支持 BLE 和经典蓝牙
6. Bluedroid_Beacon
Bluedroid 信标示例
使用 Bluedroid 协议栈实现 BLE 信标
支持 iBeacon 或 Eddystone 格式
周期广播设备信息
7. Bluedroid_Connection
Bluedroid 连接示例
展示 Bluedroid 下的 BLE 连接建立
包含扫描、连接、断开连接流程
基础连接管理示例
8. Bluedroid_GATT_Server
Bluedroid GATT 服务器
使用 Bluedroid 协议栈创建 GATT 服务器
定义自定义服务和特征值
响应客户端请求
📘 NimBLE 协议栈示例
9. nimble
NimBLE 协议栈示例目录
基于 Apache NimBLE 协议栈(更轻量级)
专门为 BLE 优化
10. NimBLE_Beacon
NimBLE 信标示例
使用 NimBLE 协议栈实现 BLE 信标
低功耗广播模式
支持标准信标格式
11. NimBLE_Connection
NimBLE 连接示例
展示 NimBLE 下的 BLE 连接管理
更轻量级的连接实现
适用于资源受限设备
12. NimBLE_GATT_Server
NimBLE GATT 服务器
使用 NimBLE 创建 GATT 服务
内存占用更小,效率更高
适用于电池供电设备
13. NimBLE_Security
NimBLE 安全示例
展示 NimBLE 的安全特性
包括配对、加密、密钥管理
安全连接建立流程
📗 BLE 专用示例
14. ble
BLE 示例总目录
纯 BLE 应用示例(不区分协议栈)
包含各种 BLE 应用场景
15. ble_throughput
BLE 吞吐量测试总目录
BLE 数据传输速率测试示例
分为客户端和服务器端
16. throughput_client
吞吐量测试客户端
连接到服务器进行数据速率测试
发送/接收大数据包
统计吞吐量性能
17. throughput_server
吞吐量测试服务器
响应客户端测试请求
配合客户端完成吞吐量测试
展示最大传输速率
18. ble_ancs
Apple 通知中心服务
实现 ANCS(Apple Notification Center Service)客户端
接收 iOS 设备通知
显示来电、短信、应用通知
19. ble_compatibility_test
BLE 兼容性测试
测试 ESP32 BLE 与其他设备的兼容性
验证协议栈互操作性
调试和兼容性验证工具
20. ble_eddystone
Eddystone 信标
实现 Google Eddystone 信标协议
支持 UID、URL、TLM、EID 帧类型
用于位置服务和物联网应用
21. ble_hid_device_demo
BLE HID 设备演示
模拟 BLE 人机接口设备
可作为键盘、鼠标、游戏手柄
连接到支持 BLE HID 的主机
22. ble_ibeacon
iBeacon 信标
实现 Apple iBeacon 协议
广播 UUID、Major、Minor 值
用于室内定位、近距离触发
🔍 协议栈选择建议
Bluedroid vs NimBLE:
| 特性 | Bluedroid | NimBLE |
|---|---|---|
| 协议栈 | 双模(BLE + 经典) | 单模(仅 BLE) |
| 内存占用 | 较大 | 较小 |
| 复杂度 | 较高 | 较低 |
| 功能 | 完整 | 精简 |
| 适用场景 | 需要经典蓝牙 | 仅需 BLE,资源受限 |
推荐选择:
-
需要经典蓝牙功能 → 选择 Bluedroid
-
仅需 BLE,追求低功耗 → 选择 NimBLE
-
新手入门 → 从 Bluedroid 开始(官方默认)
-
产品开发 → 根据需求选择,NimBLE 更适合电池设备
ble_spp_client
BLE SPP 客户端
实现蓝牙串口协议(SPP-over-BLE)客户端
连接到 BLE SPP 服务器进行串口通信
支持数据透传,适用于无线串口应用
3. ble_spp_server
BLE SPP 服务器
提供 BLE 串口协议服务
接受客户端连接,实现双向数据通信
创建虚拟串口通道,替代有线串口
4. gattc_multi_connect
GATT 多连接客户端
同时连接和管理多个 BLE 外设
演示多设备并发通信
适用于网关、集线器类设备
5. gatt_client
基础 GATT 客户端
扫描、连接、发现 BLE 服务
读写特征值,订阅通知
GATT 客户端标准实现
6. gatt_security_client
安全 GATT 客户端
实现安全连接(LE Security)
支持配对、绑定、加密
演示安全通信流程
7. gatt_security_server
安全 GATT 服务器
提供安全的 GATT 服务
实现身份验证和数据加密
保护敏感数据通信
8. gatt_server
基础 GATT 服务器
创建自定义 GATT 服务
定义特征值和描述符
响应客户端请求
9. gatt_server_service_table
服务表式 GATT 服务器
使用服务表方式组织 GATT 服务
简化复杂服务定义
提高代码可维护性
📙 BLE 5.0 高级特性
10. ble_50
BLE 5.0 综合示例
展示 ESP32 对 BLE 5.0 的支持
包含 PHY 切换、扩展广播等特性
11. ble50_throughput
BLE 5.0 吞吐量测试框架
测试 BLE 5.0 的高速率特性
支持 2M PHY 和 Coded PHY
12. throughput_client
吞吐量客户端
发起吞吐量测试
测量实际数据传输速率
性能评估工具
13. throughput_server
吞吐量服务器
响应吞吐量测试
配合客户端完成性能测试
14. ble50_security_client
BLE 5.0 安全客户端
演示 BLE 5.0 增强安全特性
LE Secure Connections (LESC)
更高安全级别的连接
15. ble50_security_server
BLE 5.0 安全服务器
提供 BLE 5.0 安全服务
支持现代安全协议
16. multi-adv
多广播集
同时发送多个广播数据包
不同参数、不同内容
适用于多服务场景
17. periodic_adv
周期性广播
实现 BLE 5.0 周期性广播
适用于音频流、定位数据
低功耗数据同步
18. periodic_sync
周期性广播同步
同步到周期性广播源
接收定时广播数据
实现时间同步数据接收
📘 Bluedroid 主机模式
19. bluedroid_host_only
纯主机模式
仅运行蓝牙主机协议栈
控制外部蓝牙控制器
适用于定制化蓝牙应用
20. bluedroid_host_only_uart
UART 主机模式
通过 UART 连接外部蓝牙芯片
实现 HCI 主机功能
硬件解耦设计
📒 经典蓝牙(BR/EDR)
21. classic_bt
经典蓝牙示例目录
- 包含所有经典蓝牙应用
22. a2dp_sink
A2DP 音频接收器
接收蓝牙音频流
支持 SBC 解码
作为蓝牙音箱
23. a2dp_source
A2DP 音频发送器
发送音频到蓝牙音箱
支持 SBC 编码
作为音频源设备
24. bt_discovery
设备发现
扫描周围经典蓝牙设备
获取设备信息
基础发现功能
25. bt_hid_mouse_device
HID 鼠标设备
模拟蓝牙鼠标
发送鼠标事件
人机交互设备
26. bt_l2cap_client
L2CAP 客户端
建立 L2CAP 数据通道
实现自定义协议通信
比 RFCOMM 更灵活
27. bt_l2cap_server
L2CAP 服务器
接受 L2CAP 连接
提供数据通道服务
协议开发基础
28. bt_spp_acceptor
SPP 接收端
监听 SPP 连接
经典蓝牙串口通信
兼容传统设备
29. bt_spp_initiator(虽未列出但通常成对出现)
SPP 发起端
发起 SPP 连接
主动连接到串口设备
应用场景建议
物联网网关
text
big_weapon(多协议管理)
gattc_multi_connect(多设备连接)
periodic_sync(数据收集)
音频设备
text
a2dp_sink(蓝牙音箱)
a2dp_source(音频发送)
ble_50(高质量音频)
工业控制
text
ble_spp_server(无线串口)
bt_spp_acceptor(经典串口)
bt_l2cap_server(可靠数据通道)
安全设备
text
gatt_security_server(安全通信)
ble50_security_server(高级安全)
信标/定位
text
multi-adv(多广播)
periodic_adv(定位广播)
ble_50(远距离)
🔧 开发选择指南
| 需求 | 推荐示例 | 协议栈 |
|---|---|---|
| 最高性能 | big_weapon |
双模优化 |
| 最低功耗 | periodic_adv |
BLE 5.0 |
| 音频应用 | a2dp_sink/source |
经典蓝牙 |
| 数据透传 | ble_spp_server/client |
BLE |
| 多设备 | gattc_multi_connect |
BLE |
| 安全通信 | ble50_security_* |
BLE 5.0 |
| 兼容传统 | bt_spp_acceptor |
经典蓝牙 |
| 自定义协议 | bt_l2cap_server/client |
经典蓝牙 |
bt_spp_vfs_acceptor
SPP VFS 接收端(虚拟文件系统接口)
通过 VFS(虚拟文件系统)接口提供 SPP 服务
允许应用程序像操作文件一样操作蓝牙串口
支持标准文件操作(open/read/write/close)
简化蓝牙串口集成到现有系统
2. bt_spp_vfs_initiator
SPP VFS 发起端(虚拟文件系统接口)
通过 VFS 接口发起 SPP 连接
提供类文件操作的蓝牙通信接口
便于现有应用移植到蓝牙通信
3. hfp_ag
HFP 音频网关(Hands-Free Profile Audio Gateway)
实现 HFP 音频网关角色
作为手机等设备的音频网关
支持语音通话控制(接听/拒接/挂断)
适用于车载系统、蓝牙耳机座
4. hfp_hf
HFP 免提设备(Hands-Free Profile Handsfree)
实现 HFP 免提设备角色
连接到音频网关进行语音通话
支持拨号、音量控制、状态查询
适用于蓝牙耳机、车载免提
📙 蓝牙共存示例
5. coex
蓝牙与 WiFi 共存
演示蓝牙和 WiFi 在同一芯片上共存工作
优化射频资源分配
减少无线干扰
6. a2dp_gatts_coex
A2DP 与 GATT 服务共存
同时运行 A2DP 音频流和 BLE GATT 服务
展示双模蓝牙同时工作
适用于智能音频设备(如带控制功能的蓝牙音箱)
7. gatte_gatts_coex
GATT 客户端与服务器共存
同一设备同时作为 GATT 客户端和服务器
双向 GATT 通信能力
适用于中继设备、网关
📗 ESP-BLE-MESH 蓝牙 mesh 网络
8. esp_ble_mesh
ESP BLE Mesh 总目录
基于 Bluetooth SIG Mesh 1.0.1 协议
支持大规模设备组网
低功耗 mesh 网络解决方案
9. directed forwarding
定向转发机制
实现 mesh 网络中的定向消息转发
优化网络路径选择
提高传输效率
10. df_client
定向转发客户端
在 mesh 网络中发起定向转发请求
指定消息传输路径
11. df_server
定向转发服务器
响应和处理定向转发消息
按指定路径转发数据
12. fast_provisioning
快速配网机制
批量设备快速加入 mesh 网络
简化大规模部署流程
13. fast_prov_client
快速配网客户端
快速配置多个未配网设备
批量分发网络密钥
14. fast_prov_server
快速配网服务器
接收快速配网请求
协助新设备快速入网
15. onoff_models
开关模型示例目录
基于 mesh 模型的开关控制
通用开关控制功能
16. onoff_client
开关客户端
控制 mesh 网络中的开关设备
发送开关状态改变命令
17. onoff_server
开关服务器
接收并执行开关控制命令
上报开关状态
18. remote_provisioning
远程配网机制
通过网络远程配置 mesh 设备
支持远程设备管理
19. rpr_client
远程配网客户端
发起远程设备配网请求
管理远程设备入网
20. rpr_server
远程配网服务器
响应远程配网请求
代理远程设备配置
21. unprov_dev
未配网设备示例
演示设备配网前状态
配网流程起始点
22. sensor_models
传感器模型示例目录
基于 mesh 模型的传感器数据采集
环境监测应用
23. sensor_client
传感器客户端
请求传感器数据
订阅传感器状态变化
24. sensor_server
传感器服务器
采集和发布传感器数据
响应数据查询请求
25. vendor_models
厂商自定义模型
实现非标准 mesh 模型
厂商特定功能扩展
26. vendor_client
厂商模型客户端
使用厂商自定义协议通信
专有功能控制
应用场景深度解析
智能家居系统
yaml
核心组件:
- esp_ble_mesh: 网络基础
- onoff_client/server: 灯光控制
- sensor_server: 环境监测
- fast_provisioning: 批量部署
特性:
- 大规模设备组网
- 低功耗运行
- 远程控制
- 自动化场景
工业物联网
yaml
核心组件:
- bt_spp_vfs_*: 串口设备无线化
- coex: 多协议共存
- directed_forwarding: 可靠传输
- vendor_models: 定制协议
特性:
- 工业级可靠性
- 实时数据传输
- 长距离覆盖
- 抗干扰能力
音频通信系统
yaml
核心组件:
- hfp_ag/hf: 语音通话
- a2dp_gatts_coex: 音控一体
- a2dp_sink/source: 音频流
特性:
- 高清音频传输
- 语音控制集成
- 低延迟通信
- 多设备连接
楼宇自动化
yaml
核心组件:
- remote_provisioning: 远程管理
- sensor_models: 楼宇监测
- onoff_models: 设备控制
- df_client/server: 优化路由
特性:
- 大规模网络管理
- 节能控制
- 集中监控
- 故障自愈
技术选择指南
| 项目需求 | 推荐方案 | 关键特性 |
|---|---|---|
| 大规模设备组网 | esp_ble_mesh + fast_provisioning |
数千节点,自组织网络 |
| 工业串口无线化 | bt_spp_vfs_* + coex |
可靠透传,多协议共存 |
| 语音通话系统 | hfp_ag + hfp_hf + a2dp_* |
完整音频方案 |
| 智能照明控制 | onoff_models + remote_provisioning |
批量控制,远程管理 |
| 环境监测网络 | sensor_models + directed_forwarding |
数据采集,优化传输 |
| 定制化应用 | vendor_models + coex |
灵活扩展,兼容现有 |
vendor_server
厂商模型服务器
实现厂商自定义 mesh 模型服务器端
响应厂商特定命令和数据请求
支持非标准 mesh 功能扩展
适用于专有协议实现
2. aligenie_demo
天猫精灵智能家居对接示例
演示 ESP-BLE-MESH 与阿里 IoT 平台对接
支持天猫精灵语音控制
实现云端到 mesh 网络的控制链路
适用于智能家居产品开发
3. provisioner
Mesh 配网器专用示例
完整的 mesh 网络配网器实现
批量设备配网和管理功能
网络密钥分发和设备管理
适用于网关、手机配网应用
4. wifi_coexist
WiFi 与 BLE Mesh 共存
演示 WiFi 和 BLE Mesh 同时工作
优化双模无线通信资源分配
网关设备的典型应用场景
📙 HCI(主机控制器接口)示例
5. hci
HCI 接口示例目录
展示 ESP32 作为蓝牙控制器的使用
支持外部主机通过 HCI 控制蓝牙
6. ble_adv_scan_combined
广播与扫描同时进行
同时作为广播者和扫描者
支持角色快速切换
适用于信标和扫描复合设备
7. controller_hci_uart_esp32
UART HCI 控制器(ESP32)
ESP32 作为蓝牙控制器,通过 UART 连接外部主机
提供标准 HCI UART 接口
兼容标准蓝牙主机协议栈
8. controller_hci_uart_esp32c3_and_esp32s3
UART HCI 控制器(ESP32-C3/S3)
针对 ESP32-C3 和 ESP32-S3 的 HCI 控制器实现
RISC-V 和 Xtensa 架构优化
低功耗和性能优化版本
9. controller_vhci_ble_adv
虚拟 HCI 广播示例
使用虚拟 HCI 接口实现 BLE 广播
无需外部物理连接
测试和开发用途
📗 NimBLE 高级特性示例
10. nimble
NimBLE 协议栈高级示例目录
- 展示 NimBLE 协议栈的扩展功能
11. ble_cts
当前时间服务(Current Time Service)
实现蓝牙当前时间服务
时间同步和时间获取功能
12. cts_cent
当前时间服务客户端
连接到时间服务器获取当前时间
自动时间同步功能
13. cts_prph
当前时间服务外设端
作为时间服务器提供当前时间
支持时间更新和通知
14. ble_enc_adv_data
加密广播数据
演示加密的广播数据功能
保护广播内容隐私
15. enc_adv_data_cent
加密广播数据客户端
扫描并解密加密的广播数据
安全数据接收
16. enc_adv_data_prph
加密广播数据外设端
广播加密的数据包
隐私保护广播
17. ble_htp
健康温度计服务(Health Thermometer Profile)
实现医疗温度计蓝牙服务
符合蓝牙 SIG 标准规范
18. htp_cent
健康温度计客户端
连接到温度计设备读取温度数据
医疗设备监控应用
19. htp_prph
健康温度计外设端
模拟蓝牙温度计设备
提供温度测量服务
20. ble_l2cap_coc
BLE L2CAP 面向连接通道
实现 BLE 的 L2CAP 连接导向通道
比 ATT 协议更高效的数据传输
21. coc_blecent
L2CAP CoC 客户端
建立 L2CAP 面向连接通道
大数据量传输应用
22. coc_bleprph
L2CAP CoC 外设端
接受 L2CAP 连接通道
高效数据传输服务端
23. ble_multi_conn
多连接管理示例
展示同时管理多个 BLE 连接
连接状态管理和资源分配
24. ble_multi_conn_cent
多连接客户端
同时连接到多个外设
并发通信管理
25. ble_multi_conn_prph
多连接外设端
接受多个中心设备连接
广播给多个连接者
26. ble_pawr_adv
周期性广播与响应
实现 BLE 5.0 的周期性广播和响应
低功耗双向通信
适用于传感器网络
🎯 应用场景深度解析
医疗健康设备
yaml
核心组件:
- ble_htp (健康温度计)
- cts_prph (时间同步)
- ble_enc_adv_data (数据加密)
应用场景:
- 蓝牙体温计
- 医疗监护设备
- 可穿戴健康设备
特性:
- 医疗级数据精度
- 患者隐私保护
- 长时间监测
工业数据采集
yaml
核心组件:
- ble_l2cap_coc (高效数据传输)
- ble_multi_conn (多设备连接)
- controller_hci_uart (外部控制)
应用场景:
- 工业传感器网络
- 数据采集网关
- 远程监控系统
特性:
- 高数据吞吐量
- 多设备并发
- 工业级可靠性
智能家居网关
yaml
核心组件:
- aligenie_demo (云平台对接)
- provisioner (设备配网)
- wifi_coexist (多协议共存)
应用场景:
- 智能家居中枢
- 语音控制网关
- 远程管理平台
特性:
- 云边端协同
- 语音交互
- 批量设备管理
安全通信系统
yaml
核心组件:
- ble_enc_adv_data (加密广播)
- vendor_server (专有协议)
- controller_vhci (安全测试)
应用场景:
- 安全信标
- 加密数据传输
- 隐私保护应用
特性:
- 端到端加密
- 防窃听保护
- 身份验证
🔧 技术架构指南
NimBLE 协议栈优势
text
1. 轻量级设计:
- 内存占用小 (约1/3的Bluedroid)
- 启动速度快
- 适合资源受限设备
2. 模块化架构:
- 各层独立可配置
- 易于功能裁剪
- 快速定制开发
3. 开源优势:
- Apache 2.0 许可证
- 活跃社区支持
- 跨平台兼容
HCI 架构应用场景
text
1. 芯片级集成:
ESP32作为蓝牙协处理器
└── UART HCI接口
└── 主处理器 (Linux/Windows)
2. 系统扩展:
现有系统增加蓝牙功能
└── ESP32提供完整蓝牙协议栈
3. 测试验证:
虚拟HCI接口
└── 协议栈功能测试
Mesh 网络拓扑选择
text
1. 星型拓扑:
provisioner为中心
├── onoff_server
├── sensor_server
└── vendor_server
2. 网状拓扑:
所有节点平等
├── 自组织路由
├── 冗余路径
└── 故障自愈
3. 分层拓扑:
gateway
├── subnetwork_1
│ ├── node_1
│ └── node_2
└── subnetwork_2
├── node_3
└── node_4
🚀 开发工作流建议
步骤1:协议栈选择
bash
# 资源受限设备
选择 NimBLE (内存 < 512KB)
# 需要经典蓝牙
选择 Bluedroid
# 仅需控制器功能
选择 HCI 模式
步骤2:示例参考
bash
# 医疗设备
参考: ble_htp + ble_enc_adv_data
# 工业网关
参考: ble_multi_conn + ble_l2cap_coc
# 智能家居
参考: aligenie_demo + provisioner
步骤3:性能优化
bash
# 内存优化
启用 BLE Only 模式
关闭不需要的 GATT 服务
优化缓冲区大小
# 功耗优化
调整广播间隔
使用连接参数协商
启用睡眠模式
# 吞吐量优化
使用 L2CAP CoC 替代 ATT
启用 BLE 5.0 2M PHY
优化 MTU 大小
📊 性能基准参考
| 示例 | 内存占用 | 功耗 | 吞吐量 | 适用场景 |
|---|---|---|---|---|
ble_htp |
~200KB | 低 | 1-10kbps | 医疗传感器 |
ble_l2cap_coc |
~300KB | 中 | 100-500kbps | 数据传输 |
ble_multi_conn |
~400KB | 中高 | 多路并发 | 网关设备 |
provisioner |
~500KB | 高 | N/A | 网络管理 |
controller_hci |
~150KB | 低 | 依赖主机 | 协处理器 |
ble_pawr_adv(子项)
PAwR 广播端
作为周期性广播的发起者
定期发送广播数据包
低功耗数据发布
3. ble_pawr_sync
PAwR 同步端
同步到周期性广播
按预定时间间隔接收广播数据
节能的数据接收模式
4. ble_pawr_adv_conn(目录)
PAwR 广播与连接复合模式
同时支持周期性广播和连接功能
复合工作模式示例
5. ble_pawr_adv_conn(子项)
PAwR 广播+连接复合广播端
在周期性广播基础上支持连接
广播和连接模式动态切换
6. ble_pawr_sync_conn
PAwR 同步+连接复合接收端
同步接收广播数据并可建立连接
多种通信模式组合
📙 BLE 物理层特性
7. ble_phy
BLE 物理层特性控制
演示不同 PHY(物理层)的使用
支持 1M、2M、Coded PHY
8. phy_cent
PHY 客户端
连接时协商和切换 PHY 参数
测试不同 PHY 的性能表现
9. phy_prph
PHY 外设端
支持多种 PHY 模式
响应客户端的 PHY 协商请求
📗 BLE 邻近感知服务
10. ble_proximity_sensor
邻近传感器服务
实现蓝牙邻近检测功能
基于 RSSI 信号强度进行距离估计
11. proximity_sensor_cent
邻近传感器客户端
监控外设的信号强度
实现接近/远离检测
触发相应事件
12. proximity_sensor_prph
邻近传感器外设端
广播信号供客户端检测
模拟距离变化
📘 BLE 串口协议
13. ble_spp
BLE 串口协议(Serial Port Profile)
在 BLE 上实现串口通信功能
替代传统有线串口
14. spp_client
SPP 客户端
连接到 BLE SPP 服务器
双向数据传输
15. spp_server
SPP 服务器
提供 BLE 串口服务
虚拟串口通信
📙 吞吐量测试应用
16. throughput_app
吞吐量测试应用框架
完整的吞吐量测试解决方案
包含客户端和服务器端
17. blecent_throughput
中心设备吞吐量测试
作为中心设备测试吞吐量
发起数据传输测试
18. bleprph_throughput
外设设备吞吐量测试
作为外设设备测试吞吐量
响应数据传输测试
📗 BLE 中心设备综合示例
19. blecent
中心设备综合示例目录
- 多种中心设备应用示例
20. blecsc
自行车速度与踏频传感器客户端
连接蓝牙自行车传感器
获取速度和踏频数据
运动健身应用
21. blehr
心率监测客户端
连接蓝牙心率带
实时监测心率数据
健康运动应用
22. blemesh
BLE Mesh 客户端
Mesh 网络管理客户端
控制 Mesh 网络节点
适用于网关设备
23. bleprph
外设设备示例(基础版)
基础外设设备实现
通用外设功能
24. bleprph_host_only
仅主机模式外设
外设设备的主机模式实现
简化协议栈配置
25. bleprph_wifi_coex
WiFi 共存外设
外设设备与 WiFi 共存工作
优化无线资源分配
26. ble_dynamic_service
动态服务管理
运行时动态添加/删除 GATT 服务
灵活的服务配置
适应不同应用场景
27. ble_multi_adv
多广播集
同时发送多个广播数据集
不同广播参数配置
多服务广播支持
🎯 应用场景深度解析
运动健康监测系统
yaml
核心组件:
- blehr (心率监测)
- blecsc (运动传感器)
- ble_proximity_sensor (安全距离)
设备组合:
智能手表/手环:
├── blehr (接收心率数据)
├── blecsc (接收速度数据)
└── blecent_throughput (数据传输)
运动传感器:
├── blehr (心率带)
├── blecsc (速度传感器)
└── bleprph (低功耗广播)
应用特性:
- 实时运动数据监测
- 多传感器融合
- 低功耗长续航
工业物联网数据采集
yaml
核心组件:
- ble_spp (串口透传)
- ble_pawr_adv (周期性数据)
- ble_multi_adv (多数据流)
系统架构:
网关设备 (blecent):
├── ble_spp (连接串口设备)
├── ble_pawr_sync (接收周期性数据)
└── ble_multi_adv (管理多设备)
传感器节点 (bleprph):
├── ble_spp (数据上传)
├── ble_pawr_adv (周期性上报)
└── ble_proximity_sensor (位置感知)
应用特性:
- 工业级可靠性
- 周期性数据采集
- 设备位置监控
智能家居控制网络
yaml
核心组件:
- blemesh (Mesh网络)
- ble_dynamic_service (灵活配置)
- bleprph_wifi_coex (多协议)
网络拓扑:
家庭网关:
├── blemesh (Mesh网络管理)
├── bleprph_wifi_coex (WiFi桥接)
└── blecent (设备控制)
智能设备:
├── bleprph (基础功能)
├── ble_multi_adv (状态广播)
└── ble_dynamic_service (功能扩展)
应用特性:
- 自组织网络
- 灵活设备管理
- 多协议协同
🔧 技术实现指南
PHY 选择策略
text
1. 1M PHY (默认):
- 兼容所有 BLE 设备
- 最远通信距离
- 功耗最低
2. 2M PHY (BLE 5.0):
- 双倍数据速率
- 降低传输时间
- 功耗稍高
3. Coded PHY:
- 超远距离通信
- 抗干扰能力强
- 数据速率较低
选择建议:
- 数据传输: 2M PHY
- 远距离: Coded PHY (S=2 或 S=8)
- 兼容性: 1M PHY
PAwR 配置优化
c
// 周期性广播配置
struct ble_gap_periodic_adv_params adv_params = {
.interval_min = BLE_GAP_PERIODIC_ADV_INTERVAL_MIN, // 最小间隔
.interval_max = BLE_GAP_PERIODIC_ADV_INTERVAL_MAX, // 最大间隔
.properties = BLE_GAP_PERIODIC_ADV_PROP_INCLUDE_TX_POWER, // 包含发射功率
};
// 同步配置
struct ble_gap_periodic_sync_params sync_params = {
.skip = 0, // 跳过的广播事件数
.timeout = 10000, // 同步超时(ms)
.flags = 0, // 同步标志
};
动态服务管理示例
c
// 动态添加服务
void add_dynamic_service(void) {
struct ble_gatt_svc_def *service = create_custom_service();
ble_gatts_add_svcs(service);
}
// 动态移除服务
void remove_dynamic_service(uint16_t service_handle) {
ble_gatts_delete_svc(service_handle);
}
// 运行时配置
void configure_dynamic_features(uint8_t feature_mask) {
if (feature_mask & FEATURE_HEART_RATE) {
add_heart_rate_service();
}
if (feature_mask & FEATURE_BATTERY) {
add_battery_service();
}
}
🚀 性能优化建议
功耗优化策略
bash
# 1. 广播参数优化
CONFIG_BT_NIMBLE_EXT_ADV=y # 启用扩展广播
CONFIG_BT_NIMBLE_SLEEP_ENABLE=y # 启用睡眠模式
# 2. 连接参数优化
- Connection Interval: 根据数据需求调整
- Slave Latency: 允许跳过连接事件
- Supervision Timeout: 适当设置超时
# 3. PHY 优化
- 静态数据: 使用 Coded PHY 降低功耗
- 实时数据: 使用 2M PHY 缩短传输时间
吞吐量优化
bash
# 1. MTU 优化
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=512 # 增大 MTU
# 2. 数据包优化
- 使用 Write Without Response
- 启用 Data Length Extension
- 使用 L2CAP CoC 替代 ATT
# 3. 协议优化
- 减少协议开销
- 批量数据传输
- 压缩数据格式
多设备连接管理
c
// 连接管理结构
struct connection_manager {
struct ble_gap_conn_desc *connections[MAX_CONNECTIONS];
uint8_t active_count;
uint8_t max_allowed;
};
// 连接优先级策略
enum connection_priority {
PRIORITY_HIGH = 0, // 实时数据连接
PRIORITY_MEDIUM = 1, // 普通数据连接
PRIORITY_LOW = 2, // 配置/控制连接
};
// 资源分配算法
void allocate_connection_resources(struct connection_manager *mgr) {
// 根据优先级分配时隙
// 动态调整连接参数
// 负载均衡策略
}
📊 性能基准参考
| 功能模块 | 功耗(uA) | 延迟(ms) | 吞吐量(kbps) | 适用场景 |
|---|---|---|---|---|
ble_pawr_adv |
10-50 | 100-1000 | 1-10 | 传感器数据 |
ble_spp |
100-500 | 20-100 | 50-200 | 串口透传 |
blecent |
200-1000 | 10-50 | 100-500 | 网关设备 |
ble_multi_adv |
50-200 | N/A | N/A | 信标应用 |
ble_dynamic_service |
+10% | 增加1-5 | 基本不变 | 灵活配置 |
ble_periodic_adv
周期性广播高级示例
完整的周期性广播实现
支持 BLE 5.0 周期性广播特性
低功耗数据发布方案
适用于传感器网络、信标应用
2. ble_periodic_sync
周期性广播同步高级示例
同步到周期性广播的高级实现
支持多广播源同步
数据接收优化和处理
适用于数据采集网关
3. hci
主机控制器接口综合示例
ESP32 作为蓝牙控制器的完整示例
支持 UART 和 USB HCI 接口
与外部主机系统集成
适用于蓝牙协处理器应用
4. power_save
蓝牙功耗优化示例
深度睡眠和功耗管理
蓝牙低功耗模式配置
动态功耗调整策略
电池供电设备优化
📙 ESP 专用蓝牙功能
5. blufi
BluFi 协议示例
ESP32 专有的蓝牙配网协议
通过蓝牙配置 WiFi 网络
安全传输 WiFi SSID 和密码
智能设备配网解决方案
6. esp_hid_device
ESP HID 设备示例
实现 HID(人机接口设备)外设
模拟键盘、鼠标、游戏手柄
支持蓝牙和 USB HID
适用于输入设备开发
7. esp_hid_host
ESP HID 主机示例
HID 主机设备实现
连接和控制 HID 外设
解析 HID 报告描述符
适用于 HID 设备管理器
📗 构建系统与配置管理
8. build_system
构建系统高级示例
ESP-IDF 构建系统的深度使用
自定义构建流程
复杂项目结构管理
高级编译配置技巧
9. cmake
CMake 高级特性示例
ESP-IDF CMake 系统的深度配置
自定义 CMake 模块
条件编译和特性选择
多目标构建配置
10. component_manager
组件管理器示例
组件依赖管理
版本控制和冲突解决
第三方组件集成
组件库管理最佳实践
11. idf_as_lib
IDF 作为库使用
将 ESP-IDF 作为静态库集成到其他项目
外部构建系统集成
跨平台开发支持
现有项目迁移方案
12. import_lib
库导入示例
导入第三方库到 ESP-IDF 项目
预编译库集成
库版本管理
依赖关系解析
13. import_prebuilt
预编译库导入
集成预编译的二进制库
商业库的闭源集成
库的 ABI 兼容性
许可证管理
14. multi_config
多配置管理
同一项目的多个配置变体
开发/测试/生产配置
不同硬件版本的配置
配置切换和复用
15. plugins
构建系统插件
扩展 ESP-IDF 构建功能
自定义构建步骤
自动化任务集成
工具链扩展
16. wrappers
包装器示例
为现有代码创建 ESP-IDF 包装
兼容层实现
接口适配器模式
第三方代码集成框架
📘 Bootloader 定制
17. custom_bootloader
自定义 Bootloader
ESP32 bootloader 深度定制
安全启动配置
OTA 更新优化
启动流程扩展
18. bootloader_hooks
Bootloader 钩子函数
在 bootloader 阶段执行自定义代码
启动前硬件初始化
安全检查和验证
启动参数传递
19. bootloader_override
Bootloader 覆盖示例
替换默认 bootloader 行为
自定义启动逻辑
恢复模式实现
安全启动增强
📙 C++ 特性支持
20. CXX
C++ 语言特性示例
ESP-IDF 中 C++ 的完整使用
面向对象设计模式
C++ 标准库集成
混合 C/C++ 项目
21. exceptions
C++ 异常处理
在 ESP32 上使用 C++ 异常
异常安全编程
资源管理(RAII)
错误处理最佳实践
22. pthread
POSIX 线程示例
POSIX 线程 API 使用
多线程同步和通信
线程安全和性能
实时操作系统集成
23. rtti
运行时类型信息
C++ RTTI 在 ESP32 上的使用
动态类型转换
类型识别和反射
面向对象设计模式
📗 以太网功能
24. ethernet
以太网功能总览
ESP32 以太网接口使用
有线网络连接方案
工业通信应用
25. basic
基础以太网示例
以太网基础连接
TCP/UDP 通信
网络配置和管理
网络诊断工具
26. iperf
网络性能测试
iPerf 网络性能测试工具
带宽和吞吐量测试
网络延迟测量
以太网性能评估
🎯 跨领域应用场景
智能网关设备
yaml
硬件配置:
- 以太网: 有线主干网
- 蓝牙: 本地设备连接
- WiFi: 无线扩展
软件架构:
网络层:
├── ethernet/basic (有线连接)
├── blufi (蓝牙配网)
└── power_save (功耗管理)
服务层:
├── ble_periodic_sync (数据采集)
├── esp_hid_host (设备管理)
└── cmake/multi_config (配置管理)
应用层:
├── idf_as_lib (服务框架)
├── wrappers (协议适配)
└── iperf (网络监控)
工业控制系统
yaml
硬件特性:
- 以太网: 工业协议 (Modbus TCP, EtherCAT)
- 蓝牙: 设备调试和配置
- 安全: 安全启动和加密
软件特性:
实时性:
├── pthread (多线程调度)
├── custom_bootloader (快速启动)
└── ble_periodic_adv (定时数据)
可靠性:
├── exceptions (错误处理)
├── build_system (版本控制)
└── multi_config (容错配置)
可维护性:
├── component_manager (模块管理)
├── import_prebuilt (专有库)
└── plugins (扩展工具)
消费电子产品
yaml
产品特性:
- 蓝牙: 用户交互 (esp_hid_device)
- 网络: 云连接 (ethernet/wifi)
- 更新: OTA (custom_bootloader)
开发流程:
原型阶段:
├── blufi (快速配网)
├── basic (基础功能)
└── CXX (快速开发)
量产阶段:
├── power_save (功耗优化)
├── bootloader_override (生产模式)
└── import_lib (第三方集成)
维护阶段:
├── build_system (持续集成)
├── wrappers (向后兼容)
└── rtti (动态扩展)
🔧 关键技术实现
BluFi 配网流程
c
// 1. 启动 BluFi 服务
esp_blufi_register_callbacks(&blufi_callbacks);
esp_blufi_profile_init();
// 2. 接收 WiFi 配置
void blufi_recv_wifi_config(uint8_t *ssid, uint8_t *password) {
// 安全验证和存储
store_wifi_credentials(ssid, password);
// 连接 WiFi
wifi_connect();
}
// 3. 状态反馈
void blufi_send_wifi_status(esp_blufi_wifi_mode_t mode,
esp_blufi_wifi_state_t state) {
// 向手机应用反馈连接状态
}
HID 设备实现
cpp
class ESPHIDDevice {
public:
// 初始化 HID 设备
bool init(const HIDReportDescriptor &desc);
// 发送输入报告
bool sendInputReport(const uint8_t *data, size_t len);
// 接收输出报告
void onOutputReport(const uint8_t *data, size_t len);
private:
esp_hid_device_t *hid_dev;
HIDReportDescriptor descriptor;
};
// 键盘设备示例
class BluetoothKeyboard : public ESPHIDDevice {
public:
void sendKeyPress(uint8_t keycode) {
uint8_t report[] = {0, 0, keycode, 0, 0, 0, 0, 0};
sendInputReport(report, sizeof(report));
}
};
构建系统高级配置
cmake
# CMakeLists.txt 高级示例
idf_component_register(
SRCS "main.cpp"
INCLUDE_DIRS "include"
REQUIRES
freertos
nvs_flash
esp_netif
PRIV_REQUIRES
esp_hid
blufi
KCONFIG ./Kconfig.projbuild
KCONFIG_PROJBUILD ./Kconfig.projbuild
)
# 条件编译
if(CONFIG_BLUETOOTH_ENABLED)
add_definitions(-DBT_FEATURE_ENABLED)
target_link_libraries(${COMPONENT_LIB} PUBLIC bluetooth)
endif()
# 自定义构建步骤
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/generated_file.bin
COMMAND python ${PROJECT_DIR}/scripts/generate_data.py
DEPENDS ${PROJECT_DIR}/scripts/generate_data.py
)
🚀 开发最佳实践
多配置项目管理
bash
# 创建不同配置
idf.py create-managed-config debug
idf.py create-managed-config release
idf.py create-managed-config production
# 切换配置
idf.py set-target esp32 --managed-config debug
# 合并配置
idf.py merge-config debug release
# 配置差异比较
idf.py diff-config debug release
功耗优化策略
c
// 1. 深度睡眠配置
esp_sleep_enable_timer_wakeup(3600 * 1000000); // 1小时
esp_deep_sleep_start();
// 2. 蓝牙低功耗模式
esp_pm_configure(&power_management_config);
esp_bluedroid_disable();
esp_bt_controller_disable();
// 3. 动态频率调整
esp_pm_lock_acquire(ESP_PM_CPU_FREQ_MAX);
// 高性能代码段
esp_pm_lock_release(ESP_PM_CPU_FREQ_MAX);
安全启动增强
c
// 自定义安全启动流程
void custom_bootloader_security_check(void) {
// 1. 验证数字签名
if (!verify_firmware_signature()) {
enter_recovery_mode();
}
// 2. 检查固件完整性
if (!check_firmware_integrity()) {
attempt_repair();
}
// 3. 安全计数器
update_boot_counter();
check_rollback_protection();
}
📊 性能与资源参考
| 模块 | Flash占用 | RAM占用 | 启动时间 | 适用场景 |
|---|---|---|---|---|
blufi |
~100KB | ~50KB | 快速 | 配网应用 |
esp_hid_device |
~150KB | ~80KB | 中等 | 输入设备 |
custom_bootloader |
~30KB | ~10KB | N/A | 安全启动 |
ethernet/basic |
~200KB | ~100KB | 中等 | 网络设备 |
CXX/exceptions |
+20KB | +10KB | 增加5% | C++应用 |
power_save |
~50KB | ~20KB | 增加 | 低功耗设备 |
1. ieee802154
IEEE 802.15.4 协议栈总目录
基于 IEEE 802.15.4 标准的低速率无线个人区域网络
2.4GHz 频段,250kbps 数据速率
低功耗、低成本、低复杂度
Zigbee、6LoWPAN、Thread 的基础协议
2. ieee802154_cli
IEEE 802.15.4 命令行接口
提供 IEEE 802.15.4 网络调试和管理命令行工具
支持网络扫描、设备发现、数据包监控
类似于
iw命令的 802.15.4 版本
📗 Mesh 网络
3. mesh
Mesh 网络总目录
ESP-Mesh 网络协议示例
自组织、自修复的无线网络
4. internal_communication
内部通信示例
Mesh 网络内部节点间通信
数据路由和转发机制
组播和广播通信
5. ip_internal_network
IP 内部网络
在 Mesh 网络上运行 IP 协议栈
支持 TCP/IP over Mesh
网络地址转换(NAT)和路由
6. manual_networking
手动网络配置
手动配置 Mesh 网络参数
静态路由表配置
网络拓扑定制
📙 网络功能
7. network
网络功能总目录
- 高级网络功能示例
8. bridge
网络桥接
在不同网络接口间桥接数据
支持以太网、WiFi、Mesh 桥接
二层数据包转发
9. eth2ap
以太网到 AP 模式
将以太网连接转换为 WiFi AP
有线网络无线扩展
网络共享功能
10. simple_sniffer
简单网络嗅探器
捕获和分析网络数据包
协议分析和调试
网络安全监控
11. sta2eth
STA 模式到以太网
WiFi STA 连接到以太网
无线到有线的网络桥接
客户端网络扩展
12. vlan_support
VLAN 支持
虚拟局域网功能
802.1Q VLAN 标签支持
网络流量隔离
📘 OpenThread 协议栈
13. openthread
OpenThread 总目录
Google 开源的 Thread 协议栈实现
IPv6 over 802.15.4 网状网络
低功耗 IoT 网络协议
14. ot_sleepy_device
睡眠设备示例
Thread 网络中的睡眠节点实现
极低功耗设计
周期性唤醒通信
15. deep_sleep
深度睡眠模式
Thread 设备深度睡眠管理
超低功耗运行
电池供电设备优化
16. light_sleep
浅睡眠模式
Thread 设备浅睡眠管理
快速唤醒响应
平衡功耗和性能
17. ot_br
OpenThread 边界路由器
Thread 网络与 IP 网络的边界路由器
网络协议转换
网关功能实现
18. ot_cli
OpenThread 命令行接口
Thread 网络管理和调试命令行工具
完整的 Thread 命令集
网络诊断和配置
19. ot_rcp
无线协处理器模式
ESP32 作为 Thread 无线协处理器
通过 SPI/UART 连接外部主机
专有 Thread 无线模块
20. ot_trel
Thread over Ethernet/WiFi
在以太网或 WiFi 上运行 Thread 协议
扩展 Thread 网络覆盖范围
混合网络拓扑
📗 外设示例
21. peripherals
外设功能总目录
- ESP32 外设使用示例
22. adc
模数转换器示例
ESP32 ADC 模块使用
模拟信号采集和数字化
23. continuous_read
连续读取模式
ADC 连续采样模式
高速数据采集
实时信号处理
24. oneshot_read
单次读取模式
ADC 单次采样模式
低功耗采样
事件触发采样
🎯 应用场景深度解析
智能家居 Thread 网络
yaml
网络架构:
Thread 骨干网络:
├── ot_br (边界路由器,连接互联网)
├── ot_sleepy_device (传感器节点,深度睡眠)
└── ot_cli (网络管理工具)
混合网络:
├── bridge (Thread-WiFi 桥接)
├── eth2ap (有线到无线扩展)
└── mesh (Mesh 网络扩展)
应用特性:
- IPv6 端到端通信
- 低功耗电池设备
- 自组织、自修复网络
- 安全加密通信
工业物联网 802.15.4 网络
yaml
网络架构:
802.15.4 网络:
├── ieee802154_cli (网络调试)
├── manual_networking (定制拓扑)
└── simple_sniffer (网络监控)
数据采集:
├── continuous_read (连续数据采集)
├── adc (传感器接口)
└── ip_internal_network (IP 化数据)
应用特性:
- 工业级可靠性
- 实时数据采集
- 抗干扰能力
- 长距离覆盖
混合网络网关设备
yaml
网关功能:
协议转换:
├── bridge (二层桥接)
├── ot_br (Thread 网关)
└── sta2eth (WiFi-以太网转换)
网络管理:
├── vlan_support (网络隔离)
├── internal_communication (内部路由)
└── ot_trel (扩展网络)
应用特性:
- 多协议支持
- 网络聚合
- 流量管理
- 安全隔离
🔧 技术实现指南
OpenThread 网络配置
bash
# 启动 Thread 网络
ot-cli dataset init new
ot-cli dataset commit active
ot-cli ifconfig up
ot-cli thread start
# 网络诊断
ot-cli state # 查看设备状态
ot-cli networkdiagnostic get # 网络诊断
ot-cli ping <ipv6_addr> # IPv6 ping 测试
# 睡眠配置
ot-cli dataset meshlocalprefix <prefix>
ot-cli pollperiod <ms> # 设置轮询周期
802.15.4 网络管理
c
// 初始化 802.15.4 接口
esp_ieee802154_init(&config);
// 设置信道和 PAN ID
esp_ieee802154_set_channel(11); // 2.4GHz 信道 11
esp_ieee802154_set_pan_id(0x1234); // PAN ID
// 启用接收
esp_ieee802154_receive();
// 发送数据
esp_ieee802154_transmit(data, len, &result);
Mesh 网络配置
c
// Mesh 网络初始化
esp_mesh_init(&config);
// 设置网络参数
esp_mesh_set_id(&id);
esp_mesh_set_password(password);
// 启动网络
esp_mesh_start();
// 数据发送
esp_mesh_send(&to, data, len, protocol, &flag);
🚀 开发工作流
Thread 设备开发流程
bash
# 1. 选择设备类型
# 边界路由器: ot_br
# 路由设备: openthread
# 睡眠设备: ot_sleepy_device
# 2. 配置网络参数
idf.py menuconfig
# 配置 Thread 网络参数
# 配置睡眠策略
# 配置安全选项
# 3. 网络调试
# 使用 ot_cli 调试网络
# 使用 ieee802154_cli 调试物理层
# 使用 simple_sniffer 抓包分析
混合网络集成
c
// Thread 和 WiFi 共存配置
void setup_hybrid_network(void) {
// 1. 初始化 Thread
otInstance *instance = otSysInit(argc, argv);
// 2. 初始化 WiFi
wifi_init();
// 3. 配置桥接
esp_bridge_init();
// 4. 设置网络路由
setup_routing_table();
}
// 数据转发逻辑
void forward_packet(void *data, int len, int src_if, int dst_if) {
if (src_if == THREAD_IF && dst_if == WIFI_IF) {
// Thread -> WiFi 转发
wifi_send(data, len);
} else if (src_if == WIFI_IF && dst_if == THREAD_IF) {
// WiFi -> Thread 转发
thread_send(data, len);
}
}
功耗优化策略
c
// 睡眠设备配置
void configure_sleepy_device(void) {
// 1. 设置睡眠参数
esp_sleep_enable_timer_wakeup(SLEEP_DURATION);
// 2. 配置 Thread 轮询周期
otLinkSetPollPeriod(instance, POLL_PERIOD);
// 3. 优化发送功率
esp_ieee802154_set_tx_power(TX_POWER_LOW);
// 4. 启用深度睡眠
if (is_battery_powered()) {
enable_deep_sleep();
} else {
enable_light_sleep();
}
}
📊 性能特性参考
| 协议/示例 | 数据速率 | 功耗 | 覆盖范围 | 节点数量 | 延迟 |
|---|---|---|---|---|---|
| 802.15.4 | 250 kbps | 极低 | 10-100m | 65000+ | 中等 |
| OpenThread | 250 kbps | 低 | 10-100m | 250+ | 低 |
| ESP-Mesh | 1-54 Mbps | 中等 | 50-500m | 1000 | 可变 |
| WiFi | 1-150 Mbps | 高 | 50-300m | 200 | 低 |
功耗对比
text
设备类型 | 工作电流 | 睡眠电流 | 电池寿命
-------------------------|----------|----------|----------
Thread 路由设备 | 20-30mA | 10-20μA | 月-年级
Thread 睡眠设备 | 15-25mA | 1-5μA | 年级
802.15.4 基础设备 | 15-20mA | 1-10μA | 年-年级
ESP-Mesh 设备 | 50-100mA | 10-50μA | 天-月级
🔍 网络调试工具
OpenThread 诊断命令
bash
# 网络拓扑查看
ot-cli router table
ot-cli child table
# 网络状态监控
ot-cli netstat
ot-cli counters
# 性能测试
ot-cli diag
ot-cli perf
802.15.4 调试工具
bash
# 信道扫描
ieee802154 scan
# 数据包捕获
ieee802154 sniff channel 11
# 设备发现
ieee802154 discover
# 链路质量测试
ieee802154 lqi <address>
摄像头与图像处理
1. camera
摄像头模块总目录
ESP32 摄像头功能集成
支持多种摄像头传感器
图像采集和处理框架
2. dvp_isp_dsi
DVP 接口摄像头 + ISP + DSI 显示
DVP(Digital Video Port)接口摄像头驱动
ISP(Image Signal Processor)图像信号处理
DSI(Display Serial Interface)显示接口输出
完整的摄像头到显示流水线
3. mipi_isp_dsi
MIPI 接口摄像头 + ISP + DSI 显示
MIPI(Mobile Industry Processor Interface)摄像头接口
高速串行图像数据传输
ISP 图像处理和 DSI 显示输出
移动设备级摄像头系统
📗 DAC(数模转换器)
4. dac
DAC 功能总目录
ESP32 DAC 模块使用示例
数字信号到模拟信号转换
5. dac_continuous
DAC 连续输出模式
连续波形生成
高精度模拟信号输出
音频和信号生成应用
6. dac_audio
DAC 音频输出
音频 DAC 功能实现
PCM 音频数据转换
模拟音频输出
7. signal_generator
信号发生器
生成各种波形信号
支持正弦波、方波、三角波、锯齿波
可调频率和幅度
8. dac_cosine_wave
DAC 余弦波生成
高精度余弦波输出
内置余弦波发生器使用
低 CPU 开销的波形生成
9. dac_oneshot
DAC 单次输出模式
单次电压输出
静态电压设置
电平控制应用
📙 GPIO 与数字接口
10. dedicated_gpio
专用 GPIO 管理器
硬件级 GPIO 事件响应
中断和事件触发优化
低延迟 GPIO 控制
11. soft_i2c
软件 I2C 实现
GPIO 模拟的 I2C 主从设备
灵活的引脚配置
当硬件 I2C 不足时的替代方案
12. soft_spi
软件 SPI 实现
GPIO 模拟的 SPI 主从设备
自定义时钟极性和相位
多从设备管理
13. soft_uart
软件 UART 实现
GPIO 模拟的 UART 串口
额外的串口通道
自定义波特率和格式
14. gpio
GPIO 基础功能
GPIO 输入输出基础操作
中断和事件处理
上下拉电阻配置
15. generic_gpio
通用 GPIO 应用
GPIO 通用控制模式
输入捕获和输出比较
电平转换和信号调理
16. matrix_keyboard
矩阵键盘
矩阵键盘扫描驱动
按键检测和消抖
多按键组合识别
📘 硬件 I2C 接口
17. i2c
I2C 接口总目录
- ESP32 硬件 I2C 控制器使用
18. i2c_eeprom
I2C EEPROM 读写
I2C EEPROM 存储器操作
页读写和字节操作
存储数据管理
19. i2c_slave_network_sensor
I2C 从设备网络传感器
ESP32 作为 I2C 从设备
模拟传感器数据
多主设备支持
20. i2c_tools
I2C 调试工具
I2C 总线扫描工具
设备检测和识别
寄存器读写测试
📗 I2S 音频接口
21. i2s
I2S 接口总目录
- ESP32 I2S 音频接口使用
22. i2s_basic
I2S 基础功能
I2S 基础配置和传输
音频数据采集和播放
标准 I2S 协议
23. i2s_pdm
PDM 麦克风接口
PDM(Pulse Density Modulation)麦克风支持
数字麦克风数据采集
PDM 到 PCM 转换
24. i2s_std
标准 I2S 模式
标准 I2S 协议实现
左右声道分离
音频编解码器接口
25. i2s_tdm
TDM 多通道音频
TDM(Time Division Multiplexing)模式
多通道音频数据传输
专业音频设备接口
🎯 应用场景深度解析
智能家居视觉系统
yaml
硬件配置:
- 摄像头: dvp_isp_dsi 或 mipi_isp_dsi
- 音频: i2s_pdm (麦克风) + dac_audio (扬声器)
- 控制: matrix_keyboard (触摸/按键)
软件架构:
视觉处理:
├── 图像采集 (摄像头驱动)
├── ISP 处理 (图像增强)
└── 显示输出 (DSI 接口)
音频处理:
├── 语音采集 (PDM 麦克风)
├── 音频输出 (DAC 音频)
└── 音效处理 (I2S 数据)
用户交互:
├── 按键输入 (矩阵键盘)
├── GPIO 控制 (外设接口)
└── I2C 通信 (传感器)
工业数据采集系统
yaml
硬件配置:
- 模拟输入: dedicated_gpio (高速采集)
- 数字接口: soft_uart/soft_i2c (扩展接口)
- 信号输出: dac_continuous (控制信号)
软件架构:
数据采集:
├── 模拟信号 (ADC + DAC)
├── 数字信号 (GPIO + I2C)
└── 串行数据 (UART + SPI)
信号处理:
├── 波形生成 (signal_generator)
├── 滤波处理 (DSP 算法)
└── 控制输出 (dac_oneshot)
通信接口:
├── 主从通信 (i2c_slave)
├── 设备管理 (i2c_tools)
└── 网络传输 (网络栈)
专业音频设备
yaml
硬件配置:
- 音频接口: i2s_std + i2s_tdm
- 信号处理: dac_cosine_wave (测试信号)
- 控制接口: generic_gpio (控制信号)
软件架构:
音频处理:
├── 多通道输入 (TDM 接口)
├── 数字处理 (DSP 算法)
└── 高品质输出 (I2S 标准)
测试功能:
├── 信号生成 (各种波形)
├── 音频分析 (频谱分析)
└── 性能测试 (延迟测试)
控制管理:
├── 参数调节 (旋转编码器)
├── 状态显示 (显示屏)
└── 预设管理 (EEPROM)
🔧 技术实现指南
摄像头系统配置
c
// DVP 摄像头初始化
camera_config_t config = {
.pin_pwdn = -1,
.pin_reset = -1,
.pin_xclk = 21,
.pin_sccb_sda = 26,
.pin_sccb_scl = 27,
.pin_d7 = 35,
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 19,
.pin_d2 = 18,
.pin_d1 = 5,
.pin_d0 = 4,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.xclk_freq_hz = 20000000,
.frame_size = FRAMESIZE_QVGA,
.pixel_format = PIXFORMAT_JPEG,
.fb_count = 2
};
esp_err_t err = esp_camera_init(&config);
DAC 波形生成
c
// 余弦波生成配置
dac_cw_config_t cw_config = {
.en_ch = DAC_CHANNEL_1,
.scale = DAC_CW_SCALE_1,
.phase = DAC_CW_PHASE_0,
.freq = 1000, // 1kHz
.offset = 64 // 偏置电压
};
dac_cosine_wave_config(&cw_config);
dac_cosine_wave_enable();
// 连续输出配置
dac_continuous_config_t cont_config = {
.chan_mask = DAC_CHANNEL_MASK_ALL,
.desc_num = 8,
.buf_size = 2048,
.freq_hz = 44100, // 音频采样率
.offset = 0,
.clk_src = DAC_DIGI_CLK_SRC_DEFAULT,
};
dac_continuous_new_channels(&cont_config, &handle);
矩阵键盘实现
c
// 矩阵键盘配置 (4x4)
#define ROWS 4
#define COLS 4
uint8_t row_pins[ROWS] = {12, 13, 14, 15};
uint8_t col_pins[COLS] = {16, 17, 18, 19};
// 键盘扫描函数
void matrix_keyboard_scan(void) {
for (int col = 0; col < COLS; col++) {
// 设置列线为输出低电平
gpio_set_level(col_pins[col], 0);
for (int row = 0; row < ROWS; row++) {
// 读取行线电平
int level = gpio_get_level(row_pins[row]);
if (level == 0) {
// 按键按下处理
handle_key_press(row, col);
}
}
// 恢复列线为高阻态
gpio_set_level(col_pins[col], 1);
}
}
I2S 多通道音频
c
// TDM 多通道配置
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
i2s_tdm_config_t tdm_cfg = {
.clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(44100),
.slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
I2S_DATA_BIT_WIDTH_32BIT,
I2S_SLOT_MODE_STEREO,
I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3
),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = 26,
.ws = 25,
.dout = 22,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
i2s_channel_init_tdm_mode(tx_handle, &tdm_cfg);
🚀 开发最佳实践
外设资源管理
c
// 资源分配策略
typedef struct {
i2s_chan_handle_t i2s_handle;
dac_continuous_handle_t dac_handle;
camera_handle_t camera_handle;
i2c_master_bus_handle_t i2c_bus;
} peripheral_resources_t;
// 初始化顺序优化
esp_err_t init_peripherals(peripheral_resources_t *res) {
// 1. 先初始化低速接口
ESP_ERROR_CHECK(init_i2c_bus(&res->i2c_bus));
ESP_ERROR_CHECK(init_sensors(res->i2c_bus));
// 2. 初始化中速接口
ESP_ERROR_CHECK(init_camera(&res->camera_handle));
// 3. 初始化高速接口
ESP_ERROR_CHECK(init_i2s(&res->i2s_handle));
ESP_ERROR_CHECK(init_dac(&res->dac_handle));
return ESP_OK;
}
功耗优化
c
// 外设功耗管理
void manage_peripheral_power(bool enable) {
if (enable) {
// 启用必要外设
power_on_camera();
power_on_i2s();
power_on_dac();
} else {
// 关闭非必要外设
power_off_camera();
power_off_i2s();
// DAC 保持最低功耗模式
dac_continuous_disable(res->dac_handle);
}
}
// 动态频率调整
void adjust_peripheral_frequency(perf_mode_t mode) {
switch (mode) {
case PERF_HIGH:
set_camera_fps(30);
set_i2s_sample_rate(48000);
set_dac_update_rate(100000);
break;
case PERF_MEDIUM:
set_camera_fps(15);
set_i2s_sample_rate(44100);
set_dac_update_rate(50000);
break;
case PERF_LOW:
set_camera_fps(5);
set_i2s_sample_rate(22050);
set_dac_update_rate(10000);
break;
}
}
📊 性能特性参考
| 外设 | 最大速度 | 精度 | 功耗 | 典型应用 |
|---|---|---|---|---|
| DAC | 8MHz (连续) | 8-bit | 低 | 音频输出、信号生成 |
| GPIO | 80MHz | 数字 | 极低 | 控制信号、中断 |
| I2C | 1MHz | 8-bit | 低 | 传感器、EEPROM |
| I2S | 40MHz | 16-32bit | 中 | 音频编解码器 |
| 摄像头 | 20MP/s | 8-10bit | 高 | 图像采集、视频 |
| 软接口 | 可变 | 数字 | 中 | 接口扩展 |
时序特性
text
DAC 响应时间: < 1μs
GPIO 中断延迟: < 10μs
I2C 传输速率: 100kbps - 1Mbps
I2S 音频延迟: < 10ms
摄像头帧率: 1-60 FPS (取决于分辨率)
I2S 音频编解码器
1. i2s_codec
I2S 音频编解码器总目录
音频编解码器芯片驱动和集成
完整的音频输入输出解决方案
2. i2s_es7210_tdm
ES7210 TDM 麦克风阵列编解码器
ES7210 多通道音频 ADC 驱动
支持 4 通道 TDM 麦克风阵列
高精度语音采集
适用于语音识别和会议系统
3. i2s_es8311
ES8311 音频编解码器
ES8311 低功耗音频 Codec 驱动
集成 ADC 和 DAC
支持耳机和扬声器输出
适用于便携式音频设备
4. i2s_recorder
I2S 录音机示例
完整的音频录制功能
支持麦克风输入录制
音频数据存储和处理
实时音频流处理
📗 ISP 图像信号处理器
5. isp
ISP 图像信号处理器总目录
ESP32-S3 内置 ISP 功能
图像增强和预处理
6. multi_pipelines
多管道 ISP 处理
并行多个图像处理管道
同时处理不同分辨率和格式
多路视频流处理
实时图像分析应用
📙 JPEG 编解码
7. jpeg
JPEG 图像编解码总目录
- ESP32 JPEG 硬件编解码器使用
8. jpeg_decode
JPEG 解码
JPEG 图像硬件解码
支持多种 JPEG 格式
高效图像显示预处理
节省 CPU 资源
9. jpeg_encode
JPEG 编码
图像数据硬件 JPEG 编码
支持质量参数调整
图像压缩和存储优化
网络传输优化
📘 LCD 显示控制
10. lcd
LCD 显示总目录
- 多种 LCD 接口和控制器支持
11. i2c_oled
I2C OLED 显示屏
SSD1306/SSH1106 OLED 驱动
I2C 接口 OLED 控制
文本和图形显示
低功耗显示方案
12. i80_controller
Intel 8080 并行接口控制器
i80 并行接口 LCD 驱动
高速并行数据传输
适用于大尺寸 LCD
全彩图像显示
13. mipi_dsi
MIPI DSI 显示接口
MIPI Display Serial Interface
高速串行显示接口
支持高分辨率显示屏
移动设备级显示
14. rgb_panel
RGB 接口面板
RGB 并行接口 LCD
支持多种 RGB 格式
高刷新率显示
视频播放应用
15. spi_lcd_touch
SPI LCD 带触摸屏
SPI 接口 LCD 驱动
集成触摸屏控制
图形用户界面支持
交互式显示应用
16. tjpgd
Tiny JPEG Decompressor
软件 JPEG 解码库
轻量级 JPEG 解码
适用于资源受限场景
备用解码方案
📗 LED PWM 控制器
17. ledc
LED PWM 控制器总目录
- ESP32 LEDC 硬件 PWM 控制器
18. ledc_basic
LEDC 基础功能
PWM 基础输出控制
频率和占空比设置
LED 亮度控制
19. ledc_fade
LED 渐变控制
PWM 渐变效果
平滑亮度变化
硬件加速渐变
呼吸灯效果
20. ledc_gamma_curve_fade
Gamma 曲线渐变
基于 Gamma 曲线的亮度控制
符合人眼感知的亮度变化
专业照明控制
显示背光调节
📙 MCPWM 电机控制
21. mcpwm
MCPWM 电机控制总目录
- ESP32 MCPWM 硬件控制器
22. mcpwm_bdc_speed_control
有刷直流电机速度控制
有刷直流电机 PWM 控制
速度闭环控制
方向控制
适用于风扇、泵等
23. mcpwm_bldc_hall_control
无刷直流电机霍尔控制
BLDC 电机六步换相控制
霍尔传感器反馈
速度和位置控制
适用于无人机、机器人
24. mcpwm_capture_hc_sr04
超声波测距模块控制
HC-SR04 超声波模块驱动
PWM 捕获模式测量距离
高精度测距应用
避障和测距系统
25. mcpwm_foc_svpwm_open_loop
磁场定向控制 SVPWM 开环
电机 FOC(磁场定向控制)
SVPWM(空间矢量脉宽调制)
开环电机控制
高性能电机驱动
26. mcpwm_servo_control
舵机控制
PWM 舵机角度控制
支持标准舵机信号
多舵机同步控制
机器人关节控制
🎯 应用场景深度解析
智能语音交互设备
yaml
硬件配置:
- 音频输入: i2s_es7210_tdm (4麦克风阵列)
- 音频输出: i2s_es8311 (扬声器/耳机)
- 显示: i2c_oled (状态显示)
- 控制: ledc_fade (指示灯)
软件架构:
语音处理:
├── 音频采集 (ES7210 TDM)
├── 语音增强 (降噪、波束成形)
├── 编解码处理 (ES8311)
└── 音频录制 (i2s_recorder)
用户交互:
├── 状态显示 (OLED)
├── 视觉反馈 (LED 渐变)
└── 触摸输入 (SPI LCD Touch)
应用功能:
├── 语音助手
├── 录音回放
└── 音乐播放
工业机器视觉系统
yaml
硬件配置:
- 图像处理: isp (多管道处理)
- 显示: rgb_panel (实时监控)
- 编码: jpeg_encode (图像存储)
- 控制: mcpwm (电机控制)
软件架构:
视觉处理:
├── 多路视频流 (multi_pipelines)
├── 图像增强 (ISP 处理)
├── JPEG 压缩 (硬件编码)
└── 实时显示 (RGB 面板)
运动控制:
├── 电机驱动 (BLDC/PMSM)
├── 位置反馈 (霍尔/编码器)
├── 高级控制 (FOC SVPWM)
└── 舵机控制 (伺服机构)
系统集成:
├── 超声波测距 (避障)
├── 状态监控 (LED 指示)
└── 数据存储 (JPEG 图像)
专业显示控制设备
yaml
硬件配置:
- 高分辨率: mipi_dsi (手机级显示)
- 高速接口: i80_controller (并行传输)
- 图像处理: jpeg_decode (快速显示)
- 背光控制: ledc_gamma_curve (专业调光)
软件架构:
显示系统:
├── 高速数据传输 (MIPI DSI)
├── 图像解码 (硬件 JPEG)
├── 图形渲染 (2D 加速)
└── 触摸交互 (SPI 触摸屏)
背光管理:
├── Gamma 校正 (人眼优化)
├── 自动调光 (环境光感应)
├── 节能模式 (功耗管理)
└── 渐变效果 (平滑过渡)
应用场景:
├── 工业 HMI
├── 医疗显示
├── 车载中控
└── 广告显示
🔧 技术实现指南
ES7210 TDM 麦克风阵列配置
c
// ES7210 初始化配置
es7210_codec_config_t es7210_config = {
.i2c_port = I2C_NUM_0,
.i2c_addr = ES7210_ADDR,
.sample_rate = ES7210_SAMPLE_RATE_16K,
.bit_width = ES7210_BIT_WIDTH_16BIT,
.mic_bias = ES7210_MIC_BIAS_2_2V,
.mic_gain = ES7210_MIC_GAIN_30DB,
.channels = {
.channel_mask = ES7210_CHANNEL_MASK_ALL,
.channel_slot = {
ES7210_INPUT_MIC1,
ES7210_INPUT_MIC2,
ES7210_INPUT_MIC3,
ES7210_INPUT_MIC4
}
}
};
es7210_codec_init(&es7210_config);
// TDM 模式配置
i2s_tdm_config_t tdm_config = {
.clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(
I2S_DATA_BIT_WIDTH_32BIT,
I2S_SLOT_MODE_TDM,
I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3
),
.gpio_cfg = {...},
};
JPEG 硬件编解码
c
// JPEG 解码配置
jpeg_dec_config_t dec_config = {
.output_format = JPEG_DEC_RGB565,
.rgb_order = JPEG_DEC_RGB_ORDER_RGB,
.scale = JPEG_DEC_SCALE_1_2, // 1/2 缩放
.dithering_en = true, // 启用抖动
};
jpeg_dec_handle_t *dec_handle;
jpeg_new_decoder(&dec_config, &dec_handle);
// 解码 JPEG 图像
jpeg_dec_header_info_t header_info;
jpeg_dec_process(dec_handle, &header_info);
jpeg_dec_get_image_size(dec_handle, &width, &height);
// JPEG 编码配置
jpeg_enc_config_t enc_config = {
.width = 640,
.height = 480,
.quality = 85, // 质量 85%
.format = JPEG_ENC_FORMAT_RGB888,
.sub_sample = JPEG_ENC_SUB_SAMPLE_422,
};
jpeg_enc_handle_t *enc_handle;
jpeg_new_encoder(&enc_config, &enc_handle);
MCPWM BLDC 霍尔控制
c
// BLDC 电机配置
mcpwm_bldc_config_t bldc_config = {
.pwm_freq_hz = 20000, // 20kHz PWM 频率
.group_id = 0,
.gpio_num = {
.uh = GPIO_NUM_19, // U 相高侧
.ul = GPIO_NUM_18, // U 相低侧
.vh = GPIO_NUM_17,
.vl = GPIO_NUM_16,
.wh = GPIO_NUM_15,
.wl = GPIO_NUM_14,
},
};
mcpwm_bldc_handle_t *bldc_handle;
mcpwm_new_bldc(&bldc_config, &bldc_handle);
// 霍尔传感器配置
hall_sensor_config_t hall_config = {
.gpio_num = {
GPIO_NUM_32, // Hall U
GPIO_NUM_33, // Hall V
GPIO_NUM_25, // Hall W
},
.active_level = 0,
};
// 六步换相控制
void bldc_commutation_step(int step) {
const uint8_t step_pattern[6][6] = {
// UH UL VH VL WH WL
{1, 0, 0, 1, 0, 0}, // Step 1
{1, 0, 0, 0, 0, 1}, // Step 2
{0, 0, 1, 0, 0, 1}, // Step 3
{0, 1, 1, 0, 0, 0}, // Step 4
{0, 1, 0, 0, 1, 0}, // Step 5
{0, 0, 0, 1, 1, 0}, // Step 6
};
apply_pwm_pattern(step_pattern[step]);
}
LEDC Gamma 曲线控制
c
// Gamma 校正表 (2.2 Gamma)
const uint32_t gamma_table[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
// ... 完整的 Gamma 表
};
// Gamma 校正渐变
void gamma_fade_led(uint32_t duty_from, uint32_t duty_to, uint32_t duration_ms) {
uint32_t steps = duration_ms / 10; // 10ms 每步
float delta = (float)(duty_to - duty_from) / steps;
for (int i = 0; i <= steps; i++) {
uint32_t linear_duty = duty_from + (uint32_t)(delta * i);
uint32_t gamma_duty = gamma_table[linear_duty * 255 / LEDC_MAX_DUTY];
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, gamma_duty);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
🚀 开发最佳实践
多外设协同工作
c
// 音频-显示-控制协同框架
typedef struct {
// 音频子系统
es7210_handle_t *mic_array;
es8311_handle_t *codec;
i2s_chan_handle_t i2s_rx;
i2s_chan_handle_t i2s_tx;
// 显示子系统
lcd_panel_handle_t lcd;
jpeg_dec_handle_t *jpeg_dec;
// 控制子系统
mcpwm_bldc_handle_t *motor;
ledc_channel_handle_t led;
} multimedia_system_t;
// 同步控制函数
void sync_audio_visual(multimedia_system_t *sys, audio_visual_event_t event) {
switch (event) {
case AV_EVENT_START:
// 启动音频采集
i2s_channel_enable(sys->i2s_rx);
// 启动显示更新
lcd_refresh(sys->lcd);
// 控制 LED 反馈
ledc_fade_start(sys->led);
break;
case AV_EVENT_STOP:
// 同步停止所有外设
i2s_channel_disable(sys->i2s_rx);
lcd_sleep(sys->lcd);
ledc_fade_stop(sys->led);
break;
}
}
实时性能优化
c
// DMA 缓冲区优化
void optimize_dma_buffers(void) {
// 音频 DMA 配置
i2s_dma_config_t audio_dma = {
.auto_clear = true,
.size = 4096, // 4KB 缓冲区
.cnt = 8, // 8 个缓冲区
.align = 4096, // 4KB 对齐
};
// 显示 DMA 配置
lcd_dma_config_t display_dma = {
.buffer_size = 8192, // 8KB 缓冲区
.trans_queue_depth = 4, // 4 级传输队列
.psram_trans_align = 64, // 64字节对齐
};
// MCPWM DMA 配置
mcpwm_dma_config_t motor_dma = {
.burst_size = 16, // 16字突发传输
.threshold = 8, // 8字阈值
};
}
📊 性能特性参考
| 模块 | 分辨率/通道 | 帧率/采样率 | 延迟 | 功耗 |
|---|---|---|---|---|
| ES7210 TDM | 4通道 | 8-48kHz | < 5ms | 低 |
| ES8311 Codec | 立体声 | 8-48kHz | < 10ms | 中 |
| ISP 多管道 | 1080p x2 | 30fps | < 33ms | 高 |
| JPEG 编解码 | 4096x4096 | 60fps (1080p) | < 16ms | 中 |
| MIPI DSI | 1080p | 60Hz | < 1ms | 中高 |
| BLDC FOC | 6通道 PWM | 20kHz | < 50μs | 高 |
显示性能对比
text
接口类型 最大分辨率 刷新率 颜色深度 适用场景
I2C OLED 128x64 60Hz 1-bit 状态显示
SPI LCD 320x240 60Hz 16-bit 小型 GUI
RGB Panel 800x480 60Hz 24-bit 视频播放
MIPI DSI 1920x1080 60Hz 24-bit 高清显示
i80 并行 1024x768 75Hz 18-bit 工业 HMI
MCPWM 同步功能
1. mcpwm_sync
MCPWM 同步功能
多个 MCPWM 控制器同步操作
相位同步和时序对齐
多轴同步运动控制
适用于需要精确时序同步的应用
📗 ParlIO 并行输入输出接口
2. parlio_rx
并行输入接口
高速并行数据输入接口
支持 8/16/24/32 位并行数据
数据捕获和缓冲管理
3. logic_analyzer (parlio_rx 子项)
逻辑分析仪
使用 ParlIO 实现简易逻辑分析仪
多通道数字信号捕获
信号时序分析和显示
数字电路调试工具
4. parlio_tx
并行输出接口
高速并行数据输出接口
支持多种并行输出模式
实时数据流输出
5. simple_rgb_led_matrix (parlio_tx 子项)
简易 RGB LED 矩阵驱动
驱动 RGB LED 矩阵显示
ParlIO 高速刷新控制
灰度控制和颜色混合
LED 显示屏应用
📙 脉冲计数器 (PCNT)
6. pcnt
脉冲计数器总目录
- ESP32 PCNT 硬件脉冲计数器
7. rotary_encoder
旋转编码器
正交编码器信号解码
位置和速度测量
工业编码器接口
电机位置反馈
📘 像素处理加速器 (PPA)
8. ppa
像素处理加速器总目录
- ESP32-S3 PPA 硬件加速器
9. ppa_dsi
PPA DSI 显示加速
PPA 与 MIPI DSI 显示协同工作
硬件加速图像处理
实时图像叠加和混合
显示性能优化
📗 RMT (红外遥控器)
10. rmt
RMT 红外遥控模块总目录
- ESP32 RMT 硬件控制器
11. dshot_esc
DShot ESC 电调控制
DShot 数字协议电调控制
无人机 ESC 驱动
高速 PWM 信号生成
无人机飞控应用
12. ir_nec_transceiver
红外 NEC 协议收发
红外遥控 NEC 协议实现
发送和接收红外信号
家电遥控器控制
红外学习和转发
13. led_strip
LED 灯带控制
WS2812/SK6812 LED 灯带驱动
RGB/RGBW LED 控制
动画效果和颜色混合
智能照明应用
14. led_strip_simple_encoder
LED 灯带简单编码器
简化版 LED 灯带驱动
基础颜色控制
内存优化版本
15. musical_buzzer
音乐蜂鸣器
使用 RMT 生成音乐信号
频率和音调控制
简单旋律播放
报警和提示音
16. onewire
单总线协议
Dallas 单总线协议实现
DS18B20 温度传感器驱动
单总线设备通信
传感器网络
17. stepper_motor
步进电机控制
步进电机脉冲控制
细分驱动支持
速度和位置控制
3D 打印/CNC 应用
📙 SDIO 接口
18. sdio
SDIO 接口总目录
- ESP32 SDIO 主机/从机接口
19. host
SDIO 主机模式
SDIO 主机控制器
SD 卡和 SDIO 设备通信
高速数据传输
存储扩展
20. slave
SDIO 从机模式
ESP32 作为 SDIO 从设备
与主机处理器通信
高速外设接口
协处理器应用
📘 Sigma-Delta 调制器
21. sigma_delta
Sigma-Delta 调制器总目录
- ESP32 SDM 模块
22. sdm_dac
SDM DAC 输出
Sigma-Delta DAC 实现
高分辨率模拟输出
音频和信号生成
低成本 DAC 方案
23. sdm_led
SDM LED 调光
Sigma-Delta LED 调光控制
高精度 PWM 替代方案
无闪烁调光
专业照明控制
📗 SPI 主机接口
24. spi_master
SPI 主机接口总目录
- ESP32 SPI 主机控制器
25. hd_eeprom
高密度 EEPROM
大容量 SPI EEPROM 驱动
页编程和扇区擦除
数据存储管理
配置参数存储
🎯 应用场景深度解析
工业自动化控制系统
yaml
硬件配置:
- 运动控制: mcpwm_sync (多轴同步)
- 位置反馈: rotary_encoder (高精度编码器)
- 执行机构: stepper_motor (步进电机)
- 信号监控: logic_analyzer (调试工具)
软件架构:
运动控制:
├── 多轴同步 (MCPWM 同步)
├── 闭环控制 (编码器反馈)
├── 轨迹规划 (运动算法)
└── 故障保护 (实时监控)
数据采集:
├── 高速采集 (ParlIO RX)
├── 信号处理 (数字滤波)
├── 数据存储 (HD EEPROM)
└── 通信接口 (SDIO 从机)
用户界面:
├── 状态显示 (LED 矩阵)
├── 操作输入 (旋转编码器)
└── 报警指示 (LED 灯带)
无人机飞行控制系统
yaml
硬件配置:
- 电机控制: dshot_esc (电调驱动)
- 传感器: onewire (温度监控)
- 灯光: led_strip (航向灯)
- 存储: sdio_host (数据记录)
软件架构:
飞行控制:
├── 电调控制 (DShot 协议)
├── PID 控制算法
├── 姿态解算
└── 飞行模式切换
传感器系统:
├── 温度监测 (DS18B20)
├── 电压监控 (ADC)
├── 信号处理 (滤波)
└── 故障检测
灯光系统:
├── 航向指示灯 (RGB LED)
├── 状态显示 (动画效果)
├── 夜间照明 (调光控制)
└── 故障报警 (闪烁模式)
智能显示与广告系统
yaml
硬件配置:
- 显示加速: ppa_dsi (图像处理)
- LED 显示: simple_rgb_led_matrix
- 背光控制: sdm_led (调光)
- 远程控制: ir_nec_transceiver
软件架构:
显示处理:
├── 图像加速 (PPA 硬件)
├── 视频解码 (硬件解码器)
├── 特效处理 (叠加混合)
└── 实时渲染 (图形引擎)
灯光控制:
├── LED 矩阵驱动 (ParlIO TX)
├── 灰度控制 (PWM/模拟)
├── 颜色校准 (Gamma 校正)
└── 节能模式 (自动调光)
控制系统:
├── 红外遥控 (NEC 协议)
├── 定时任务 (调度器)
├── 内容管理 (SD 卡)
└── 网络更新 (OTA)
🔧 技术实现指南
多轴 MCPWM 同步配置
c
// MCPWM 同步配置
typedef struct {
mcpwm_timer_handle_t timers[3]; // 三个轴
mcpwm_sync_handle_t sync_src; // 同步源
mcpwm_capture_timer_handle_t cap_timer; // 捕获定时器
} multi_axis_sync_t;
// 创建同步多轴系统
void create_sync_multi_axis(multi_axis_sync_t *sys) {
// 1. 配置同步源 (GPIO 输入)
mcpwm_gpio_sync_src_config_t sync_config = {
.group_id = 0,
.gpio_num = GPIO_NUM_18,
.flags.pull_down = true,
.flags.active_neg = false,
};
mcpwm_new_gpio_sync_src(&sync_config, &sys->sync_src);
// 2. 创建三个定时器并同步
for (int i = 0; i < 3; i++) {
mcpwm_timer_config_t timer_config = {
.group_id = 0,
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
.resolution_hz = 10 * 1000 * 1000, // 10MHz
.count_mode = MCPWM_TIMER_COUNT_MODE_UP,
.period_ticks = 10000, // 1ms @ 10MHz
};
mcpwm_new_timer(&timer_config, &sys->timers[i]);
// 应用同步源
mcpwm_timer_set_sync_src(sys->timers[i], sys->sync_src, MCPWM_SYNC_SRC_PROVIDED);
// 设置相位偏移
mcpwm_timer_set_phase_on_sync(sys->timers[i],
(mcpwm_timer_direction_t)MCPWM_TIMER_DIRECTION_UP,
i * 1000); // 每轴偏移 100us
}
}
正交编码器解码实现
c
// 旋转编码器配置
pcnt_unit_config_t unit_config = {
.high_limit = 10000,
.low_limit = -10000,
.flags.accum_count = true, // 累积计数
};
pcnt_chan_config_t chan_a_config = {
.edge_gpio_num = ENCODER_A_GPIO,
.level_gpio_num = ENCODER_B_GPIO,
};
pcnt_chan_config_t chan_b_config = {
.edge_gpio_num = ENCODER_B_GPIO,
.level_gpio_num = ENCODER_A_GPIO,
};
// 创建 PCNT 单元
pcnt_unit_handle_t pcnt_unit;
pcnt_new_unit(&unit_config, &pcnt_unit);
// 配置通道 A 和 B (正交编码)
pcnt_channel_handle_t pcnt_chan_a, pcnt_chan_b;
pcnt_new_channel(pcnt_unit, &chan_a_config, &pcnt_chan_a);
pcnt_new_channel(pcnt_unit, &chan_b_config, &pcnt_chan_b);
// 设置边沿和电平动作
pcnt_chan_set_edge_action(pcnt_chan_a,
PCNT_CHANNEL_EDGE_ACTION_INCREASE, // 上升沿增加
PCNT_CHANNEL_EDGE_ACTION_HOLD); // 下降沿保持
pcnt_chan_set_level_action(pcnt_chan_a,
PCNT_CHANNEL_LEVEL_ACTION_KEEP, // 低电平保持
PCNT_CHANNEL_LEVEL_ACTION_INVERSE); // 高电平反向
// 启动计数
pcnt_unit_enable(pcnt_unit);
pcnt_unit_start(pcnt_unit);
// 读取位置
int pulse_count = 0;
pcnt_unit_get_count(pcnt_unit, &pulse_count);
WS2812 LED 灯带驱动
c
// LED 灯带配置
#define LED_STRIP_LENGTH 30
#define LED_STRIP_RMT_INTR_NUM 19
rmt_encoder_handle_t led_encoder;
rmt_channel_handle_t led_chan;
// 创建 RMT 发送通道
rmt_tx_channel_config_t tx_chan_config = {
.gpio_num = LED_STRIP_GPIO,
.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 10 * 1000 * 1000, // 10MHz
.mem_block_symbols = 64,
.trans_queue_depth = 4,
.flags.invert_out = false,
.flags.with_dma = false,
};
rmt_new_tx_channel(&tx_chan_config, &led_chan);
// 创建 LED 灯带编码器
led_strip_encoder_config_t encoder_config = {
.resolution = 10 * 1000 * 1000,
};
rmt_new_led_strip_encoder(&encoder_config, &led_encoder);
// 安装编码器到通道
rmt_transmit_config_t tx_config = {
.loop_count = 0, // 不循环
};
rmt_enable(led_chan);
// 设置 LED 颜色
void set_led_strip_color(uint32_t *led_colors, size_t led_num) {
rmt_transmit(led_chan, led_encoder, led_colors,
led_num * sizeof(uint32_t), &tx_config);
rmt_tx_wait_all_done(led_chan, portMAX_DELAY);
}
// 彩虹渐变效果
void rainbow_effect(void) {
uint32_t colors[LED_STRIP_LENGTH];
for (int i = 0; i < LED_STRIP_LENGTH; i++) {
// HSV 到 RGB 转换
float hue = (float)i / LED_STRIP_LENGTH * 360.0f;
colors[i] = hsv_to_rgb(hue, 1.0f, 1.0f);
}
set_led_strip_color(colors, LED_STRIP_LENGTH);
}
DShot ESC 电调控制
c
// DShot 协议配置
typedef struct {
uint16_t throttle; // 油门值 (48-2047)
bool telemetry; // 遥测请求
uint8_t checksum; // 校验和
} dshot_packet_t;
// DShot 600 协议参数
#define DSHOT_600_T0H 750 // ns
#define DSHOT_600_T1H 1500 // ns
#define DSHOT_600_T0L 1500 // ns
#define DSHOT_600_T1L 750 // ns
// 创建 DShot ESC 控制器
void dshot_esc_init(void) {
rmt_tx_channel_config_t tx_chan_config = {
.gpio_num = ESC_GPIO,
.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 80 * 1000 * 1000, // 80MHz
.mem_block_symbols = 64,
.trans_queue_depth = 4,
.flags.with_dma = true,
};
rmt_new_tx_channel(&tx_chan_config, &esc_chan);
// 创建 DShot 编码器
dshot_encoder_config_t encoder_config = {
.resolution = 80 * 1000 * 1000,
.t0h_ticks = DSHOT_600_T0H * 80 / 1000,
.t1h_ticks = DSHOT_600_T1H * 80 / 1000,
.t0l_ticks = DSHOT_600_T0L * 80 / 1000,
.t1l_ticks = DSHOT_600_T1L * 80 / 1000,
};
rmt_new_dshot_encoder(&encoder_config, &dshot_encoder);
}
// 发送 DShot 命令
void dshot_send_command(uint16_t throttle, bool telemetry) {
dshot_packet_t packet = {
.throttle = throttle,
.telemetry = telemetry,
};
// 计算校验和
uint16_t data = (throttle << 1) | (telemetry ? 1 : 0);
uint8_t checksum = (data ^ (data >> 4) ^ (data >> 8)) & 0x0F;
packet.checksum = checksum;
// 发送数据包
rmt_transmit(esc_chan, dshot_encoder, &packet,
sizeof(dshot_packet_t), NULL);
}
Sigma-Delta LED 调光
c
// SDM LED 调光配置
sdm_channel_handle_t sdm_chan;
void sdm_led_dimmer_init(void) {
sdm_config_t sdm_config = {
.clk_src = SDM_CLK_SRC_DEFAULT,
.sample_rate_hz = 1 * 1000 * 1000, // 1MHz
.gpio_num = LED_DIMMER_GPIO,
};
sdm_new_channel(&sdm_config, &sdm_chan);
// 设置占空比 (0-255 对应 0-100%)
sdm_channel_set_duty(sdm_chan, 128); // 50% 亮度
sdm_channel_enable(sdm_chan);
}
// 平滑亮度渐变
void sdm_led_fade(uint8_t target_brightness, uint32_t duration_ms) {
uint8_t current_brightness;
sdm_channel_get_duty(sdm_chan, ¤t_brightness);
int steps = duration_ms / 10; // 10ms 每步
float step = (float)(target_brightness - current_brightness) / steps;
for (int i = 0; i <= steps; i++) {
uint8_t brightness = current_brightness + (uint8_t)(step * i);
sdm_channel_set_duty(sdm_chan, brightness);
vTaskDelay(pdMS_TO_TICKS(10));
}
}
// Gamma 校正调光
void sdm_led_gamma_dimming(uint8_t linear_brightness) {
// Gamma 2.2 校正表
static const uint8_t gamma_table[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
// ... 完整的 Gamma 表
};
uint8_t gamma_corrected = gamma_table[linear_brightness];
sdm_channel_set_duty(sdm_chan, gamma_corrected);
}
开发最佳实践
实时控制系统架构
c
// 实时控制任务优先级
typedef enum {
TASK_PRIORITY_CRITICAL = 10, // 关键控制 (ESC, 电机)
TASK_PRIORITY_HIGH = 8, // 传感器读取
TASK_PRIORITY_MEDIUM = 6, // 数据处理
TASK_PRIORITY_LOW = 4, // 用户界面
TASK_PRIORITY_BACKGROUND = 2, // 系统维护
} task_priority_t;
// 实时任务调度
void create_real_time_tasks(void) {
// 关键控制任务 (最高优先级)
xTaskCreate(esc_control_task, "ESC Control", 4096, NULL,
TASK_PRIORITY_CRITICAL, NULL);
// 传感器读取任务
xTaskCreate(sensor_read_task, "Sensor Read", 4096, NULL,
TASK_PRIORITY_HIGH, NULL);
// 数据处理任务
xTaskCreate(data_process_task, "Data Process", 4096, NULL,
TASK_PRIORITY_MEDIUM, NULL);
// 用户界面任务
xTaskCreate(ui_update_task, "UI Update", 4096, NULL,
TASK_PRIORITY_LOW, NULL);
}
电源和热管理
c
// 外设功耗管理
void manage_peripheral_power(power_mode_t mode) {
switch (mode) {
case POWER_MODE_HIGH_PERF:
// 全性能模式
sdm_channel_set_power(sdm_chan, SDM_POWER_HIGH);
rmt_set_power_mode(rmt_chan, RMT_POWER_HIGH);
pcnt_unit_set_power(pcnt_unit, PCNT_POWER_HIGH);
break;
case POWER_MODE_BALANCED:
// 平衡模式
sdm_channel_set_power(sdm_chan, SDM_POWER_MEDIUM);
rmt_set_power_mode(rmt_chan, RMT_POWER_MEDIUM);
pcnt_unit_set_power(pcnt_unit, PCNT_POWER_MEDIUM);
break;
case POWER_MODE_LOW_POWER:
// 低功耗模式
sdm_channel_set_power(sdm_chan, SDM_POWER_LOW);
rmt_set_power_mode(rmt_chan, RMT_POWER_LOW);
pcnt_unit_set_power(pcnt_unit, PCNT_POWER_LOW);
break;
}
}
// 热管理
void thermal_management(void) {
float temp = read_temperature_sensor();
if (temp > 70.0f) {
// 过热保护
manage_peripheral_power(POWER_MODE_LOW_POWER);
activate_cooling_fan();
log_warning("Over temperature: %.1f°C", temp);
} else if (temp > 60.0f) {
// 温度警告
manage_peripheral_power(POWER_MODE_BALANCED);
log_info("High temperature: %.1f°C", temp);
}
}
📊 性能特性参考
| 外设/协议 | 最大频率 | 分辨率 | 延迟 | 典型应用 |
|---|---|---|---|---|
| MCPWM 同步 | 40MHz | 16-bit | < 100ns | 多轴同步 |
| ParlIO RX/TX | 80MHz | 8-32bit | < 50ns | 高速并行 |
| PCNT 编码器 | 80MHz | 16-bit | 实时 | 位置反馈 |
| RMT DShot | 80MHz | 1-bit | < 1μs | 无人机 ESC |
| RMT LED 灯带 | 40MHz | 24-bit | < 10μs | RGB LED |
| SDM 调光 | 1MHz | 8-bit | < 1ms | LED 调光 |
| SPI EEPROM | 80MHz | 8-bit | 可变 | 数据存储 |
通信协议性能对比
text
协议 数据速率 距离 功耗 复杂度
DShot ESC 600kbps < 2m 低 中
单总线 15kbps < 100m 极低 低
红外 NEC 1.2kbps < 10m 低 低
SPI EEPROM 80Mbps < 0.5m 中 中
SDIO 200Mbps < 0.1m 高 高
LED 控制
1. led
LED 控制综合示例
多种 LED 控制方法和模式
包括 GPIO 控制、PWM 调光、呼吸灯效果
LED 状态指示和动画效果
📗 SPI 从机模式
2. spi_slave
SPI 从机模式总目录
- ESP32 作为 SPI 从设备的配置和使用
3. receiver
SPI 从机接收模式
SPI 从机数据接收功能
缓冲区管理和数据解析
高速数据流接收
4. sender
SPI 从机发送模式
SPI 从机数据发送功能
数据打包和传输优化
响应主机请求
5. append_mode
追加模式
SPI 数据传输中的追加操作
连续数据流处理
大数据块传输
📙 SPI 主从通信
6. master
SPI 主机模式
SPI 主机控制器配置
多从设备管理
数据传输协议
7. slave
SPI 从机模式
SPI 从设备完整实现
数据响应和处理
错误检测和恢复
8. segment_mode
分段传输模式
大数据的分段传输
流控制和错误处理
可靠数据传输
📘 段式 SPI 主从
9. seg_master
段式 SPI 主机
分段传输的主机端实现
传输控制和调度
性能优化
10. seg_slave
段式 SPI 从机
分段传输的从机端实现
数据重组和处理
缓冲区管理
📗 温度传感器
11. temperature_sensor
温度传感器总目录
- 多种温度传感器的接口和驱动
12. temp_sensor
内置温度传感器
ESP32 内置温度传感器使用
芯片温度监测
过热保护和节流控制
13. temp_sensor_monitor
温度传感器监控
温度数据采集和监控
阈值报警功能
温度历史记录
📙 定时器组
14. timer_group
定时器组总目录
- ESP32 硬件定时器配置和使用
15. gptimer
通用定时器
通用目的定时器 (GPTimer)
高精度定时功能
中断和回调处理
16. gptimer_capture_hc_sr04
GPTimer 捕获模式 - HC-SR04
使用 GPTimer 捕获模式驱动 HC-SR04
高精度超声波测距
距离计算和滤波
17. wiegand_interface
维根接口
维根协议 (Wiegand) 实现
门禁系统读卡器接口
数据解码和校验
📘 触摸传感器
18. touch_sensor
触摸传感器总目录
- ESP32 电容触摸传感器功能
19. touch_element
触摸元素库
高级触摸传感器抽象层
统一的事件处理接口
手势识别基础
20. touch_button
触摸按钮
单个触摸按钮实现
点击、长按、双击识别
消抖和灵敏度调整
21. touch_elements_combination
触摸元素组合
多个触摸元素的组合使用
复合手势识别
区域划分和优先级
22. touch_element_waterproof
防水触摸
防水设计触摸传感器
抗干扰算法
潮湿环境应用
23. touch_matrix
触摸矩阵
矩阵式触摸传感器
多按键检测
键盘和面板应用
24. touch_slider
触摸滑块
线性触摸滑块
位置检测和精度
连续值输入
25. touch_sensor_v1
触摸传感器 V1 接口
旧版触摸传感器接口
向后兼容支持
迁移指导
🎯 应用场景深度解析
智能家居控制面板
yaml
硬件配置:
- 用户输入: touch_matrix (4x4 触摸键盘)
- 状态显示: led (多色指示灯)
- 温度监测: temp_sensor (环境温度)
- 通信接口: spi_slave (与主控通信)
软件架构:
用户交互:
├── 触摸输入 (矩阵按键识别)
├── 手势识别 (滑动、长按)
├── 防水处理 (防误触算法)
└── 反馈提示 (LED 状态)
环境感知:
├── 温度监测 (内置传感器)
├── 阈值报警 (温度过高)
├── 数据记录 (历史数据)
└── 节能控制 (自动调节)
通信系统:
├── SPI 从机 (接收主控指令)
├── 数据同步 (定时更新)
├── 错误处理 (通信重试)
└── 协议解析 (命令解码)
工业测量仪器
yaml
硬件配置:
- 距离测量: gptimer_capture_hc_sr04 (超声波)
- 定时控制: timer_group (精密定时)
- 通信接口: spi_master (传感器扩展)
- 温度补偿: temp_sensor_monitor (环境校准)
软件架构:
测量系统:
├── 超声波测距 (HC-SR04 驱动)
├── 温度补偿 (环境校正)
├── 数据滤波 (噪声抑制)
└── 精度优化 (算法优化)
定时控制:
├── 高精度定时 (GPTimer)
├── 中断调度 (实时响应)
├── 时间同步 (多传感器)
└── 性能监控 (系统状态)
数据通信:
├── SPI 主从 (传感器网络)
├── 分段传输 (大数据块)
├── 错误检测 (CRC 校验)
└── 流控制 (流量管理)
门禁安全系统
yaml
硬件配置:
- 读卡接口: wiegand_interface (门禁读卡器)
- 触摸控制: touch_button (物理按键替代)
- 状态指示: led (门锁状态)
- 温度保护: temp_sensor (过热保护)
软件架构:
身份验证:
├── 维根协议解码 (26/34 位)
├── 卡号验证 (数据库查询)
├── 访问控制 (权限管理)
└── 事件记录 (审计日志)
用户接口:
├── 触摸按钮 (门铃/开锁)
├── 防水设计 (户外使用)
├── 反馈提示 (LED/声音)
└── 紧急控制 (手动开锁)
安全保护:
├── 温度监控 (防火保护)
├── 防拆检测 (物理安全)
├── 电源管理 (备用电池)
└── 故障报警 (系统状态)
🔧 技术实现指南
SPI 主从通信配置
c
// SPI 主机配置
spi_bus_config_t bus_cfg = {
.mosi_io_num = MOSI_GPIO,
.miso_io_num = MISO_GPIO,
.sclk_io_num = SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4096,
};
spi_device_interface_config_t dev_cfg = {
.clock_speed_hz = 10 * 1000 * 1000, // 10MHz
.mode = 0, // CPOL=0, CPHA=0
.spics_io_num = CS_GPIO,
.queue_size = 7,
.flags = SPI_DEVICE_HALFDUPLEX,
};
// 初始化 SPI 主机
spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO);
spi_bus_add_device(SPI2_HOST, &dev_cfg, &spi);
// SPI 从机配置
spi_slave_interface_config_t slave_cfg = {
.mode = 0,
.spics_io_num = CS_GPIO,
.queue_size = 3,
.flags = 0,
.post_setup_cb = NULL,
.post_trans_cb = NULL,
};
// 初始化 SPI 从机
spi_slave_initialize(SPI2_HOST, &bus_cfg, &slave_cfg, SPI_DMA_CH_AUTO);
HC-SR04 超声波测距 (GPTimer 捕获)
c
// GPTimer 捕获配置
gptimer_handle_t gptimer = NULL;
gptimer_event_callbacks_t cbs = {
.on_alarm = NULL,
.on_capture = on_capture_callback,
};
// 创建 GPTimer
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = 1 * 1000 * 1000, // 1MHz, 1us 分辨率
};
gptimer_new_timer(&timer_config, &gptimer);
// 配置捕获通道
gptimer_chan_config_t chan_config = {
.flags.intr_priority = 0,
.flags.io_loop_back = false,
.flags.pull_down = true,
.flags.pull_up = false,
};
gptimer_new_channel(gptimer, &chan_config, &capture_chan);
// 设置捕获边沿
gptimer_capture_config_t cap_config = {
.cap_edge = GPTIMER_CAP_EDGE_POS, // 上升沿捕获
.cap_value = 0,
.flags.prescale = 0,
};
gptimer_channel_set_capture_action(capture_chan, &cap_config);
// 计算距离
float calculate_distance(uint64_t pulse_width_us) {
// 声速: 340m/s = 0.034cm/us
// 往返距离,所以除以2
float distance_cm = pulse_width_us * 0.034 / 2.0;
// 温度补偿 (声速随温度变化)
float temperature = read_temperature();
float speed_of_sound = 331.4 + 0.6 * temperature; // m/s
distance_cm = pulse_width_us * (speed_of_sound / 10000.0) / 2.0;
return distance_cm;
}
触摸矩阵键盘实现
c
// 4x4 触摸矩阵配置
#define TOUCH_ROWS 4
#define TOUCH_COLS 4
// 触摸 GPIO 配置
const touch_pad_t row_pins[TOUCH_ROWS] = {
TOUCH_PAD_NUM2, // 行1
TOUCH_PAD_NUM3, // 行2
TOUCH_PAD_NUM4, // 行3
TOUCH_PAD_NUM5, // 行4
};
const touch_pad_t col_pins[TOUCH_COLS] = {
TOUCH_PAD_NUM6, // 列1
TOUCH_PAD_NUM7, // 列2
TOUCH_PAD_NUM8, // 列3
TOUCH_PAD_NUM9, // 列4
};
// 触摸矩阵初始化
void touch_matrix_init(void) {
// 初始化触摸传感器
touch_pad_init();
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
// 配置所有触摸通道
for (int i = 0; i < TOUCH_ROWS; i++) {
touch_pad_config(row_pins[i], 0);
}
for (int i = 0; i < TOUCH_COLS; i++) {
touch_pad_config(col_pins[i], 0);
}
// 设置滤波
touch_pad_filter_start(10); // 10ms 滤波周期
// 安装中断
touch_pad_isr_register(touch_matrix_isr, NULL, 0, NULL);
touch_pad_intr_enable();
}
// 矩阵扫描
void touch_matrix_scan(void) {
uint16_t touch_value;
bool key_state[TOUCH_ROWS][TOUCH_COLS] = {0};
for (int row = 0; row < TOUCH_ROWS; row++) {
// 激活当前行
touch_pad_read_filtered(row_pins[row], &touch_value);
for (int col = 0; col < TOUCH_COLS; col++) {
// 读取列值
uint16_t col_value;
touch_pad_read_filtered(col_pins[col], &col_value);
// 判断按键状态 (行列交叉点)
if (touch_value < TOUCH_THRESHOLD && col_value < TOUCH_THRESHOLD) {
key_state[row][col] = true;
}
}
}
// 处理按键事件
process_key_events(key_state);
}
Wiegand 接口实现
c
// 维根接口配置
#define WIEGAND_DATA0_GPIO GPIO_NUM_4
#define WIEGAND_DATA1_GPIO GPIO_NUM_5
// 维根数据结构
typedef struct {
uint32_t data; // 26位或34位数据
uint8_t bits; // 数据位数
uint8_t parity_ok; // 奇偶校验结果
uint64_t timestamp; // 接收时间戳
} wiegand_packet_t;
// 维根解码状态机
typedef enum {
WIEGAND_IDLE,
WIEGAND_RECEIVING,
WIEGAND_COMPLETE,
WIEGAND_ERROR
} wiegand_state_t;
// GPIO 中断处理
static void IRAM_ATTR wiegand_isr_handler(void* arg) {
uint32_t gpio_num = (uint32_t)arg;
static uint32_t bit_buffer = 0;
static uint8_t bit_count = 0;
static uint64_t last_edge_time = 0;
uint64_t current_time = esp_timer_get_time();
uint64_t pulse_width = current_time - last_edge_time;
last_edge_time = current_time;
if (gpio_num == WIEGAND_DATA0_GPIO) {
// 收到数据0
bit_buffer <<= 1;
bit_buffer |= 0;
bit_count++;
} else if (gpio_num == WIEGAND_DATA1_GPIO) {
// 收到数据1
bit_buffer <<= 1;
bit_buffer |= 1;
bit_count++;
}
// 检查数据包完整性
if (pulse_width > 1000000) { // 1ms 超时
if (bit_count == 26 || bit_count == 34) {
// 验证奇偶校验
if (verify_wiegand_parity(bit_buffer, bit_count)) {
process_wiegand_packet(bit_buffer, bit_count);
}
}
bit_buffer = 0;
bit_count = 0;
}
}
// 奇偶校验验证
bool verify_wiegand_parity(uint32_t data, uint8_t bits) {
if (bits == 26) {
// 26位维根: 1位偶校验 + 8位设备号 + 16位卡号 + 1位奇校验
uint8_t even_parity = (data >> 25) & 0x01;
uint8_t odd_parity = data & 0x01;
uint32_t payload = (data >> 1) & 0x00FFFFFF;
uint8_t calculated_even = calculate_parity(payload >> 16, 8, PARITY_EVEN);
uint8_t calculated_odd = calculate_parity(payload & 0xFFFF, 16, PARITY_ODD);
return (even_parity == calculated_even) && (odd_parity == calculated_odd);
}
// 类似处理 34位
return false;
}
内置温度传感器使用
c
// 内置温度传感器配置
#define TSENS_READ_TIMES 10 // 采样次数
#define TSENS_READ_DELAY 100 // 采样间隔 (ms)
// 温度传感器初始化
void temp_sensor_init(void) {
temp_sensor_config_t temp_sensor = {
.dac_offset = TSENS_DAC_L0, // 偏移量
.clk_div = 6, // 时钟分频
};
temp_sensor_set_config(temp_sensor);
temp_sensor_start();
}
// 读取温度值
float read_temperature_celsius(void) {
float temperature = 0;
uint32_t raw_value = 0;
// 多次采样取平均
for (int i = 0; i < TSENS_READ_TIMES; i++) {
temp_sensor_read_raw(&raw_value);
// 将原始值转换为温度 (摄氏度)
// 转换公式: T = (raw_value - offset) / slope
float temp = (raw_value - TSENS_CAL_OFFSET) / TSENS_CAL_SLOPE;
temperature += temp;
vTaskDelay(pdMS_TO_TICKS(TSENS_READ_DELAY));
}
temperature /= TSENS_READ_TIMES;
return temperature;
}
// 温度监控任务
void temp_monitor_task(void *pvParameter) {
temp_sensor_init();
while (1) {
float temp = read_temperature_celsius();
if (temp > TEMP_WARNING_THRESHOLD) {
// 温度警告
log_warning("High temperature: %.1f°C", temp);
if (temp > TEMP_CRITICAL_THRESHOLD) {
// 温度过高,触发保护措施
trigger_thermal_protection();
}
}
// 记录温度数据
record_temperature(temp);
vTaskDelay(pdMS_TO_TICKS(5000)); // 5秒采样一次
}
}
🚀 开发最佳实践
触摸传感器校准和优化
c
// 触摸传感器校准流程
void touch_sensor_calibration(void) {
// 1. 获取基准值 (无触摸)
uint16_t baseline[TOUCH_CHANNELS];
for (int i = 0; i < TOUCH_CHANNELS; i++) {
touch_pad_read_filtered(touch_channels[i], &baseline[i]);
}
// 2. 等待用户触摸获取阈值
log_info("Please touch each sensor...");
uint16_t touch_values[TOUCH_CHANNELS];
for (int i = 0; i < TOUCH_CHANNELS; i++) {
wait_for_touch(touch_channels[i]);
touch_pad_read_filtered(touch_channels[i], &touch_values[i]);
// 计算阈值 (基准值 - 30%)
thresholds[i] = baseline[i] - (baseline[i] * 0.3);
log_info("Channel %d: baseline=%d, touch=%d, threshold=%d",
i, baseline[i], touch_values[i], thresholds[i]);
}
// 3. 保存校准数据到 NVS
save_calibration_data(baseline, thresholds, TOUCH_CHANNELS);
}
// 防水触摸算法
uint16_t waterproof_touch_filter(uint16_t raw_value, uint16_t baseline) {
// 动态基线调整
static float filtered_baseline = 0;
// 一阶低通滤波器更新基线
filtered_baseline = filtered_baseline * 0.99 + raw_value * 0.01;
// 计算相对变化
float relative_change = (filtered_baseline - raw_value) / filtered_baseline;
// 判断触摸条件
if (relative_change > 0.25) { // 变化超过 25%
return 1; // 确认触摸
} else if (relative_change > 0.15) { // 变化 15-25%
return 0; // 可能触摸,需要进一步判断
} else {
return 0; // 无触摸
}
}
SPI 高效数据传输
c
// DMA 优化的 SPI 传输
void spi_dma_transfer(const uint8_t *tx_data, uint8_t *rx_data, size_t len) {
spi_transaction_t trans = {
.length = len * 8, // 位数
.tx_buffer = tx_data,
.rx_buffer = rx_data,
.flags = SPI_TRANS_USE_RXDATA | SPI_TRANS_USE_TXDATA,
};
// 使用 DMA 传输
spi_device_transmit(spi_handle, &trans);
// 等待传输完成
spi_device_get_trans_result(spi_handle, &trans, portMAX_DELAY);
}
// 分段传输大数据
void spi_segmented_transfer(const uint8_t *data, size_t total_len) {
const size_t SEGMENT_SIZE = 1024; // 每段 1KB
for (size_t offset = 0; offset < total_len; offset += SEGMENT_SIZE) {
size_t segment_len = (total_len - offset) > SEGMENT_SIZE ?
SEGMENT_SIZE : (total_len - offset);
// 发送分段头
send_segment_header(offset, segment_len);
// 传输数据段
spi_dma_transfer(data + offset, NULL, segment_len);
// 等待确认
if (!wait_for_ack()) {
// 重传机制
offset -= SEGMENT_SIZE; // 回退重试
}
}
}
温度补偿算法
c
// 温度补偿的超声波测距
float temperature_compensated_distance(uint64_t pulse_width_us) {
// 读取当前温度
float temp_celsius = read_temperature_celsius();
// 计算温度补偿的声速
// 标准公式: v = 331.4 + 0.6 * T (m/s)
float speed_of_sound = 331.4 + 0.6 * temp_celsius;
// 考虑湿度影响 (可选)
float humidity = read_humidity();
if (humidity > 0) {
// 湿度对声速有轻微影响
speed_of_sound += humidity * 0.012;
}
// 计算距离 (往返距离,除以2)
float distance_m = (pulse_width_us / 1e6) * speed_of_sound / 2.0;
return distance_m * 100.0; // 转换为厘米
}
// 自适应温度采样
void adaptive_temperature_sampling(void) {
static float last_temp = 25.0; // 初始温度
static uint32_t sample_interval = 5000; // 初始采样间隔 5秒
float current_temp = read_temperature_celsius();
float temp_change = fabs(current_temp - last_temp);
// 根据温度变化率调整采样频率
if (temp_change > 5.0) {
sample_interval = 1000; // 变化大,1秒采样
} else if (temp_change > 2.0) {
sample_interval = 2000; // 变化中等,2秒采样
} else if (temp_change > 0.5) {
sample_interval = 5000; // 变化小,5秒采样
} else {
sample_interval = 10000; // 基本稳定,10秒采样
}
last_temp = current_temp;
vTaskDelay(pdMS_TO_TICKS(sample_interval));
}
📊 性能特性参考
| 外设/传感器 | 精度/分辨率 | 响应时间 | 功耗 | 适用场景 |
|---|---|---|---|---|
| 内置温度传感器 | ±1°C | 100ms | 极低 | 芯片温度监控 |
| 触摸传感器 | 0.1pF | 10ms | 低 | 用户交互 |
| GPTimer | 1ns | < 100ns | 中 | 精密定时 |
| HC-SR04 | 0.3cm | 60ms | 中 | 距离测量 |
| Wiegand 接口 | 1-bit | 实时 | 低 | 门禁系统 |
| SPI 从机 | 8-32bit | < 1μs | 中 | 协处理器 |
触摸传感器性能对比
text
触摸类型 灵敏度 响应时间 防水能力 功耗
单点触摸 高 10ms 中等 低
触摸矩阵 中等 20ms 较低 中
触摸滑块 高 15ms 低 中
防水触摸 较低 30ms 高 中高
触摸传感器 V2/V3
1. touch_sensor_v2
触摸传感器 V2 版本
改进的触摸传感器 API
增强的噪声抑制算法
更好的防水性能
2. touch_pad_interrupt
触摸中断模式
触摸中断触发配置
低功耗唤醒功能
中断服务程序处理
3. touch_pad_read
触摸读取模式
轮询式触摸读取
原始值读取和滤波
灵敏度调整
4. touch_sensor_v3
触摸传感器 V3 版本
最新触摸传感器 API
多通道并发扫描
高级滤波和校准
📗 TWAI/CAN 总线
5. twai
TWAI 总线总目录
ESP32 TWAI (Two-Wire Automotive Interface) 控制器
兼容 CAN 2.0A/B 协议
6. twai_network
TWAI 网络总目录
- TWAI 网络通信示例
7. twai_network_listen_only
TWAI 网络监听模式
只接收不发送的监听模式
数据监控和分析
网络诊断工具
8. twai_network_master
TWAI 网络主节点
TWAI 网络主控制器
发送命令和调度
网络管理
9. twai_network_slave
TWAI 网络从节点
TWAI 网络从设备
响应主节点命令
数据上报
10. twai_alert_and_recovery
TWAI 警报和恢复
错误检测和警报
自动恢复机制
故障处理策略
11. twai_self_test
TWAI 自测试
硬件自检功能
回环测试模式
性能验证
📙 UART 串口通信
12. uart
UART 串口总目录
- ESP32 UART 控制器使用
13. nmea0183_parser
NMEA 0183 协议解析器
GPS NMEA 0183 协议解析
位置、速度、时间数据提取
导航设备接口
14. uart_async_rxtstasks
UART 异步接收任务
异步 UART 数据接收
任务间通信
缓冲区管理
15. uart_echo
UART 回显
串口回显功能
基础通信测试
数据透传
16. uart_echo_rs485
UART RS485 回显
RS485 半双工通信
方向控制自动切换
工业总线通信
17. uart_events
UART 事件处理
UART 事件驱动编程
数据到达、超时等事件
非阻塞通信
18. uart_repl
UART REPL 交互
串口交互式解释器
命令行接口
调试和配置工具
19. uart_select
UART Select 多路复用
多串口选择器
类似 UNIX select 的多路复用
多串口并发管理
📘 USB 设备功能
20. device
USB 设备总目录
- ESP32-S2/S3 USB 设备功能
21. tusb_composite_msc_serialdevice
复合 MSC 和串口设备
USB 复合设备 (MSC + 串口)
大容量存储和虚拟串口
多功能 USB 设备
22. tusb_console
USB 控制台
USB CDC 虚拟串口控制台
系统调试和日志输出
交互式终端
23. tusb_hid
USB HID 设备
USB 人机接口设备
键盘、鼠标、游戏手柄
输入设备模拟
24. tusb_midi
USB MIDI 设备
USB MIDI 接口
音乐设备数字接口
音频设备控制
25. tusb_msc
USB 大容量存储设备
USB Mass Storage Class
U 盘功能模拟
文件系统访问
26. tusb_ncm
USB NCM 网络设备
USB Network Control Model
USB 以太网适配器
网络共享功能
27. tusb_serial_device
USB 串口设备
USB CDC 串口设备
虚拟 COM 端口
高速串口通信
🎯 应用场景深度解析
汽车电子控制系统
yaml
硬件配置:
- 总线通信: twai_network_master (CAN 主控)
- 故障诊断: twai_alert_and_recovery (错误处理)
- 调试接口: uart_console (诊断端口)
- 用户输入: touch_sensor_v3 (触摸控制)
软件架构:
车载网络:
├── CAN 总线通信 (TWAI 协议)
├── 网络管理 (主从架构)
├── 错误处理 (自动恢复)
└── 自检功能 (系统诊断)
用户交互:
├── 触摸控制 (中控面板)
├── 状态显示 (LCD 界面)
├── 声音反馈 (音频输出)
└── 物理按键 (备份控制)
调试诊断:
├── UART 诊断接口
├── USB 配置端口
├── 故障码记录
└── 实时监控
工业自动化网关
yaml
硬件配置:
- 串口扩展: uart_echo_rs485 (多设备连接)
- 协议解析: nmea0183_parser (传感器数据)
- USB 接口: tusb_composite_msc_serial (配置/存储)
- 网络接口: tusb_ncm (以太网扩展)
软件架构:
数据采集:
├── 多串口管理 (RS485/RS232)
├── 协议解析 (NMEA/Modbus)
├── 数据缓存 (环形缓冲区)
└── 实时处理 (滤波算法)
通信接口:
├── USB 复合设备 (存储+串口)
├── 网络共享 (USB 以太网)
├── 无线通信 (WiFi/蓝牙)
└── 云平台对接 (MQTT/HTTP)
系统管理:
├── 配置存储 (USB MSC)
├── 远程更新 (OTA)
├── 日志记录 (故障追踪)
└── 状态监控 (健康检查)
智能物联网设备
yaml
硬件配置:
- 用户接口: touch_pad_interrupt (低功耗唤醒)
- 数据通信: uart_events (异步通信)
- USB 功能: tusb_hid (用户输入)
- 调试接口: tusb_console (开发调试)
软件架构:
低功耗设计:
├── 触摸唤醒 (中断模式)
├── 深度睡眠 (节能模式)
├── 事件驱动 (按需处理)
└── 动态调频 (性能调节)
数据通信:
├── 异步串口 (非阻塞)
├── 协议栈优化 (效率提升)
├── 错误恢复 (自动重试)
└── 流量控制 (防丢包)
开发支持:
├── USB 控制台 (实时调试)
├── 虚拟串口 (日志输出)
├── HID 设备 (配置工具)
└── 存储设备 (固件更新)
🔧 技术实现指南
TWAI/CAN 总线配置
c
// TWAI 通用配置
twai_general_config_t g_config = {
.mode = TWAI_MODE_NORMAL,
.tx_io = GPIO_NUM_5, // TX 引脚
.rx_io = GPIO_NUM_4, // RX 引脚
.clkout_io = TWAI_IO_UNUSED,
.bus_off_io = TWAI_IO_UNUSED,
.tx_queue_len = 5, // 发送队列长度
.rx_queue_len = 5, // 接收队列长度
.alerts_enabled = TWAI_ALERT_ALL,
.clkout_divider = 0,
};
// 定时器配置 (500kbps)
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
// 滤波器配置 (接收所有 ID)
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
// 初始化 TWAI
twai_driver_install(&g_config, &t_config, &f_config);
twai_start();
// 发送 CAN 帧
twai_message_t message = {
.identifier = 0x123, // CAN ID
.flags = TWAI_MSG_FLAG_EXTD, // 扩展帧
.data_length_code = 8, // 数据长度
.data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
};
twai_transmit(&message, pdMS_TO_TICKS(1000));
NMEA 0183 GPS 解析
c
// NMEA 句子结构
typedef struct {
char sentence[256]; // 原始句子
char type[6]; // 句子类型 (GPGGA, GPRMC, etc.)
bool checksum_valid; // 校验和验证
union {
gga_data_t gga; // GPGGA 数据
rmc_data_t rmc; // GPRMC 数据
gsa_data_t gsa; // GPGSA 数据
} data;
} nmea_sentence_t;
// GPGGA 解析 (GPS 定位数据)
typedef struct {
float utc_time; // UTC 时间
float latitude; // 纬度
char lat_direction; // 纬度方向 (N/S)
float longitude; // 经度
char lon_direction; // 经度方向 (E/W)
uint8_t fix_quality; // 定位质量 (0-1)
uint8_t satellites; // 使用的卫星数
float hdop; // 水平精度因子
float altitude; // 海拔高度
char altitude_unit; // 高度单位 (M)
float geoid_separation; // 大地水准面分离
char geoid_unit; // 分离单位 (M)
float dgps_age; // DGPS 数据年龄
uint16_t dgps_station_id; // DGPS 基站 ID
} gga_data_t;
// NMEA 解析器
bool parse_nmea_sentence(const char *sentence, nmea_sentence_t *result) {
// 检查起始符 '$'
if (sentence[0] != '$') return false;
// 查找结束符 '*'
char *checksum_pos = strchr(sentence, '*');
if (!checksum_pos) return false;
// 验证校验和
uint8_t calculated_checksum = 0;
for (const char *p = sentence + 1; p < checksum_pos; p++) {
calculated_checksum ^= *p;
}
uint8_t received_checksum = strtol(checksum_pos + 1, NULL, 16);
result->checksum_valid = (calculated_checksum == received_checksum);
if (!result->checksum_valid) return false;
// 提取句子类型
strncpy(result->type, sentence + 1, 5);
result->type[5] = '\0';
// 根据类型解析数据
if (strcmp(result->type, "GPGGA") == 0) {
return parse_gga_sentence(sentence, &result->data.gga);
} else if (strcmp(result->type, "GPRMC") == 0) {
return parse_rmc_sentence(sentence, &result->data.rmc);
}
return false;
}
USB 复合设备配置
c
// TinyUSB 配置
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE)
// USB 描述符配置
tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0xCafe,
.idProduct = 0x4000,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
// 复合设备配置 (MSC + CDC)
enum {
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
ITF_NUM_MSC,
ITF_NUM_TOTAL
};
// TinyUSB 初始化
void tusb_init_composite_device(void) {
// 初始化 TinyUSB 堆栈
tusb_init();
// 注册 CDC 回调
tud_cdc_set_rx_callback(cdc_rx_callback);
tud_cdc_set_tx_callback(cdc_tx_callback);
// 注册 MSC 回调
tud_msc_set_sense(msc_sense_cb);
tud_msc_set_read10_cb(msc_read10_cb);
tud_msc_set_write10_cb(msc_write10_cb);
}
// USB 任务处理
void usb_device_task(void) {
// 处理 USB 事件
tud_task();
// CDC 数据处理
if (tud_cdc_connected()) {
handle_cdc_data();
}
// MSC 数据处理
if (tud_msc_mounted()) {
handle_msc_requests();
}
}
UART 事件驱动编程
c
// UART 事件配置
#define UART_BUF_SIZE (1024)
#define UART_EVENT_QUEUE_SIZE (20)
// UART 事件处理任务
void uart_event_task(void *pvParameters) {
uart_event_t event;
uint8_t data[UART_BUF_SIZE];
while (1) {
// 等待 UART 事件
if (xQueueReceive(uart_event_queue, &event, portMAX_DELAY)) {
switch (event.type) {
case UART_DATA:
// 数据到达事件
uart_read_bytes(UART_NUM_1, data, event.size, portMAX_DELAY);
process_uart_data(data, event.size);
break;
case UART_FIFO_OVF:
// FIFO 溢出事件
uart_flush_input(UART_NUM_1);
xQueueReset(uart_event_queue);
break;
case UART_BUFFER_FULL:
// 缓冲区满事件
uart_read_bytes(UART_NUM_1, data, UART_BUF_SIZE, portMAX_DELAY);
process_uart_data(data, UART_BUF_SIZE);
break;
case UART_BREAK:
// Break 信号事件
log_warning("UART break detected");
break;
case UART_PARITY_ERR:
// 奇偶校验错误
log_error("UART parity error");
break;
case UART_FRAME_ERR:
// 帧错误
log_error("UART frame error");
break;
default:
log_info("UART event type: %d", event.type);
break;
}
}
}
}
// UART 初始化带事件
void uart_init_with_events(void) {
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
uart_param_config(UART_NUM_1, &uart_config);
uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
// 安装驱动并创建事件队列
uart_driver_install(UART_NUM_1, UART_BUF_SIZE * 2, UART_BUF_SIZE * 2,
UART_EVENT_QUEUE_SIZE, &uart_event_queue, 0);
// 启用事件类型
uart_enable_pattern_det_baud_intr(UART_NUM_1, '+', 3, 9, 0, 0);
uart_pattern_queue_reset(UART_NUM_1, UART_EVENT_QUEUE_SIZE);
}
RS485 半双工通信
c
// RS485 配置
#define RS485_TX_EN_GPIO GPIO_NUM_23 // 发送使能引脚
// RS485 发送函数
void rs485_send_data(const uint8_t *data, size_t len) {
// 使能发送 (DE 引脚拉高)
gpio_set_level(RS485_TX_EN_GPIO, 1);
// 短暂延时确保驱动器稳定
esp_rom_delay_us(10);
// 发送数据
uart_write_bytes(UART_NUM_1, data, len);
// 等待发送完成
uart_wait_tx_done(UART_NUM_1, pdMS_TO_TICKS(100));
// 禁用发送,切换为接收模式
gpio_set_level(RS485_TX_EN_GPIO, 0);
// 短暂延时确保模式切换
esp_rom_delay_us(10);
}
// RS485 接收函数
size_t rs485_receive_data(uint8_t *buffer, size_t buf_size, uint32_t timeout_ms) {
// 确保在接收模式
gpio_set_level(RS485_TX_EN_GPIO, 0);
// 读取数据
return uart_read_bytes(UART_NUM_1, buffer, buf_size, pdMS_TO_TICKS(timeout_ms));
}
// RS485 Modbus 协议实现
bool rs485_modbus_query(uint8_t slave_addr, uint8_t function_code,
uint16_t start_addr, uint16_t quantity,
uint8_t *response, size_t *response_len) {
// 构建 Modbus RTU 请求帧
uint8_t request[8];
request[0] = slave_addr; // 从机地址
request[1] = function_code; // 功能码
request[2] = (start_addr >> 8) & 0xFF; // 起始地址高字节
request[3] = start_addr & 0xFF; // 起始地址低字节
request[4] = (quantity >> 8) & 0xFF; // 数量高字节
request[5] = quantity & 0xFF; // 数量低字节
// 计算 CRC
uint16_t crc = modbus_crc16(request, 6);
request[6] = crc & 0xFF; // CRC 低字节
request[7] = (crc >> 8) & 0xFF; // CRC 高字节
// 发送请求
rs485_send_data(request, sizeof(request));
// 等待响应
uint8_t rx_buffer[256];
size_t rx_len = rs485_receive_data(rx_buffer, sizeof(rx_buffer), 1000);
if (rx_len > 0 && modbus_validate_response(rx_buffer, rx_len, slave_addr, function_code)) {
memcpy(response, rx_buffer, rx_len);
*response_len = rx_len;
return true;
}
return false;
}
🚀 开发最佳实践
TWAI 网络可靠性设计
c
// TWAI 错误恢复策略
typedef struct {
twai_state_t last_state;
uint32_t error_count;
uint32_t recovery_attempts;
uint64_t last_error_time;
} twai_health_t;
void twai_health_monitor(twai_health_t *health) {
twai_status_info_t status;
twai_get_status_info(&status);
// 状态变化检测
if (status.state != health->last_state) {
health->last_state = status.state;
switch (status.state) {
case TWAI_STATE_BUS_OFF:
log_error("TWAI bus-off detected, attempting recovery...");
twai_initiate_recovery();
health->recovery_attempts++;
break;
case TWAI_STATE_RECOVERING:
log_info("TWAI bus recovering...");
break;
case TWAI_STATE_STOPPED:
log_warning("TWAI driver stopped, restarting...");
twai_stop();
vTaskDelay(pdMS_TO_TICKS(100));
twai_start();
break;
case TWAI_STATE_RUNNING:
if (health->recovery_attempts > 0) {
log_info("TWAI recovered successfully after %d attempts",
health->recovery_attempts);
health->recovery_attempts = 0;
}
break;
}
}
// 错误计数监控
if (status.arb_lost_count > 0 || status.error_count > 0) {
health->error_count += status.arb_lost_count + status.error_count;
health->last_error_time = esp_timer_get_time();
if (health->error_count > ERROR_THRESHOLD) {
log_warning("High TWAI error rate: %lu errors", health->error_count);
// 动态调整总线速率
if (health->error_count > CRITICAL_ERROR_THRESHOLD) {
adjust_twai_baudrate(250000); // 降速到 250kbps
}
}
}
// 定期重置错误计数
static uint64_t last_reset_time = 0;
uint64_t current_time = esp_timer_get_time();
if (current_time - last_reset_time > ERROR_RESET_INTERVAL) {
health->error_count = 0;
last_reset_time = current_time;
}
}
USB 复合设备电源管理
c
// USB 电源管理状态机
typedef enum {
USB_STATE_DISCONNECTED,
USB_STATE_SUSPENDED,
USB_STATE_ACTIVE,
USB_STATE_CONFIGURED,
} usb_state_t;
void usb_power_management(void) {
static usb_state_t current_state = USB_STATE_DISCONNECTED;
usb_state_t new_state;
if (!tud_mounted()) {
new_state = USB_STATE_DISCONNECTED;
} else if (tud_suspended()) {
new_state = USB_STATE_SUSPENDED;
} else {
new_state = tud_configured() ? USB_STATE_CONFIGURED : USB_STATE_ACTIVE;
}
// 状态变化处理
if (new_state != current_state) {
switch (new_state) {
case USB_STATE_DISCONNECTED:
log_info("USB disconnected, entering low power mode");
enter_low_power_mode();
break;
case USB_STATE_SUSPENDED:
log_info("USB suspended");
suspend_usb_peripherals();
break;
case USB_STATE_ACTIVE:
log_info("USB active but not configured");
resume_usb_peripherals();
break;
case USB_STATE_CONFIGURED:
log_info("USB fully configured");
enable_usb_functionality();
break;
}
current_state = new_state;
}
// 根据状态调整功耗
switch (current_state) {
case USB_STATE_SUSPENDED:
// 最小功耗模式
set_cpu_frequency(CPU_FREQ_10MHZ);
disable_usb_phy();
break;
case USB_STATE_ACTIVE:
// 中等功耗
set_cpu_frequency(CPU_FREQ_80MHZ);
enable_usb_phy();
break;
case USB_STATE_CONFIGURED:
// 高性能模式
set_cpu_frequency(CPU_FREQ_240MHZ);
enable_usb_phy();
break;
}
}
📊 性能特性参考
| 接口/协议 | 最大速率 | 距离 | 节点数 | 实时性 |
|---|---|---|---|---|
| TWAI/CAN | 1 Mbps | 40m @ 1Mbps | 110 | 高 |
| UART | 5 Mbps | 15m | 点对点 | 中等 |
| RS485 | 10 Mbps | 1200m | 32/256 | 高 |
| USB 2.0 | 480 Mbps | 5m | 127 | 高 |
| NMEA 0183 | 4800 bps | 串口限制 | 1 | 低 |
USB 设备类对比
text
设备类 速度 功耗 复杂度 应用场景
CDC 串口 全速 低 低 虚拟串口
HID 低速 极低 中 键盘/鼠标
MSC 全速 中 高 U盘功能
MIDI 全速 中 高 音频设备
NCM 高速 高 高 网络适配器
复合设备 全速 中 高 多功能设备
USB 主机功能
1. host
USB 主机模式总目录
ESP32-S2/S3 USB 主机功能
连接和控制 USB 外设
2. cdc
通信设备类 (CDC)
- USB CDC 设备驱动和管理
3. cdc_acm_host
CDC ACM 主机
USB CDC ACM (Abstract Control Model) 主机驱动
连接 USB 串口设备 (如 FTDI, CP2102)
虚拟串口通信
4. cdc_acm_vcp
CDC ACM 虚拟 COM 端口
Virtual COM Port (VCP) 实现
Windows/Linux/macOS 兼容的串口设备
USB 转串口适配器
5. hid
人机接口设备主机
USB HID 主机驱动
连接键盘、鼠标、游戏手柄
HID 报告描述符解析
6. msc
大容量存储主机
USB Mass Storage Class 主机
连接 U 盘、SD 卡读卡器
FAT/exFAT 文件系统支持
7. usb_host_lib
USB 主机库
USB 主机核心库
设备枚举和管理
传输调度和错误处理
8. uvc
USB 视频类
USB Video Class 主机
连接 USB 摄像头
视频流捕获和处理
📗 USB Serial/JTAG
9. usb_serial_jtag
USB 串口/JTAG 总目录
- ESP32-S3 内置 USB 串口/JTAG
10. usb_serial_jtag_echo
USB 串口/JTAG 回显
通过 USB 串口实现回显功能
调试和测试 USB 接口
无需外部 UART 转 USB 芯片
📙 模拟比较器
11. analog_comparator
模拟比较器
ESP32 模拟比较器功能
模拟信号比较和触发
阈值检测和窗口比较
📘 PHY 和射频
12. phy
物理层总目录
- 射频和天线相关配置
13. antenna
天线配置
天线选择和切换
天线阻抗匹配
射频性能优化
14. cert_test
认证测试
射频认证测试工具
合规性测试支持
法规要求验证
📗 网络协议
15. protocols
网络协议总目录
- 高级网络协议实现
16. https_server
HTTPS 服务器
安全 HTTP 服务器
TLS/SSL 加密支持
安全 Web 服务
17. simple
简单协议示例
基础网络协议实现
最小化配置示例
18. wss_server
WebSocket 安全服务器
WebSocket over TLS (WSS)
实时双向安全通信
WebSocket 协议实现
📙 HTTP 服务器
19. http_server
HTTP 服务器总目录
- ESP32 HTTP 服务器功能
20. advanced_tests
高级测试
HTTP 服务器高级功能测试
性能和压力测试
边界条件验证
21. async_handlers
异步处理器
异步 HTTP 请求处理
非阻塞请求响应
长连接管理
22. captive_portal
强制门户
WiFi 认证门户
重定向和认证页面
网络接入控制
23. file_serving
文件服务
静态文件服务器
目录浏览和文件下载
嵌入式 Web 界面
24. persistent_sockets
持久连接
HTTP 持久连接 (Keep-Alive)
连接复用优化
减少连接开销
25. restful_server
RESTful 服务器
REST API 实现
CRUD 操作接口
JSON 数据交换
🎯 应用场景深度解析
工业数据采集网关
yaml
硬件配置:
- USB 接口: cdc_acm_host (连接传感器)
- 网络: https_server (安全数据传输)
- 存储: msc (数据备份到 U 盘)
- 调试: usb_serial_jtag (系统调试)
软件架构:
数据采集:
├── USB CDC 设备管理 (多传感器)
├── 数据解析和校验 (协议栈)
├── 实时处理 (滤波算法)
└── 本地缓存 (环形缓冲区)
网络服务:
├── HTTPS 安全传输 (TLS 加密)
├── RESTful API (数据接口)
├── WebSocket 实时推送 (WSS)
└── 强制门户配置 (Captive Portal)
系统管理:
├── USB 大容量存储 (配置/日志)
├── 异步事件处理 (非阻塞)
├── 文件服务 (Web 界面)
└── 远程更新 (OTA)
智能监控系统
yaml
硬件配置:
- 摄像头: uvc (USB 摄像头)
- 用户界面: captive_portal (Web 配置)
- 存储: file_serving (录像存储)
- 传感器: analog_comparator (报警触发)
软件架构:
视频处理:
├── USB 视频流捕获 (UVC 协议)
├── 视频编码 (H.264/JPEG)
├── 运动检测 (图像分析)
└── 视频流分发 (RTSP/HTTP)
报警系统:
├── 模拟比较器触发 (阈值检测)
├── 实时通知 (WebSocket)
├── 事件记录 (日志系统)
└── 联动控制 (外部设备)
用户访问:
├── Web 界面 (视频查看)
├── 移动端适配 (响应式设计)
├── 用户认证 (登录系统)
└── 权限管理 (多用户)
网络测试与认证设备
yaml
硬件配置:
- 射频测试: antenna (天线性能)
- 协议测试: cert_test (合规性)
- USB 扩展: hid (测试设备控制)
- 网络接口: persistent_sockets (压力测试)
软件架构:
射频测试:
├── 天线参数配置 (阻抗匹配)
├── 信号强度测量 (RSSI)
├── 频谱分析 (扫频测试)
└── 合规性验证 (法规测试)
协议测试:
├── HTTP/HTTPS 压力测试
├── WebSocket 连接测试
├── TLS 安全验证
└── 性能基准测试
自动化测试:
├── USB HID 设备控制 (自动化)
├── 测试脚本执行 (Python/Lua)
├── 结果报告生成 (HTML/JSON)
└── 远程监控 (Web 界面)
🔧 技术实现指南
USB CDC ACM 主机配置
c
// CDC ACM 主机配置
typedef struct {
cdc_acm_dev_hdl_t cdc_dev; // CDC 设备句柄
cdc_acm_host_dev_desc_t *desc; // 设备描述符
TaskHandle_t read_task; // 数据读取任务
QueueHandle_t data_queue; // 数据队列
} usb_cdc_host_t;
// CDC ACM 回调函数
static void cdc_acm_callback(cdc_acm_dev_hdl_t cdc_hdl,
cdc_acm_event_t event, void *arg) {
usb_cdc_host_t *cdc_host = (usb_cdc_host_t *)arg;
switch (event) {
case CDC_ACM_HOST_DATA:
// 数据接收事件
uint8_t data[512];
size_t data_len;
esp_err_t ret = cdc_acm_host_read(cdc_hdl, data, sizeof(data), &data_len, 0);
if (ret == ESP_OK && data_len > 0) {
xQueueSend(cdc_host->data_queue, data, portMAX_DELAY);
}
break;
case CDC_ACM_HOST_SERIAL_STATE:
// 串口状态变化 (DTR/RTS)
break;
case CDC_ACM_HOST_NETWORK_CONNECTION:
// 网络连接状态
break;
}
}
// 初始化 CDC ACM 主机
esp_err_t usb_cdc_host_init(usb_cdc_host_t *cdc_host) {
// 初始化 USB 主机
usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
};
ESP_ERROR_CHECK(usb_host_install(&host_config));
// 安装 CDC ACM 驱动
cdc_acm_host_driver_config_t driver_config = {
.connection_timeout_ms = 5000,
.out_buffer_size = 512,
.event_cb = cdc_acm_callback,
.data_cb = NULL,
.user_arg = cdc_host,
};
ESP_ERROR_CHECK(cdc_acm_host_install(&driver_config));
// 创建设备句柄
cdc_acm_new_dev_desc_t new_dev = {
.vid = 0x0403, // FTDI Vendor ID
.pid = 0x6001, // FT232R Product ID
.interface_num = 0,
.flags = 0,
};
return cdc_acm_host_new_dev(&new_dev, &cdc_host->cdc_dev);
}
HTTPS 服务器配置
c
// HTTPS 服务器配置
typedef struct {
httpd_handle_t server; // HTTP 服务器句柄
httpd_ssl_config_t ssl_config; // SSL 配置
httpd_config_t http_config; // HTTP 配置
} https_server_t;
// 启动 HTTPS 服务器
esp_err_t start_https_server(https_server_t *server) {
// HTTP 服务器配置
server->http_config = HTTPD_DEFAULT_CONFIG();
server->http_config.server_port = 443;
server->http_config.ctrl_port = 32768;
server->http_config.max_open_sockets = 7;
server->http_config.max_uri_handlers = 16;
server->http_config.lru_purge_enable = true;
// SSL 配置
server->ssl_config = HTTPD_SSL_CONFIG_DEFAULT();
server->ssl_config.httpd = &server->http_config;
server->ssl_config.servercert = (const uint8_t *)server_cert_pem_start;
server->ssl_config.servercert_len = server_cert_pem_end - server_cert_pem_start;
server->ssl_config.prvtkey_pem = (const uint8_t *)server_key_pem_start;
server->ssl_config.prvtkey_len = server_key_pem_end - server_key_pem_start;
// 启用 TLS 1.2
server->ssl_config.transport_mode = HTTPD_SSL_TRANSPORT_SECURE;
server->ssl_config.httpd.max_uri_handlers = 20;
server->ssl_config.use_ecdsa_peripheral = false;
// 启动 SSL 服务器
ESP_LOGI(TAG, "Starting HTTPS server on port 443");
esp_err_t ret = httpd_ssl_start(&server->server, &server->ssl_config);
if (ret == ESP_OK) {
// 注册 URI 处理器
register_uri_handlers(server->server);
ESP_LOGI(TAG, "HTTPS server started successfully");
}
return ret;
}
// RESTful API 处理器示例
esp_err_t api_get_handler(httpd_req_t *req) {
// 设置响应头
httpd_resp_set_type(req, "application/json");
httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
// 构建 JSON 响应
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "status", "success");
cJSON_AddNumberToObject(root, "timestamp", (double)esp_timer_get_time() / 1000000);
// 根据请求路径处理不同资源
char *uri = req->uri;
if (strstr(uri, "/api/sensors")) {
cJSON *sensors = cJSON_CreateArray();
cJSON_AddItemToArray(sensors, cJSON_CreateNumber(25.5)); // 温度
cJSON_AddItemToArray(sensors, cJSON_CreateNumber(65.2)); // 湿度
cJSON_AddItemToObject(root, "sensors", sensors);
}
// 发送响应
char *json_str = cJSON_Print(root);
httpd_resp_send(req, json_str, strlen(json_str));
// 清理
cJSON_Delete(root);
free(json_str);
return ESP_OK;
}
USB 视频类 (UVC) 配置
c
// UVC 设备描述符
typedef struct {
uint16_t width; // 视频宽度
uint16_t height; // 视频高度
uint8_t fps; // 帧率
uint8_t format; // 视频格式 (MJPEG, YUYV, etc.)
uint8_t interface; // 接口编号
uint8_t endpoint; // 端点地址
} uvc_device_info_t;
// UVC 帧回调
typedef void (*uvc_frame_callback_t)(uint8_t *frame_data, uint32_t frame_len,
uvc_device_info_t *info, void *user_data);
// UVC 主机初始化
esp_err_t uvc_host_init(uvc_frame_callback_t frame_cb, void *user_data) {
// 初始化 USB 主机
usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LEVEL1,
};
ESP_ERROR_CHECK(usb_host_install(&host_config));
// 配置 UVC 主机
uvc_config_t uvc_config = {
.frame_callback = frame_cb,
.user_data = user_data,
.max_payload_size = 1024 * 16, // 16KB 最大负载
.num_buffers = 4, // 4 个缓冲区
.bulk_mode = true, // 批量传输模式
};
return uvc_driver_install(&uvc_config);
}
// 视频帧处理回调
void uvc_frame_handler(uint8_t *frame_data, uint32_t frame_len,
uvc_device_info_t *info, void *user_data) {
ESP_LOGI(TAG, "Received frame: %dx%d, %d bytes, format: %d",
info->width, info->height, frame_len, info->format);
// MJPEG 格式处理
if (info->format == UVC_FRAME_FORMAT_MJPEG) {
// 解码 JPEG 或直接流式传输
save_mjpeg_frame(frame_data, frame_len);
// 或者转换为其他格式
// jpeg_decoder_t *decoder = get_jpeg_decoder();
// decode_jpeg_frame(decoder, frame_data, frame_len);
}
// YUYV 格式处理
else if (info->format == UVC_FRAME_FORMAT_YUYV) {
// YUYV 转 RGB
yuyv_to_rgb(frame_data, rgb_buffer, info->width, info->height);
// 显示或处理 RGB 图像
display_rgb_image(rgb_buffer, info->width, info->height);
}
}
强制门户 (Captive Portal) 实现
c
// DNS 拦截配置 (用于强制门户)
typedef struct {
uint32_t dns_query_count;
uint32_t http_redirect_count;
ip4_addr_t gateway_ip;
ip4_addr_t portal_ip;
} captive_portal_stats_t;
// DNS 拦截回调
static void dns_query_handler(struct dns_hdr *hdr, struct dns_query *q, void *arg) {
captive_portal_stats_t *stats = (captive_portal_stats_t *)arg;
stats->dns_query_count++;
// 拦截所有 DNS 查询,返回门户 IP
struct pbuf *p = (struct pbuf *)arg;
struct dns_hdr *dns_hdr = (struct dns_hdr *)p->payload;
// 设置响应标志
dns_hdr->qr = 1; // 响应标志
dns_hdr->ans_count = htons(1);
// 构建 DNS 响应记录
uint8_t *ptr = (uint8_t *)(dns_hdr + 1);
ptr += strlen((char *)ptr) + 1 + sizeof(struct dns_query);
// A 记录
*ptr++ = 0xC0; // 指针
*ptr++ = 0x0C; // 指向查询名称
*ptr++ = 0x00; // 类型: A 记录
*ptr++ = 0x01;
*ptr++ = 0x00; // 类: IN
*ptr++ = 0x01;
*ptr++ = 0x00; // TTL: 300 秒
*ptr++ = 0x00;
*ptr++ = 0x01;
*ptr++ = 0x2C;
*ptr++ = 0x00; // 数据长度: 4 字节
*ptr++ = 0x04;
// 门户 IP 地址
*ptr++ = ip4_addr1(&stats->portal_ip);
*ptr++ = ip4_addr2(&stats->portal_ip);
*ptr++ = ip4_addr3(&stats->portal_ip);
*ptr++ = ip4_addr4(&stats->portal_ip);
}
// HTTP 重定向处理器
esp_err_t captive_portal_redirect_handler(httpd_req_t *req) {
captive_portal_stats_t *stats = (captive_portal_stats_t *)req->user_ctx;
stats->http_redirect_count++;
// 检查是否已认证
if (is_user_authenticated(req)) {
// 已认证用户,放行请求
return ESP_OK;
}
// 未认证用户,重定向到认证页面
const char *login_url = "http://portal.example.com/login";
httpd_resp_set_status(req, "302 Found");
httpd_resp_set_hdr(req, "Location", login_url);
httpd_resp_send(req, NULL, 0);
return ESP_OK;
}
// 强制门户初始化
void init_captive_portal(void) {
// 启动 DNS 服务器
dns_server_config_t dns_config = {
.port = 53,
.ttl = 300,
.query_handler = dns_query_handler,
};
start_dns_server(&dns_config);
// 启动 HTTP 服务器
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
config.uri_match_fn = httpd_uri_match_wildcard;
httpd_handle_t server = NULL;
httpd_start(&server, &config);
// 注册通配符处理器,捕获所有请求
httpd_uri_t catch_all = {
.uri = "/*",
.method = HTTP_GET,
.handler = captive_portal_redirect_handler,
.user_ctx = NULL,
};
httpd_register_uri_handler(server, &catch_all);
// 注册认证页面
httpd_uri_t login_page = {
.uri = "/login",
.method = HTTP_GET,
.handler = login_page_handler,
.user_ctx = NULL,
};
httpd_register_uri_handler(server, &login_page);
// 注册认证处理
httpd_uri_t auth_handler = {
.uri = "/auth",
.method = HTTP_POST,
.handler = auth_process_handler,
.user_ctx = NULL,
};
httpd_register_uri_handler(server, &auth_handler);
}
WebSocket 安全服务器
c
// WebSocket 会话管理
typedef struct {
int fd; // 套接字文件描述符
bool authenticated; // 认证状态
uint32_t user_id; // 用户 ID
uint64_t last_activity; // 最后活动时间
QueueHandle_t send_queue; // 发送队列
} wss_session_t;
// WSS 处理器
static esp_err_t wss_handler(httpd_req_t *req) {
if (req->method == HTTP_GET) {
// WebSocket 握手
if (httpd_req_get_hdr_value_str(req, "Upgrade", NULL, 0) == ESP_OK) {
return wss_handshake(req);
}
}
return ESP_FAIL;
}
// WebSocket 握手
static esp_err_t wss_handshake(httpd_req_t *req) {
char ws_key[256];
char ws_accept[29];
// 获取 WebSocket Key
if (httpd_req_get_hdr_value_str(req, "Sec-WebSocket-Key", ws_key, sizeof(ws_key)) != ESP_OK) {
return ESP_FAIL;
}
// 计算 Accept 值
strcat(ws_key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
unsigned char sha_hash[20];
mbedtls_sha1((unsigned char *)ws_key, strlen(ws_key), sha_hash);
// Base64 编码
size_t out_len;
mbedtls_base64_encode((unsigned char *)ws_accept, sizeof(ws_accept),
&out_len, sha_hash, 20);
// 发送握手响应
httpd_resp_set_status(req, "101 Switching Protocols");
httpd_resp_set_hdr(req, "Upgrade", "websocket");
httpd_resp_set_hdr(req, "Connection", "Upgrade");
httpd_resp_set_hdr(req, "Sec-WebSocket-Accept", ws_accept);
httpd_resp_send(req, NULL, 0);
// 创建 WebSocket 会话
wss_session_t *session = create_wss_session(req->handle);
if (session) {
start_wss_receive_task(session);
}
return ESP_OK;
}
// WebSocket 数据帧处理
typedef struct {
uint8_t fin : 1;
uint8_t rsv1 : 1;
uint8_t rsv2 : 1;
uint8_t rsv3 : 1;
uint8_t opcode : 4;
uint8_t mask : 1;
uint8_t payload_len : 7;
uint8_t extended_len[8]; // 扩展长度
uint8_t masking_key[4]; // 掩码密钥
} ws_frame_header_t;
// 发送 WebSocket 消息
esp_err_t wss_send_text(wss_session_t *session, const char *text) {
size_t text_len = strlen(text);
size_t frame_len = 2 + (text_len > 125 ? 2 : 0) + text_len;
uint8_t *frame = (uint8_t *)malloc(frame_len);
if (!frame) return ESP_ERR_NO_MEM;
// 构建文本帧
frame[0] = 0x81; // FIN + 文本帧
if (text_len < 126) {
frame[1] = text_len;
memcpy(frame + 2, text, text_len);
} else {
frame[1] = 126;
frame[2] = (text_len >> 8) & 0xFF;
frame[3] = text_len & 0xFF;
memcpy(frame + 4, text, text_len);
}
// 发送帧
esp_err_t ret = send(session->fd, frame, frame_len, 0);
free(frame);
return ret;
}
// 实时数据推送示例
void wss_data_push_task(void *arg) {
wss_session_t *session = (wss_session_t *)arg;
while (session->authenticated) {
// 获取传感器数据
sensor_data_t data = read_sensor_data();
// 构建 JSON 消息
cJSON *json = cJSON_CreateObject();
cJSON_AddNumberToObject(json, "temperature", data.temperature);
cJSON_AddNumberToObject(json, "humidity", data.humidity);
cJSON_AddNumberToObject(json, "pressure", data.pressure);
cJSON_AddNumberToObject(json, "timestamp", esp_timer_get_time() / 1000);
char *json_str = cJSON_PrintUnformatted(json);
wss_send_text(session, json_str);
cJSON_Delete(json);
free(json_str);
vTaskDelay(pdMS_TO_TICKS(1000)); // 每秒推送一次
}
}
🚀 开发最佳实践
USB 主机电源管理
c
// USB 主机电源状态管理
typedef enum {
USB_HOST_POWER_OFF,
USB_HOST_POWER_LOW,
USB_HOST_POWER_MEDIUM,
USB_HOST_POWER_HIGH,
} usb_host_power_state_t;
void usb_host_power_management(usb_device_info_t *dev_info) {
static usb_host_power_state_t current_state = USB_HOST_POWER_OFF;
usb_host_power_state_t new_state;
// 根据连接的设备类型确定功耗状态
if (!dev_info || !dev_info->connected) {
new_state = USB_HOST_POWER_OFF;
} else {
switch (dev_info->device_class) {
case USB_CLASS_HID:
new_state = USB_HOST_POWER_LOW; // 键盘/鼠标
break;
case USB_CLASS_CDC:
new_state = USB_HOST_POWER_MEDIUM; // 串口设备
break;
case USB_CLASS_MSC:
new_state = USB_HOST_POWER_HIGH; // 存储设备
break;
case USB_CLASS_VIDEO:
new_state = USB_HOST_POWER_HIGH; // 摄像头
break;
default:
new_state = USB_HOST_POWER_MEDIUM;
break;
}
}
// 状态切换处理
if (new_state != current_state) {
switch (new_state) {
case USB_HOST_POWER_OFF:
ESP_LOGI(TAG, "USB host power off");
usb_host_deinit();
set_cpu_frequency(CPU_FREQ_80MHZ);
break;
case USB_HOST_POWER_LOW:
ESP_LOGI(TAG, "USB host low power mode");
set_cpu_frequency(CPU_FREQ_80MHZ);
disable_usb_phy_pll();
break;
case USB_HOST_POWER_MEDIUM:
ESP_LOGI(TAG, "USB host medium power mode");
set_cpu_frequency(CPU_FREQ_160MHZ);
enable_usb_phy_pll();
break;
case USB_HOST_POWER_HIGH:
ESP_LOGI(TAG, "USB host high power mode");
set_cpu_frequency(CPU_FREQ_240MHZ);
enable_usb_phy_pll();
usb_host_set_current_limit(500); // 500mA 电流限制
break;
}
current_state = new_state;
}
}
HTTPS 服务器安全加固
c
// TLS 安全配置加固
void configure_secure_tls(httpd_ssl_config_t *ssl_config) {
// 仅允许 TLS 1.2 及以上版本
ssl_config->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
// 禁用弱加密套件
static const int secure_ciphersuites[] = {
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
0 // 结束标记
};
// 启用证书验证
ssl_config->cacert_pem = ca_cert_pem_start;
ssl_config->cacert_len = ca_cert_pem_end - ca_cert_pem_start;
ssl_config->client_verify_cert = true;
// 配置会话票证和会话恢复
ssl_config->session_tickets = true;
ssl_config->session_ticket_len = 48; // 384位
ssl_config->session_cache_size = 10;
// 启用 OCSP Stapling (如果支持)
ssl_config->ocsp_stapling = true;
// 设置安全的椭圆曲线
ssl_config->ecdh_curve = MBEDTLS_ECP_DP_SECP256R1;
// 启用 HSTS (HTTP Strict Transport Security)
ssl_config->hsts_max_age = 31536000; // 1年
// 禁用压缩以防止 CRIME 攻击
ssl_config->disable_compression = true;
}
// HTTP 安全头部配置
void add_security_headers(httpd_req_t *req) {
// HSTS - 强制 HTTPS
httpd_resp_set_hdr(req, "Strict-Transport-Security", "max-age=31536000; includeSubDomains");
// X-Frame-Options - 防止点击劫持
httpd_resp_set_hdr(req, "X-Frame-Options", "DENY");
// X-Content-Type-Options - 防止 MIME 类型嗅探
httpd_resp_set_hdr(req, "X-Content-Type-Options", "nosniff");
// Content-Security-Policy - 限制资源加载
httpd_resp_set_hdr(req, "Content-Security-Policy",
"default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'");
// X-XSS-Protection - 浏览器 XSS 过滤
httpd_resp_set_hdr(req, "X-XSS-Protection", "1; mode=block");
// Referrer-Policy - 控制 Referer 头
httpd_resp_set_hdr(req, "Referrer-Policy", "strict-origin-when-cross-origin");
}
// 请求速率限制
typedef struct {
uint32_t request_count;
uint64_t window_start;
uint32_t window_requests[60]; // 60秒滑动窗口
} rate_limit_t;
bool check_rate_limit(rate_limit_t *limit, const char *client_ip) {
uint64_t current_time = esp_timer_get_time() / 1000000; // 转换为秒
uint32_t current_second = current_time % 60;
// 清理旧数据
if (current_time - limit->window_start >= 60) {
memset(limit->window_requests, 0, sizeof(limit->window_requests));
limit->window_start = current_time;
limit->request_count = 0;
}
// 检查当前秒的请求数
if (limit->window_requests[current_second] >= RATE_LIMIT_PER_SECOND) {
ESP_LOGW(TAG, "Rate limit exceeded for IP: %s", client_ip);
return false;
}
// 检查总请求数
if (limit->request_count >= RATE_LIMIT_PER_MINUTE) {
ESP_LOGW(TAG, "Minute rate limit exceeded for IP: %s", client_ip);
return false;
}
// 更新计数器
limit->window_requests[current_second]++;
limit->request_count++;
return true;
}
📊 性能特性参考
| 功能模块 | 最大连接数 | 吞吐量 | 延迟 | 内存占用 |
|---|---|---|---|---|
| HTTP 服务器 | 10-20 | 10-50 Mbps | 10-100ms | 50-100KB |
| HTTPS 服务器 | 5-10 | 5-20 Mbps | 20-200ms | 100-200KB |
| WebSocket 服务器 | 10-30 | 1-10 Mbps | < 10ms | 20-50KB |
| USB CDC 主机 | 5-10 设备 | 12 Mbps | < 1ms | 30-60KB |
| USB MSC 主机 | 1-2 设备 | 20-40 Mbps | 可变 | 50-100KB |
| UVC 主机 | 1 设备 | 30-60 Mbps | 33ms (30fps) | 100-200KB |
安全协议性能影响
text
协议 加密开销 握手延迟 内存占用 适用场景
HTTP (明文) 无 低 低 内部网络
HTTPS (TLS) 20-30% 100-500ms 中 公网访问
WSS (TLS) 20-30% 100-500ms 中 实时通信
WebSocket 服务器
1. simple
简单 WebSocket 服务器
基础 WebSocket 服务器实现
支持文本和二进制帧
连接管理和心跳检测
2. ws_echo_server
WebSocket 回显服务器
接收消息并原样返回
WebSocket 协议验证
基础通信测试
📗 Modbus 协议
3. serial
串口 Modbus 总目录
- Modbus RTU/ASCII 协议实现
4. mb_master
Modbus 主站 (串口)
Modbus RTU/ASCII 主设备
读取/写入寄存器
轮询和事件驱动
5. mb_slave
Modbus 从站 (串口)
Modbus RTU/ASCII 从设备
响应主站请求
寄存器映射管理
6. tcp
TCP Modbus 总目录
- Modbus TCP 协议实现
7. mb_tcp_master
Modbus TCP 主站
Modbus TCP 客户端
网络通信优化
多从站管理
8. mb_tcp_slave
Modbus TCP 从站
Modbus TCP 服务器
并发连接处理
工业物联网应用
📙 MQTT 协议
9. mqtt
MQTT 协议总目录
- MQTT 客户端实现
10. custom_outbox
自定义发件箱
自定义 MQTT 消息队列
QoS 1/2 消息存储
离线消息支持
11. ssl
MQTT over SSL
MQTT 安全连接 (单向认证)
TLS 加密传输
证书验证
12. ssl_ds
MQTT SSL 数字签名
使用数字签名的 SSL 认证
增强安全性
硬件安全模块支持
13. ssl_mutual_auth
MQTT SSL 双向认证
客户端和服务端双向认证
最高安全级别
企业级应用
14. ssl_psk
MQTT SSL 预共享密钥
预共享密钥认证
轻量级安全方案
资源受限设备
15. tcp
MQTT over TCP
基础 TCP 连接
无加密通信
内部网络使用
16. ws
MQTT over WebSocket
WebSocket 传输 MQTT
浏览器兼容性
防火墙穿透
17. wss
MQTT over WSS
WebSocket Secure 传输
TLS 加密的 WebSocket
安全 Web 应用
📘 Socket 编程
18. sockets
Socket 编程总目录
- BSD Socket API 使用
19. icmpv6_ping
ICMPv6 Ping
IPv6 Ping 工具实现
网络连通性测试
ICMPv6 协议处理
20. non_blocking
非阻塞 Socket
非阻塞 I/O 操作
select/poll 多路复用
高性能网络编程
21. tcp_client
TCP 客户端
TCP 客户端基础
连接建立和数据传输
错误处理和重连
22. tcp_client_multi_net
多网络 TCP 客户端
多网络接口支持
WiFi 和以太网切换
网络故障转移
23. tcp_server
TCP 服务器
TCP 服务器实现
多客户端并发
连接管理
24. tcp_transport_client
TCP 传输客户端
高级 TCP 客户端
传输层优化
可靠数据传输
25. udp_client
UDP 客户端
UDP 客户端实现
无连接通信
广播和组播支持
26. udp_multicast
UDP 组播
IP 组播通信
一对多数据传输
组播组成员管理
27. udp_server
UDP 服务器
UDP 服务器实现
数据报处理
实时通信应用
🎯 应用场景深度解析
工业自动化控制系统
yaml
硬件配置:
- 现场总线: mb_master (Modbus RTU)
- 网络通信: mb_tcp_slave (Modbus TCP)
- 监控系统: mqtt (数据上报)
- 远程访问: wss (WebSocket 安全)
软件架构:
现场设备层:
├── Modbus RTU 主站 (PLC 控制)
├── 串口通信 (RS485 总线)
├── 设备轮询 (实时数据)
└── 错误恢复 (自动重试)
网络网关层:
├── Modbus TCP 服务器 (以太网)
├── 协议转换 (RTU ↔ TCP)
├── 数据缓存 (环形队列)
└── 连接管理 (多客户端)
云端服务层:
├── MQTT 客户端 (数据上传)
├── SSL 双向认证 (企业安全)
├── QoS 消息保障 (可靠传输)
└── WebSocket 实时监控 (Web 界面)
智能家居物联网平台
yaml
硬件配置:
- 本地通信: udp_multicast (设备发现)
- 云连接: mqtt_ssl (安全通信)
- 远程控制: ws_echo_server (实时控制)
- 网络诊断: icmpv6_ping (网络测试)
软件架构:
设备发现层:
├── UDP 组播广播 (设备发现)
├── mDNS 服务注册 (零配置)
├── 设备配对 (安全绑定)
└── 拓扑维护 (状态同步)
数据通信层:
├── MQTT over TLS (加密传输)
├── QoS 分级消息 (优先级)
├── 离线消息队列 (断网缓存)
└── 连接保持 (心跳机制)
控制接口层:
├── WebSocket 服务器 (实时控制)
├── RESTful API (配置管理)
├── OTA 更新 (固件升级)
└── 事件通知 (推送服务)
网络测试与监控系统
yaml
硬件配置:
- 协议测试: tcp_server (服务模拟)
- 性能测试: non_blocking (并发测试)
- 安全测试: mqtt_ssl_mutual_auth (认证测试)
- 网络诊断: udp_client (工具集)
软件架构:
协议测试套件:
├── Modbus 协议测试 (工业协议)
├── MQTT 客户端测试 (物联网协议)
├── WebSocket 测试 (实时协议)
└── 自定义协议测试 (扩展性)
性能测试工具:
├── 并发连接测试 (压力测试)
├── 吞吐量测试 (带宽测试)
├── 延迟测试 (响应时间)
└── 稳定性测试 (长时运行)
安全测试模块:
├── TLS 配置验证 (证书检查)
├── 加密强度测试 (算法验证)
├── 认证机制测试 (密码/PKI)
└── 漏洞扫描 (安全审计)
🔧 技术实现指南
Modbus TCP 服务器实现
c
// Modbus TCP 服务器配置
#define MB_TCP_PORT 502
#define MB_TCP_MAX_CLIENTS 5
#define MB_TCP_TIMEOUT 1000 // ms
// Modbus 功能码处理
typedef esp_err_t (*modbus_handler_t)(uint8_t *request, uint8_t *response,
uint16_t *response_len);
// 功能码处理器表
static modbus_handler_t modbus_handlers[] = {
[MB_FUNC_READ_COILS] = handle_read_coils,
[MB_FUNC_READ_DISCRETE_INPUTS] = handle_read_discrete_inputs,
[MB_FUNC_READ_HOLDING_REGISTERS] = handle_read_holding_registers,
[MB_FUNC_READ_INPUT_REGISTERS] = handle_read_input_registers,
[MB_FUNC_WRITE_SINGLE_COIL] = handle_write_single_coil,
[MB_FUNC_WRITE_SINGLE_REGISTER] = handle_write_single_register,
[MB_FUNC_WRITE_MULTIPLE_COILS] = handle_write_multiple_coils,
[MB_FUNC_WRITE_MULTIPLE_REGISTERS] = handle_write_multiple_registers,
};
// Modbus TCP 服务器任务
static void mb_tcp_server_task(void *pvParameters) {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_len = sizeof(client_addr);
// 创建 TCP 套接字
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
ESP_LOGE(TAG, "Failed to create socket");
vTaskDelete(NULL);
}
// 配置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(MB_TCP_PORT);
// 绑定和监听
bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
listen(server_fd, MB_TCP_MAX_CLIENTS);
ESP_LOGI(TAG, "Modbus TCP server started on port %d", MB_TCP_PORT);
while (1) {
// 接受客户端连接
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
if (client_fd < 0) {
ESP_LOGE(TAG, "Failed to accept connection");
continue;
}
ESP_LOGI(TAG, "New Modbus TCP client connected: %s:%d",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 为每个客户端创建处理任务
xTaskCreate(mb_tcp_client_handler, "mb_tcp_client", 4096,
(void *)(intptr_t)client_fd, 5, NULL);
}
}
// Modbus TCP 客户端处理
static void mb_tcp_client_handler(void *pvParameters) {
int client_fd = (int)(intptr_t)pvParameters;
uint8_t request[256], response[256];
while (1) {
// 接收 Modbus 请求
ssize_t recv_len = recv(client_fd, request, sizeof(request), 0);
if (recv_len <= 0) {
break; // 连接关闭或错误
}
// 验证 Modbus PDU (去掉 MBAP 头)
if (recv_len < 7) {
ESP_LOGW(TAG, "Invalid Modbus TCP packet length");
continue;
}
// 提取事务ID、协议ID、长度和单元ID
uint16_t transaction_id = (request[0] << 8) | request[1];
uint16_t protocol_id = (request[2] << 8) | request[3];
uint16_t length = (request[4] << 8) | request[5];
uint8_t unit_id = request[6];
if (protocol_id != 0) {
ESP_LOGW(TAG, "Invalid Modbus protocol ID: %d", protocol_id);
continue;
}
// 处理 Modbus 功能码
uint8_t function_code = request[7];
if (function_code >= sizeof(modbus_handlers) / sizeof(modbus_handlers[0]) ||
modbus_handlers[function_code] == NULL) {
// 不支持的函数码,返回异常响应
build_exception_response(response, unit_id, function_code,
MB_EX_ILLEGAL_FUNCTION);
length = 3; // 异常响应长度
} else {
// 调用对应的处理器
uint16_t resp_len = 0;
esp_err_t err = modbus_handlers[function_code](request + 7,
response + 7, &resp_len);
if (err == ESP_OK) {
length = resp_len + 1; // +1 用于单元ID
response[6] = unit_id;
} else {
build_exception_response(response, unit_id, function_code,
MB_EX_SLAVE_DEVICE_FAILURE);
length = 3;
}
}
// 构建 MBAP 头
response[0] = (transaction_id >> 8) & 0xFF;
response[1] = transaction_id & 0xFF;
response[2] = 0; // 协议ID高字节
response[3] = 0; // 协议ID低字节
response[4] = (length >> 8) & 0xFF;
response[5] = length & 0xFF;
// 发送响应
send(client_fd, response, length + 6, 0);
}
close(client_fd);
ESP_LOGI(TAG, "Modbus TCP client disconnected");
vTaskDelete(NULL);
}
MQTT with SSL 双向认证
c
// MQTT SSL 双向认证配置
typedef struct {
esp_mqtt_client_handle_t client;
esp_mqtt_client_config_t config;
xSemaphoreHandle connected_sem;
QueueHandle_t message_queue;
} mqtt_ssl_client_t;
// MQTT 事件处理
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) {
mqtt_ssl_client_t *mqtt_client = event->user_context;
switch (event->event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT connected");
xSemaphoreGive(mqtt_client->connected_sem);
// 订阅主题
esp_mqtt_client_subscribe(mqtt_client->client, "device/control", 1);
esp_mqtt_client_subscribe(mqtt_client->client, "device/config", 2);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT disconnected");
break;
case MQTT_EVENT_DATA: {
ESP_LOGI(TAG, "MQTT message received on topic %.*s: %.*s",
event->topic_len, event->topic,
event->data_len, event->data);
// 将消息放入队列供其他任务处理
mqtt_message_t msg = {
.topic = strndup(event->topic, event->topic_len),
.data = strndup(event->data, event->data_len),
.topic_len = event->topic_len,
.data_len = event->data_len,
};
xQueueSend(mqtt_client->message_queue, &msg, portMAX_DELAY);
break;
}
case MQTT_EVENT_ERROR:
ESP_LOGE(TAG, "MQTT error");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
ESP_LOGE(TAG, "Transport error: %s",
esp_err_to_name(event->error_handle->esp_transport_sock_errno));
}
break;
}
return ESP_OK;
}
// 初始化 MQTT SSL 客户端
esp_err_t mqtt_ssl_client_init(mqtt_ssl_client_t *mqtt_client,
const char *broker_uri) {
// SSL 配置 (双向认证)
esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = broker_uri,
.credentials = {
.username = "device001",
.authentication.password = "secret",
},
.session = {
.last_will = {
.topic = "device/status",
.msg = "offline",
.qos = 1,
.retain = true,
},
},
.network = {
.timeout_ms = 10000,
.disable_auto_reconnect = false,
.reconnect_timeout_ms = 5000,
},
.task = {
.priority = 5,
.stack_size = 6144,
},
.buffer = {
.size = 2048,
},
};
// SSL 配置 - 双向认证
mqtt_cfg.broker.verification.certificate = (const char *)ca_cert_pem_start;
mqtt_cfg.broker.verification.use_global_ca_store = false;
mqtt_cfg.credentials.authentication.certificate = (const char *)client_cert_pem_start;
mqtt_cfg.credentials.authentication.key = (const char *)client_key_pem_start;
mqtt_cfg.credentials.authentication.key_password = "client_key_password";
// 创建 MQTT 客户端
mqtt_client->client = esp_mqtt_client_init(&mqtt_cfg);
if (!mqtt_client->client) {
return ESP_FAIL;
}
// 设置事件处理器
esp_mqtt_client_register_event(mqtt_client->client,
ESP_EVENT_ANY_ID,
mqtt_event_handler,
mqtt_client);
// 创建信号量和队列
mqtt_client->connected_sem = xSemaphoreCreateBinary();
mqtt_client->message_queue = xQueueCreate(10, sizeof(mqtt_message_t));
// 启动 MQTT 客户端
esp_mqtt_client_start(mqtt_client->client);
// 等待连接建立
if (xSemaphoreTake(mqtt_client->connected_sem, pdMS_TO_TICKS(10000)) != pdTRUE) {
ESP_LOGE(TAG, "MQTT connection timeout");
return ESP_FAIL;
}
return ESP_OK;
}
// 发布遥测数据
esp_err_t mqtt_publish_telemetry(mqtt_ssl_client_t *mqtt_client,
const char *sensor, float value) {
cJSON *json = cJSON_CreateObject();
cJSON_AddStringToObject(json, "device_id", "esp32_001");
cJSON_AddStringToObject(json, "sensor", sensor);
cJSON_AddNumberToObject(json, "value", value);
cJSON_AddNumberToObject(json, "timestamp", (double)esp_timer_get_time() / 1000000);
char *json_str = cJSON_PrintUnformatted(json);
int msg_id = esp_mqtt_client_publish(mqtt_client->client,
"device/telemetry",
json_str, 0, 1, 0);
cJSON_Delete(json);
free(json_str);
return (msg_id >= 0) ? ESP_OK : ESP_FAIL;
}
WebSocket 服务器实现
c
// WebSocket 服务器配置
#define WS_MAX_CLIENTS 10
#define WS_BUFFER_SIZE 2048
#define WS_PING_INTERVAL 30000 // 30秒心跳
// WebSocket 客户端结构
typedef struct {
int fd;
bool authenticated;
uint64_t last_activity;
uint8_t *rx_buffer;
uint16_t rx_len;
QueueHandle_t tx_queue;
} ws_client_t;
// WebSocket 帧解析
typedef enum {
WS_OP_CONTINUATION = 0x0,
WS_OP_TEXT = 0x1,
WS_OP_BINARY = 0x2,
WS_OP_CLOSE = 0x8,
WS_OP_PING = 0x9,
WS_OP_PONG = 0xA,
} ws_opcode_t;
// WebSocket 服务器初始化
esp_err_t ws_server_init(uint16_t port) {
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
return ESP_FAIL;
}
// 设置 SO_REUSEADDR 选项
int opt = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(server_fd);
return ESP_FAIL;
}
if (listen(server_fd, WS_MAX_CLIENTS) < 0) {
close(server_fd);
return ESP_FAIL;
}
// 创建接收任务
xTaskCreate(ws_server_task, "ws_server", 4096, (void *)(intptr_t)server_fd, 5, NULL);
ESP_LOGI(TAG, "WebSocket server started on port %d", port);
return ESP_OK;
}
// WebSocket 帧发送
esp_err_t ws_send_frame(int fd, ws_opcode_t opcode, const uint8_t *payload, size_t len) {
uint8_t header[14]; // 最大头部长度
size_t header_len = 2;
header[0] = 0x80 | opcode; // FIN + opcode
if (len < 126) {
header[1] = len;
} else if (len < 65536) {
header[1] = 126;
header[2] = (len >> 8) & 0xFF;
header[3] = len & 0xFF;
header_len = 4;
} else {
header[1] = 127;
header[2] = (len >> 56) & 0xFF;
header[3] = (len >> 48) & 0xFF;
header[4] = (len >> 40) & 0xFF;
header[5] = (len >> 32) & 0xFF;
header[6] = (len >> 24) & 0xFF;
header[7] = (len >> 16) & 0xFF;
header[8] = (len >> 8) & 0xFF;
header[9] = len & 0xFF;
header_len = 10;
}
// 发送头部
if (send(fd, header, header_len, 0) != header_len) {
return ESP_FAIL;
}
// 发送负载
if (len > 0 && send(fd, payload, len, 0) != len) {
return ESP_FAIL;
}
return ESP_OK;
}
// WebSocket 帧接收
esp_err_t ws_receive_frame(int fd, uint8_t *buffer, size_t *len, ws_opcode_t *opcode) {
uint8_t header[14];
// 读取前2字节头部
if (recv(fd, header, 2, 0) != 2) {
return ESP_FAIL;
}
*opcode = header[0] & 0x0F;
bool masked = header[1] & 0x80;
uint64_t payload_len = header[1] & 0x7F;
// 读取扩展长度
size_t header_len = 2;
if (payload_len == 126) {
if (recv(fd, header + 2, 2, 0) != 2) {
return ESP_FAIL;
}
payload_len = (header[2] << 8) | header[3];
header_len = 4;
} else if (payload_len == 127) {
if (recv(fd, header + 2, 8, 0) != 8) {
return ESP_FAIL;
}
payload_len = ((uint64_t)header[2] << 56) | ((uint64_t)header[3] << 48) |
((uint64_t)header[4] << 40) | ((uint64_t)header[5] << 32) |
((uint64_t)header[6] << 24) | ((uint64_t)header[7] << 16) |
((uint64_t)header[8] << 8) | header[9];
header_len = 10;
}
// 读取掩码密钥
uint8_t masking_key[4];
if (masked) {
if (recv(fd, masking_key, 4, 0) != 4) {
return ESP_FAIL;
}
header_len += 4;
}
// 读取负载数据
if (payload_len > *len) {
ESP_LOGE(TAG, "Payload too large: %llu > %zu", payload_len, *len);
return ESP_FAIL;
}
if (recv(fd, buffer, payload_len, 0) != payload_len) {
return ESP_FAIL;
}
// 应用掩码
if (masked) {
for (size_t i = 0; i < payload_len; i++) {
buffer[i] ^= masking_key[i % 4];
}
}
*len = payload_len;
return ESP_OK;
}
// WebSocket 心跳任务
static void ws_heartbeat_task(void *pvParameters) {
ws_client_t *clients = (ws_client_t *)pvParameters;
while (1) {
uint64_t current_time = esp_timer_get_time();
for (int i = 0; i < WS_MAX_CLIENTS; i++) {
if (clients[i].fd >= 0) {
// 检查活动超时
if (current_time - clients[i].last_activity > WS_PING_INTERVAL * 1000) {
// 发送 Ping 帧
uint8_t ping_payload[] = "heartbeat";
ws_send_frame(clients[i].fd, WS_OP_PING, ping_payload, sizeof(ping_payload));
// 如果长时间无响应,关闭连接
if (current_time - clients[i].last_activity > WS_PING_INTERVAL * 2000) {
ESP_LOGI(TAG, "Client %d timeout, closing connection", i);
close(clients[i].fd);
clients[i].fd = -1;
}
}
}
}
vTaskDelay(pdMS_TO_TICKS(1000)); // 每秒检查一次
}
}
非阻塞 Socket 多路复用
c
// 非阻塞 Socket 服务器
typedef struct {
int server_fd;
fd_set read_fds;
fd_set write_fds;
int max_fd;
int client_fds[FD_SETSIZE];
int num_clients;
} nonblocking_server_t;
// 初始化非阻塞服务器
esp_err_t nonblocking_server_init(nonblocking_server_t *server, uint16_t port) {
server->server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server->server_fd < 0) {
return ESP_FAIL;
}
// 设置为非阻塞模式
int flags = fcntl(server->server_fd, F_GETFL, 0);
fcntl(server->server_fd, F_SETFL, flags | O_NONBLOCK);
// 设置 SO_REUSEADDR
int opt = 1;
setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
.sin_port = htons(port),
};
if (bind(server->server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
close(server->server_fd);
return ESP_FAIL;
}
if (listen(server->server_fd, 10) < 0) {
close(server->server_fd);
return ESP_FAIL;
}
// 初始化客户端数组
memset(server->client_fds, -1, sizeof(server->client_fds));
server->num_clients = 0;
server->max_fd = server->server_fd;
ESP_LOGI(TAG, "Non-blocking server started on port %d", port);
return ESP_OK;
}
// 运行非阻塞服务器
void nonblocking_server_run(nonblocking_server_t *server) {
while (1) {
// 清空文件描述符集
FD_ZERO(&server->read_fds);
FD_ZERO(&server->write_fds);
// 添加服务器 socket 到读集
FD_SET(server->server_fd, &server->read_fds);
// 添加客户端 sockets
for (int i = 0; i < FD_SETSIZE; i++) {
if (server->client_fds[i] >= 0) {
FD_SET(server->client_fds[i], &server->read_fds);
if (has_data_to_send(server->client_fds[i])) {
FD_SET(server->client_fds[i], &server->write_fds);
}
}
}
// 使用 select 多路复用
struct timeval timeout = {.tv_sec = 1, .tv_usec = 0};
int activity = select(server->max_fd + 1, &server->read_fds,
&server->write_fds, NULL, &timeout);
if (activity < 0) {
ESP_LOGE(TAG, "select error: %d", errno);
continue;
}
if (activity == 0) {
// 超时,无活动
continue;
}
// 检查新连接
if (FD_ISSET(server->server_fd, &server->read_fds)) {
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int client_fd = accept(server->server_fd,
(struct sockaddr *)&client_addr, &addr_len);
if (client_fd >= 0) {
// 设置为非阻塞
int flags = fcntl(client_fd, F_GETFL, 0);
fcntl(client_fd, F_SETFL, flags | O_NONBLOCK);
// 添加到客户端列表
for (int i = 0; i < FD_SETSIZE; i++) {
if (server->client_fds[i] < 0) {
server->client_fds[i] = client_fd;
server->num_clients++;
if (client_fd > server->max_fd) {
server->max_fd = client_fd;
}
ESP_LOGI(TAG, "New client connected: %s:%d",
inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
break;
}
}
}
}
// 处理客户端数据
for (int i = 0; i < FD_SETSIZE; i++) {
int client_fd = server->client_fds[i];
if (client_fd < 0) continue;
// 检查可读
if (FD_ISSET(client_fd, &server->read_fds)) {
uint8_t buffer[1024];
ssize_t len = recv(client_fd, buffer, sizeof(buffer), 0);
if (len > 0) {
// 处理接收到的数据
handle_client_data(client_fd, buffer, len);
} else if (len == 0) {
// 连接关闭
ESP_LOGI(TAG, "Client disconnected");
close(client_fd);
server->client_fds[i] = -1;
server->num_clients--;
} else {
// 错误 (非阻塞返回 EAGAIN/EWOULDBLOCK 是正常的)
if (errno != EAGAIN && errno != EWOULDBLOCK) {
ESP_LOGE(TAG, "recv error: %d", errno);
close(client_fd);
server->client_fds[i] = -1;
server->num_clients--;
}
}
}
// 检查可写
if (FD_ISSET(client_fd, &server->write_fds)) {
// 发送排队的数据
send_queued_data(client_fd);
}
}
}
}
🚀 开发最佳实践
MQTT 消息队列和 QoS 实现
c
// MQTT 消息队列管理
typedef struct {
uint16_t message_id;
uint8_t qos;
char *topic;
uint8_t *payload;
size_t payload_len;
uint32_t timestamp;
uint8_t retry_count;
} mqtt_outbox_item_t;
// MQTT 发件箱管理
typedef struct {
mqtt_outbox_item_t *items;
size_t capacity;
size_t size;
SemaphoreHandle_t mutex;
QueueHandle_t free_queue;
QueueHandle_t pending_queue;
} mqtt_outbox_t;
// 初始化发件箱
esp_err_t mqtt_outbox_init(mqtt_outbox_t *outbox, size_t capacity) {
outbox->items = calloc(capacity, sizeof(mqtt_outbox_item_t));
if (!outbox->items) return ESP_ERR_NO_MEM;
outbox->capacity = capacity;
outbox->size = 0;
outbox->mutex = xSemaphoreCreateMutex();
outbox->free_queue = xQueueCreate(capacity, sizeof(mqtt_outbox_item_t *));
outbox->pending_queue = xQueueCreate(capacity, sizeof(mqtt_outbox_item_t *));
// 初始化空闲队列
for (size_t i = 0; i < capacity; i++) {
xQueueSend(outbox->free_queue, &outbox->items[i], portMAX_DELAY);
}
return ESP_OK;
}
// 添加消息到发件箱
esp_err_t mqtt_outbox_enqueue(mqtt_outbox_t *outbox, const char *topic,
const uint8_t *payload, size_t payload_len,
uint8_t qos, uint16_t *message_id) {
mqtt_outbox_item_t *item = NULL;
if (xQueueReceive(outbox->free_queue, &item, pdMS_TO_TICKS(100)) != pdTRUE) {
return ESP_ERR_NO_MEM; // 发件箱已满
}
xSemaphoreTake(outbox->mutex, portMAX_DELAY);
static uint16_t next_msg_id = 1
1. esp_http_client
-
说明:使用 ESP-HTTP-Client 库进行 HTTP 请求的示例,支持 GET、POST 等请求方式。
-
适用场景:连接 Web 服务器、发送 API 请求、下载文件等。
2. esp_local_ctrl
-
说明:演示如何通过本地网络控制设备,支持 JSON-RPC 或自定义协议。
-
适用场景:局域网设备控制、本地配置管理等。
3. https_mbedtls
-
说明:使用 mbedTLS 库进行 HTTPS 安全通信的示例。
-
适用场景:需要加密传输的 Web 请求、安全 API 调用。
4. https_request
-
说明:发起 HTTPS 请求的示例,使用内置证书或自定义证书。
-
适用场景:安全连接服务器、访问 HTTPS 网站。
5. https_x509_bundle
-
说明:演示如何使用 X.509 证书包进行 HTTPS 验证。
-
适用场景:需要自定义 CA 证书或客户端证书的 HTTPS 连接。
6. http_request
-
说明:发起普通 HTTP 请求的示例,不加密传输。
-
适用场景:内部网络通信、测试服务器连接。
7. icmp_echo
-
说明:实现 ICMP Echo 请求(ping)功能的示例。
-
适用场景:网络连通性测试、延迟测量。
8. l2tap
-
说明:演示如何使用 L2TP 访问层(Link Layer TAP)进行数据包捕获或注入。
-
适用场景:网络调试、协议分析、自定义网络栈。
9. mqtt5
-
说明:使用 MQTT 5.0 协议与 MQTT 服务器通信的示例。
-
适用场景:物联网设备通信、消息发布与订阅。
10. smtp_client
-
说明:实现 SMTP 客户端发送电子邮件的示例。
-
适用场景:设备告警邮件、日志邮件发送。
11. sntp
-
说明:使用 SNTP 协议从时间服务器同步系统时间的示例。
-
适用场景:设备时间同步、日志时间戳。
12. static_jp
-
说明:演示如何在 ESP32 上提供静态网页服务(可能是日语界面或内容)。
-
适用场景:本地 Web 服务器、设备配置页面。
13. provisioning
-
说明:设备配网示例,支持 Wi-Fi 网络配置。
-
适用场景:首次启动设备时的网络配置、AP 配网。
14. wifi_prov_mgr
-
说明:使用 Wi-Fi Provisioning Manager 进行智能配网的示例。
-
适用场景:手机 App 配网、蓝牙配网、Wi-Fi 配网管理。
15. flash_encryption
-
说明:演示如何启用和使用 Flash 加密功能。
-
适用场景:保护固件和数据免受未经授权的读取。
16. hmac_soft_jtag
-
说明:使用 HMAC 软 JTAG 进行安全调试访问的示例。
-
适用场景:安全调试、防止未授权 JTAG 访问。
17. nvs_encryption_hmac
-
说明:演示如何使用 HMAC 加密 NVS(非易失性存储)数据。
-
适用场景:保护存储中的敏感数据(如密钥、配置)。
18. security_features_app
-
说明:综合展示 ESP-IDF 安全功能的示例应用。
-
适用场景:安全功能集成测试、安全配置参考。
19. fatfs
-
说明:使用 FAT 文件系统读写 SD 卡或 SPI Flash 的示例。
-
适用场景:文件存储、日志记录、数据读写。
20. ext_flash
-
说明:演示如何访问外部 Flash 存储器。
-
适用场景:扩展存储空间、大文件存储。
21. fatfsgen
-
说明:用于生成 FAT 文件系统镜像的工具示例。
-
适用场景:预置文件系统镜像、批量文件打包。
22. fs_operations
-
说明:演示如何进行文件系统操作(如创建、读写、删除文件)。
-
适用场景:文件系统学习、存储管理。
23. getting_started
-
说明:ESP-IDF 入门示例,通常为"Hello World"或基础功能演示。
-
适用场景:新手入门、环境测试、基础功能验证。
分类:partition_api(分区 API 相关示例)
1. partition_find
-
说明:演示如何查找和枚举 ESP32 分区表中的分区。
-
适用场景:遍历分区表、获取分区信息(如类型、大小、地址)。
2. partition_mmap
-
说明:演示如何将分区内容映射到内存中(mmap)进行直接访问。
-
适用场景:快速读取分区数据、无需缓冲区的文件访问。
3. partition_ops
-
说明:演示分区的基本操作,如读取、写入、擦除等。
-
适用场景:分区数据读写、分区管理。
分类:sd_card(SD 卡相关示例)
4. sdmmc
-
说明:使用 SDMMC 协议(4 线模式)访问 SD 卡的示例。
-
适用场景:高速 SD 卡读写、大容量存储。
5. sdspi
-
说明:使用 SPI 模式访问 SD 卡的示例。
-
适用场景:使用 SPI 接口连接 SD 卡、节省 GPIO 引脚。
分类:文件系统与存储
6. custom_flash_driver
-
说明:演示如何实现自定义 Flash 驱动程序。
-
适用场景:支持非标准 Flash 芯片、自定义存储设备。
7. emmc
-
说明:使用 eMMC 存储设备的示例。
-
适用场景:嵌入式大容量存储、eMMC 芯片访问。
8. littlefs
-
说明:使用 LittleFS 文件系统的示例,适合 Flash 存储。
-
适用场景:高可靠性 Flash 文件系统、掉电保护。
9. nvsgen
-
说明:用于生成 NVS(非易失性存储)分区镜像的工具示例。
-
适用场景:预置 NVS 数据、批量密钥配置。
10. nvs_bootloader
-
说明:演示如何在引导程序(bootloader)中访问 NVS。
-
适用场景:引导阶段读取配置、安全启动参数。
11. nvs_rw_blob
-
说明:演示如何读写 NVS 中的二进制大对象(Blob)数据。
-
适用场景:存储复杂数据结构(如结构体、数组)。
12. nvs_rw_value
-
说明:演示如何读写 NVS 中的基本类型数据(如整数、字符串)。
-
适用场景:存储配置参数、设备状态。
13. nvs_rw_value_cxx
-
说明:使用 C++ API 读写 NVS 数据的示例。
-
适用场景:C++ 项目中的 NVS 操作。
14. parttool
-
说明:用于分区表操作的工具示例(如擦除、写入分区)。
-
适用场景:分区管理、固件更新辅助工具。
15. perf_benchmark
-
说明:存储性能测试示例,用于评估读写速度。
-
适用场景:性能测试、存储设备选型。
16. semihost_vfs
-
说明:演示如何通过 JTAG 半主机模式访问主机文件系统。
-
适用场景:调试时读写主机文件、日志输出到主机。
17. spiffs
-
说明:使用 SPIFFS 文件系统的示例(适用于 SPI Flash)。
-
适用场景:轻量级只读文件系统、固件资源存储。
18. spiffsgen
-
说明:用于生成 SPIFFS 文件系统镜像的工具示例。
-
适用场景:预置 SPIFFS 镜像、资源打包。
19. wear_leveling
-
说明:演示 Flash 磨损均衡功能的示例。
-
适用场景:延长 Flash 寿命、频繁写入场景。
分类:system console(系统控制台相关)
20. advanced
-
说明:演示高级控制台功能,如命令注册、参数解析、历史记录等。
-
适用场景:复杂命令行交互、自定义控制台命令。
21. basic
-
说明:演示基础控制台功能,如回显、基本输入输出。
-
适用场景:简单命令行交互、调试信息输出。
分类:esp_event(事件循环系统)
1. default_event_loop
-
说明:演示如何使用 ESP-IDF 默认事件循环处理系统事件(如 Wi-Fi 事件、IP 事件)。
-
适用场景:监听系统事件、事件驱动编程。
2. user_event_loops
-
说明:演示如何创建和使用自定义事件循环,以处理用户定义的事件。
-
适用场景:自定义事件处理、多事件循环隔离。
分类:freertos(FreeRTOS 相关)
3. basic_freertos_smp_usage
-
说明:演示如何在多核 ESP32(SMP)上使用 FreeRTOS,包括任务分配和同步。
-
适用场景:多核任务调度、性能优化。
4. real_time_stats
-
说明:演示如何使用 FreeRTOS 实时统计功能,获取任务执行时间和 CPU 使用率。
-
适用场景:性能分析、任务调度监控。
分类:ipc_isr(中断服务程序与进程间通信)
5. riscv
-
说明:演示在 ESP32-C3/C6 等 RISC-V 架构芯片上使用 IPC(进程间通信)和 ISR。
-
适用场景:RISC-V 内核间的数据交换、中断处理。
6. xtensa
-
说明:演示在 Xtensa 架构芯片(如 ESP32/ESP32-S2/S3)上使用 IPC 和 ISR。
-
适用场景:双核通信、中断共享、数据同步。
分类:ota(无线固件升级)
7. advanced_https_ota
-
说明:演示通过 HTTPS 进行安全 OTA 升级,支持证书验证和加密传输。
-
适用场景:安全固件升级、企业级 OTA。
8. native_ota_example
-
说明:演示基本的 OTA 升级流程,使用 HTTP 服务器获取固件。
-
适用场景:简单的固件升级、测试 OTA 功能。
9. otatool
-
说明:用于生成 OTA 升级镜像和配置 OTA 分区的工具示例。
-
适用场景:OTA 镜像生成、分区管理。
10. pre_encrypted_ota
-
说明:演示如何升级预加密的固件镜像,支持 Flash 加密。
-
适用场景:安全固件升级、加密固件分发。
11. simple_ota_example
-
说明:最简单的 OTA 升级示例,适用于快速上手。
-
适用场景:初学者学习 OTA 升级。
分类:lp_core(低功耗协处理器相关)
12. lp_add(LP 核心示例)
-
说明:演示如何在低功耗协处理器(LP Core)上运行简单的加法任务。
-
适用场景:低功耗计算、常驻任务。
13. lp_i2c(LP 核心示例)
-
说明:演示如何在低功耗协处理器上使用 I2C 接口与外设通信。
-
适用场景:低功耗传感器数据采集、节能通信。
14. lp_uart_echo(LP UART 示例)
-
说明:演示在 LP Core 上使用 UART 进行数据回传。
-
适用场景:低功耗串口通信、调试信息输出。
15. lp_uart_print(LP UART 示例)
-
说明:演示在 LP Core 上通过 UART 打印信息,保持主核休眠。
-
适用场景:低功耗日志输出、状态监控。
分类:通用系统与调试
16. build_system
-
说明:演示 ESP-IDF 构建系统的使用方法,包括组件配置和依赖管理。
-
适用场景:项目构建配置、组件化开发。
17. debugging
-
说明:演示如何使用调试工具(如 JTAG、OpenOCD)进行代码调试。
-
适用场景:固件调试、断点设置、内存查看。
18. gpio
-
说明:演示 GPIO 的基本使用,包括输入输出配置。
-
适用场景:控制 LED、读取按键。
19. gpio_intr_pulse_counter
-
说明:演示使用 GPIO 中断和脉冲计数器功能。
-
适用场景:脉冲计数、频率测量。
20. gpio_wakeup
-
说明:演示如何通过 GPIO 中断唤醒芯片(从深度睡眠)。
-
适用场景:低功耗唤醒、事件触发。
21. interrupt
-
说明:演示中断服务程序(ISR)的基本编写和使用。
-
适用场景:硬件中断处理、实时响应。
22. inter_cpu_critical_section
-
说明:演示多核间的临界区保护机制,避免数据竞争。
-
适用场景:多核共享资源保护、数据同步。
1. inner_epu_structal_selection
-
说明:演示如何使用内部 EPU(嵌入式处理器单元)进行结构化数据选择或处理。
-
适用场景:数据处理加速、结构化数据过滤。
2. lp_adc
-
说明:演示在低功耗协处理器(LP Core)上使用 ADC 进行模拟信号采样。
-
适用场景:低功耗传感器数据采集、电池监测。
3. lp_i2c
-
说明:演示在低功耗协处理器上使用 I2C 接口与外设通信。
-
适用场景:低功耗传感器读取、节能通信。
4. ulp_fsm
-
说明:演示使用 ULP(超低功耗)协处理器的有限状态机功能。
-
适用场景:极低功耗任务处理、状态机控制。
5. ulp
-
说明:演示 ULP 协处理器的基本使用,包括唤醒和简单任务执行。
-
适用场景:深度睡眠下的常驻任务、低功耗监控。
6. ulp_adc
-
说明:演示在 ULP 协处理器上使用 ADC 进行模拟信号采集。
-
适用场景:超低功耗环境下的传感器采样。
7. ulp_riscv
-
说明:演示在支持 RISC-V ULP 的芯片上编写和运行 ULP 程序。
-
适用场景:RISC-V ULP 开发、低功耗计算。
8. adc
-
说明:演示主核 ADC 的基本使用,包括单次采样和连续采样。
-
适用场景:模拟信号读取、电压测量。
9. ds18b20_onewire
-
说明:演示通过单总线协议(OneWire)读取 DS18B20 温度传感器。
-
适用场景:温度监测、单总线设备通信。
10. gpio
-
说明:演示 GPIO 的基本输入输出功能。
-
适用场景:控制 LED、读取按键。
11. gpio_interrupt
-
说明:演示 GPIO 中断的配置和使用。
-
适用场景:外部事件触发、实时响应。
12. i2c
-
说明:演示 I2C 主从通信的基本使用。
-
适用场景:连接 I2C 传感器、设备间通信。
13. interrupts
-
说明:演示中断服务程序(ISR)的编写和注册。
-
适用场景:硬件中断处理、实时事件响应。
14. touch
-
说明:演示 ESP32 触摸传感器的使用。
-
适用场景:触摸按键、手势检测。
15. uart_print
-
说明:演示通过 UART 串口输出调试信息。
-
适用场景:串口调试、日志输出。
16. app_trace_basic
-
说明:演示应用程序跟踪(App Trace)的基本使用,用于性能分析。
-
适用场景:代码执行追踪、性能瓶颈分析。
17. app_trace_to_plot
-
说明:演示将 App Trace 数据导出为图形化图表。
-
适用场景:可视化性能分析、时序图生成。
18. base_mac_address
-
说明:演示如何读取和设置 ESP32 的基础 MAC 地址。
-
适用场景:网络标识、设备唯一识别。
19. deep_sleep
-
说明:演示深度睡眠模式的进入和唤醒。
-
适用场景:极低功耗待机、定时唤醒。
20. deep_sleep_wake_stub
-
说明:演示深度睡眠唤醒时的存根(stub)函数执行。
-
适用场景:唤醒后立即执行特定代码。
21. efuse
-
说明:演示如何读写 eFuse(一次性可编程存储器)。
-
适用场景:存储唯一 ID、安全密钥、配置位。
22. esp_timer
-
说明:演示使用 ESP 定时器进行高精度定时任务。
-
适用场景:精确延时、周期性任务。
23. eventfd
-
说明:演示使用 eventfd 进行线程间事件通知。
-
适用场景:线程同步、事件驱动编程。
24. flash_suspend
-
说明:演示如何在 Flash 操作期间挂起系统以降低功耗。
-
适用场景:低功耗模式下的 Flash 访问。
25. gcov
-
说明:演示使用 Gcov 进行代码覆盖率测试。
-
适用场景:测试覆盖率分析、代码质量评估。
26. gdbstub
-
说明:演示通过 GDB 调试桩(stub)进行远程调试。
-
适用场景:远程 GDB 调试、无 JTAG 调试。
27. heap_task_tracking
-
说明:演示堆内存任务追踪功能,监控内存分配。
-
适用场景:内存泄漏检测、堆使用分析。
28. himem
-
说明:演示如何使用 ESP32 的高内存(HiMem)扩展功能。
-
适用场景:大内存需求应用、数据缓存。
29. light_sleep
-
说明:演示轻睡眠模式的进入和唤醒。
-
适用场景:低功耗待机、快速唤醒。
30. nmi_isr
-
说明:演示不可屏蔽中断(NMI)服务程序的编写。
-
适用场景:系统紧急处理、硬件故障响应。
31. perfmon
-
说明:演示使用性能监视器(PerfMon)进行系统性能统计。
-
适用场景:CPU 使用率监控、性能优化。
多线程与系统功能
1. pthread
-
说明:演示使用 POSIX 线程(pthread)进行多线程编程。
-
适用场景:跨平台多线程应用、复杂任务并行处理。
2. rt_mqueue
-
说明:演示使用实时消息队列(RTOS mqueue)进行线程间通信。
-
适用场景:实时任务间数据传输、进程间通信。
3. select
-
说明 :演示使用
select()函数进行多路 I/O 复用。 -
适用场景:多路 Socket 监听、非阻塞 I/O 管理。
4. startup_time
-
说明:演示如何测量系统启动时间并进行优化。
-
适用场景:启动性能分析、快速启动优化。
5. sysview_tracing
-
说明:演示使用 SystemView 进行实时系统追踪。
-
适用场景:系统任务调度分析、时序可视化调试。
6. sysview_tracing_heap_log
-
说明:演示结合 SystemView 和堆日志功能进行内存追踪。
-
适用场景:内存分配追踪、堆使用可视化分析。
7. task_watchdog
-
说明:演示任务看门狗(Task Watchdog)的配置和使用。
-
适用场景:任务死锁检测、系统稳定性监控。
8. unit_test
-
说明:演示 ESP-IDF 单元测试框架的使用方法。
-
适用场景:代码单元测试、自动化测试集成。
9. xip_from_psram
-
说明:演示从 PSRAM 执行代码(XIP,eXecute In Place)。
-
适用场景:扩展代码存储空间、大程序运行。
分类:Wi-Fi 功能示例
10. getting_started
-
说明:Wi-Fi 功能入门示例,演示基本的 Wi-Fi 连接。
-
适用场景:快速上手 Wi-Fi 连接、基础网络功能。
11. softAP
-
说明:演示将 ESP32 配置为 Wi-Fi 接入点(AP)。
-
适用场景:创建热点、设备直连配置。
12. station
-
说明:演示将 ESP32 配置为 Wi-Fi 站点(STA)连接到路由器。
-
适用场景:连接家庭/企业 Wi-Fi、互联网接入。
13. roaming_11kvr
-
说明:演示 Wi-Fi 802.11k/v/r 协议支持的无缝漫游功能。
-
适用场景:多 AP 漫游、移动设备网络切换。
14. roaming_app
-
说明:Wi-Fi 漫游应用示例,包含完整的漫游控制逻辑。
-
适用场景:智能家居漫游、工业移动设备。
分类:Wi-Fi Aware(邻居感知网络)
15. nan_console
-
说明:演示使用 Wi-Fi Aware(NAN)功能的控制台应用。
-
适用场景:NAN 网络调试、设备发现测试。
16. nan_publisher
-
说明:演示作为 Wi-Fi Aware 发布者(Publisher)广播服务。
-
适用场景:服务广播、设备发现。
17. nan_subscriber
-
说明:演示作为 Wi-Fi Aware 订阅者(Subscriber)发现服务。
-
适用场景:服务发现、设备连接。
Wi-Fi Easy Connect 及相关功能
1. dpp-enrollee
-
说明:演示 Wi-Fi DPP(Device Provisioning Protocol)安全配网功能,作为 enrollee 设备。
-
适用场景:通过二维码或 NFC 进行安全 Wi-Fi 配网。
2. espnow
-
说明:演示 ESP-NOW 协议的使用,实现设备间快速、低功耗的无 Wi-Fi 网络通信。
-
适用场景:设备间点对点通信、传感器网络、遥控器。
3. fast_scan
-
说明:演示快速 Wi-Fi 扫描功能,优化扫描速度和功耗。
-
适用场景:快速发现可用 Wi-Fi 网络、移动设备扫描。
4. ftm
-
说明:演示 Wi-Fi FTM(Fine Timing Measurement)功能,用于精确距离测量。
-
适用场景:室内定位、距离测量、位置服务。
5. iperf
-
说明:演示使用 iPerf 工具进行 Wi-Fi 网络性能测试。
-
适用场景:网络带宽测试、吞吐量测量。
6. itwt
-
说明:演示 Wi-Fi 6/6E 的 TWT(Target Wake Time)功能,用于节能。
-
适用场景:低功耗 Wi-Fi 设备、延长电池寿命。
7. power_save
-
说明:演示 Wi-Fi 省电模式的配置和使用。
-
适用场景:电池供电设备、低功耗 Wi-Fi 连接。
8. scan
-
说明:演示基本的 Wi-Fi 网络扫描功能。
-
适用场景:发现周围 Wi-Fi 网络、信号强度检测。
9. smart_config
-
说明:演示 SmartConfig(智能配网)功能,通过手机 App 快速配网。
-
适用场景:一键配网、用户友好设备配网。
10. softap_sta
-
说明:演示 ESP32 同时作为 AP(热点)和 STA(连接路由器)的工作模式。
-
适用场景:中继模式、设备桥接、网络扩展。
11. wifi_eap_fast
-
说明:演示使用 EAP-FAST(Flexible Authentication via Secure Tunneling)协议的企业 Wi-Fi 认证。
-
适用场景:企业网络接入、安全认证。
12. wifi_enterprise
-
说明:演示企业级 Wi-Fi 认证(如 EAP-TLS、PEAP、TTLS)。
-
适用场景:企业网络、校园网、安全 Wi-Fi 接入。
13. wps
-
说明:演示 Wi-Fi Protected Setup(WPS)功能,快速安全连接。
-
适用场景:快速配对、无需密码连接 Wi-Fi。
14. wps_softap_registrar
-
说明:演示作为 WPS 注册器(Registrar)的 SoftAP 模式。
-
适用场景:设备作为 WPS 注册器、安全配网。
分类:Zigbee 协议栈示例
15. light_sample
-
说明:演示 Zigbee 照明设备的基本功能(如开关、调光)。
-
适用场景:智能灯泡、照明控制系统。
16. HA_on_off_light
-
说明:演示符合 Zigbee Home Automation(ZHA)标准的开关灯设备。
-
适用场景:Zigbee HA 兼容的智能灯控。
17. HA_on_off_switch
-
说明:演示符合 Zigbee HA 标准的开关控制器设备。
-
适用场景:Zigbee 墙面开关、遥控器。
18. esp_zigbee_gateway
-
说明:演示基于 ESP32 的 Zigbee 网关功能,连接 Zigbee 网络与 Wi-Fi/以太网。
-
适用场景:智能家居网关、Zigbee 网络桥接。