一、MTU、UUID、GATTS1. MTU数据包大小MTU在 BLE 中特指ATT_MTUAttribute Protocol Maximum Transmission Unit即属性协议层允许的最大数据包大小。默认值23 字节其中 3 字节用于 ATT 头部实际有效负载为 20 字节。作用MTU 越大单次传输的数据量越大可减少通信次数提升吞吐量。如果NRF_SDH_BLE_GATT_MAX_MTU_SIZE不是默认的 23则通过sd_ble_cfg_set配置 MTU 大小。配置后协议栈会在连接建立时协商该 MTU 值。2. UUID通用唯一标识符UUID用于唯一标识 BLE 中的服务Service、特征Characteristic、描述符Descriptor等。16 位 UUID由蓝牙 SIG 定义的标准 UUID如0x180F电池服务、0x2A19电池电量。协议栈内部已内置无需额外配置。128 位 UUID厂商自定义的 UUID需要协议栈为其分配存储空间。这里配置的是自定义 128 位 UUID 的数量vs_uuid_count协议栈据此预留内存。如果实际使用的自定义 UUID 超过此值初始化会失败。3. GATTS通用属性服务 – 服务器端GATTS是 GATT通用属性协议的服务器角色负责存储属性表Attribute Table并响应客户端的读写请求。属性表Attribute Table包含所有服务、特征、描述符等定义每个属性有句柄、UUID、权限等。服务改变特性Service Changed一个特殊特性当服务器的属性表发生变化时如动态添加服务通过此特性通知客户端重新发现服务。attr_tab_size属性表的最大字节数需要根据服务数量、特征数量及描述符数量计算配置过小会导致添加服务时失败。service_changed若为 1则协议栈会为 GATT 服务自动添加 Service Changed 特性若为 0则不添加通常仅在支持动态服务更新的设备中启用。二、服务与任务的区别1. 把 BLE 设备想象成一个工具箱服务 工具箱里的功能抽屉比如一个抽屉上贴着“电池信息”另一个抽屉上贴着“设备信息”。每个抽屉里放着一些具体的工具就是“特征”。抽屉本身只是告诉你“这里面是电池相关的信息”它自己不干活只是一个归类。任务线程 使用这些抽屉的工人工人负责去抽屉里拿工具、放工具、按按钮。比如手机要读电池电量工人就去“电池信息”抽屉里把“电池电量”这个工具上的数值拿出来发给手机。工人是真正干活的人有他独立的动作流程。2. 具体到代码层面服务你通过调用sd_ble_gatts_service_add()这样的函数在协议栈里“注册”一个服务给它一个 UUID。注册完成后协议栈内部会为这个服务分配一个句柄handle并把它放进属性表里。服务本身在内存里只是一个数据结构它不会自动运行任何代码。它只是描述“我这里有这个功能”。任务你在 RTOS 中创建一个任务例如用app_timer_create或 FreeRTOS 的xTaskCreate这个任务会主动运行比如轮询队列、处理蓝牙事件、调用 BLE 协议栈的 API 去读写数据。任务是执行流它决定了什么时候去访问服务、怎么处理数据。