BLE 开发中,ATT_MTU 直接决定单次能发多少数据。默认 23 字节(有效 20 字节)传得慢、包数多,想提速必须改大 MTU。
很多人用 BlueNRG-LP 改 MTU 时遇到改不动、达不到预期、手机不协商、跑不起来等问题,ST 官方 LAT1321 笔记把这套流程讲得最清楚。本文用实战化、可直接照做的方式,把修改步骤、坑点、配置逻辑一次性讲透。
资料获取:【应用笔记】LAT1321 基于BlueNRG SDK 修改ATT_MTU
1. 先搞懂:BLE 的 ATT_MTU 到底是什么
- ATT_MTU = 一次 ATT 事务最大传输长度
- 默认:23 字节(有效数据 20 字节)
- 连接后双方协商 MTU,最终取较小值
- BlueNRG-LP 最大支持:1018 字节
- 手机常见上限:iPhone 约527 字节,安卓各型号不同
改大 MTU 好处:
- 减少发包数量,提升传输效率
- 降低空中占用时间
- 适合 OTA、日志回传、大帧数据
2. BlueNRG 修改 MTU 核心:只改一个宏
在工程的协议栈配置文件(如 SerialPort_config.h)里找到:
#define MAX_ATT_MTU_CONF xxx
把它改成你需要的值,例如:
#define MAX_ATT_MTU_CONF 200
这是外设端宣告的最大 MTU。
3. 最常见坑:改到 200 却只能到 185?
因为默认链路层包长太短,协议栈限制了拆包数量。
想真正跑大 MTU,必须开DLE 数据长度扩展:
#define CONTROLLER_DATA_LENGTH_EXTENSION_ENABLED
开启后,LL 包承载能力变大,MTU 才能真正跑满。
4. MTU 超过 255 必须改变量类型
MTU > 255 时,原来的uint8_t存不下,会溢出截断。需要把缓存 / 长度变量类型从:
uint8_t
改成:
uint16_t
否则 MTU 设 500、1000 都会异常。
5. 完整可落地修改步骤(照做必通)
- 打开配置文件 xxx_config.h
- 设置
MAX_ATT_MTU_CONF为目标值(如 500) - 开启宏
CONTROLLER_DATA_LENGTH_EXTENSION_ENABLED - 把 MTU 相关变量改为 uint16_t
- 实现回调
aci_att_exchange_mtu_resp_event查看最终 MTU - 若主机不主动协商,调用
aci_gatt_clt_exchange_config触发
6. 怎么验证是否修改成功
- 使能 DEBUG 日志,连接后看打印
- iOS(LightBlue)会自动协商 MTU,最适合测试
- 安卓部分机型不会主动发起,需外设触发
7. 必须注意的资源问题
- MTU 越大,协议栈占用RAM 越多
- BlueNRG-LP 在编译期根据 MTU 分配内存
- 不要盲目设最大,够用即可
- 最大建议:512 或 1018
8. 总结(最精简结论)
- 改 MTU = 改
MAX_ATT_MTU_CONF - 上 200 + 必须开 DLE
- 超 255 必须用 uint16_t
- 最终 MTU = 手机与外设较小值
- 用日志或
aci_att_exchange_mtu_resp_event确认结果
按 LAT1321 笔记这套流程,BlueNRG 系列改 MTU 不会再踩坑。
阅读全文
271