本指南总结项目中实际使用的 Zephyr SDK API按功能分类给出原型、使用场景、注意事项和典型代码片段助您快速开发类似的多连接 BLE 中央设备应用。一、蓝牙地址与 UUID 工具1.bt_addr_le_to_strvoid bt_addr_le_to_str(const bt_addr_le_t *addr, char *str, size_t len);功能将 LE 蓝牙地址转为可读字符串XX:XX:XX:XX:XX:XX。项目场景日志打印、地址比较转为字符串后用strstr匹配用户输入的 MAC。注意确保str缓冲区至少BT_ADDR_LE_STR_LEN大小。2.bt_addr_le_from_strint bt_addr_le_from_str(const char *str, uint8_t type, bt_addr_le_t *addr);功能从字符串解析地址存入bt_addr_le_t。项目场景ble_set_wifi_hub中解析手机下发的 MAC 地址并保存到 Flash。注意type通常为BT_ADDR_LE_PUBLIC或BT_ADDR_LE_RANDOM。3.bt_addr_le_cmp/bt_addr_eq功能比较两个地址是否相等cmp全比较eq只比较a部分。项目场景get_device_info_by_addr用cmp识别设备扫描回调中用eq匹配已存 Hub。4.bt_uuid_cmp/bt_uuid_to_str功能比较 UUID 或转为字符串。项目场景在服务/特征查找、日志调试中频繁使用。二、连接管理bt_conn5.bt_conn_le_createint bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_param *create_param, const struct bt_le_conn_param *conn_param, struct bt_conn **conn);功能发起 LE 连接请求。项目场景ble_central_connect和重连逻辑中调用。参数通常使用BT_CONN_LE_CREATE_CONN和BT_LE_CONN_PARAM_DEFAULT。注意返回的conn需在回调中bt_conn_ref连接完成后bt_conn_unref。6.bt_conn_disconnectint bt_conn_disconnect(struct bt_conn *conn, uint8_t reason);功能主动断开连接。项目场景用户断开、超时处理、错误恢复。常用 reasonBT_HCI_ERR_REMOTE_USER_TERM_CONN用户主动、BT_HCI_ERR_CONN_TIMEOUT。7.bt_conn_ref/bt_conn_unref功能增加/减少连接引用计数防止对象在回调中被释放。项目场景在connected_cb中ref在disconnected_cb和ble_central_disconnect中unref。8.bt_conn_get_dstconst bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn);功能获取连接的对端地址。项目场景在连接/断开回调中获取地址用于日志和匹配。9.bt_conn_cb_registervoid bt_conn_cb_register(struct bt_conn_cb *cb);功能注册全局连接状态回调connected/disconnected。项目场景在ble_central_init中注册接收所有连接事件。三、GATT 服务发现10.bt_gatt_discoverint bt_gatt_discover(struct bt_conn *conn, struct bt_gatt_discover_params *params);功能发现服务、特征或描述符。项目场景级联调用——先发现主服务BT_GATT_DISCOVER_PRIMARY再在服务范围内发现特征BT_GATT_DISCOVER_CHARACTERISTIC最后发现描述符BT_GATT_DISCOVER_DESCRIPTOR。params指定起始/结束句柄、回调函数func。注意回调返回BT_GATT_ITER_STOP结束发现attr为NULL表示完成。四、GATT 数据读写与通知11.bt_gatt_write/bt_gatt_write_without_responseint bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params); int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, const void *data, uint16_t length, bool sign);功能写入特征值带响应需 ACK或无响应。项目场景ble_central_write_characteristic根据response参数选择。项目中使用无响应false以减少开销。注意无响应写入有长度限制通常 MTU-3。12.bt_gatt_readint bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params);功能读取特征值结果通过params-func回调返回。项目场景ble_central_read_characteristic中实现并使用k_yield等待回调完成。13.bt_gatt_subscribe/bt_gatt_unsubscribeint bt_gatt_subscribe(struct bt_conn *conn, struct bt_gatt_subscribe_params *params); int bt_gatt_unsubscribe(struct bt_conn *conn, struct bt_gatt_subscribe_params *params);功能订阅/取消订阅通知或指示。项目场景在服务发现完成后自动为支持NOTIFY的特征启用通知。params需指定value_handle、ccc_handle、valueBT_GATT_CCC_NOTIFY或BT_GATT_CCC_INDICATE、notify回调。14.bt_gatt_exchange_mtuint bt_gatt_exchange_mtu(struct bt_conn *conn, struct bt_gatt_exchange_params *params);功能协商 MTU 大小提高传输效率。项目场景连接成功后调用项目期望 MTU 提升至 512 字节。五、扫描控制15.bt_le_scan_start/bt_le_scan_stopint bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb); int bt_le_scan_stop(void);功能启动/停止 BLE 扫描。项目场景ble_central_start_scan/ble_central_stop_scan封装。参数BT_LE_SCAN_TYPE_ACTIVE快速间隔/窗口。六、内核同步原语16.K_MUTEX_DEFINE/k_mutex_init/k_mutex_lock/k_mutex_unlock功能互斥锁保护共享资源。项目场景dev_mutex保护设备数组app.mutex保护长数据发送过程防止并发写 GATT。注意锁定时间应尽可能短避免阻塞高优先级任务。17.k_sem信号量K_SEM_DEFINE(sem, 1, 1); k_sem_take(sem, K_FOREVER); k_sem_give(sem);功能用于同步和资源计数。项目场景conn_sem保护连接队列操作避免多个任务同时修改队列。18.k_msgq消息队列k_msgq_init(q, buffer, msg_size, max_msgs); k_msgq_put(q, msg, timeout); k_msgq_get(q, msg, timeout);功能线程间安全传递消息。项目场景BLE 回调中断/线程上下文将接收数据放入队列主线程取出处理实现生产-消费模型。七、内核工作队列延时工作项19.k_work_init_delayable/k_work_schedule/k_work_cancel_delayablevoid k_work_init_delayable(struct k_work_delayable *dwork, k_work_handler_t handler); int k_work_schedule(struct k_work_delayable *dwork, k_timeout_t delay); bool k_work_cancel_delayable(struct k_work_delayable *dwork);功能调度可延时的函数执行常用于超时和重试。项目场景连接超时10 秒后触发断开自动重连失败后延时 1 秒重试。注意工作项运行在系统工作队列线程中不能长时间阻塞。20.k_work_delayable_from_workCONTAINER_OF功能在工作回调中获取所属结构体。项目场景connect_timeout_handler中通过CONTAINER_OF获取设备对象便于操作。八、时间与延时21.k_sleep/k_yieldk_sleep使当前线程睡眠指定时间常用于轮询间隔如分包发送间隔 4ms。k_yield主动让出 CPU用于等待异步操作完成如读取等待。在嵌入式实时系统中延时操作有两种截然不同的实现方式阻塞型延时如k_sleep和非阻塞型延时工作项k_work_delayable。22.k_uptime_get_32功能获取系统运行毫秒数32 位约 49 天溢出。项目场景长数据发送超时保护若超过 10 秒未完成则报错超过 30 秒复位。九、日志与调试23.LOG_MODULE_REGISTER/LOG_INF/LOG_ERR等功能日志输出支持模块名和级别过滤。项目场景记录关键状态和错误。注意项目中将日志宏重定义为printk以提高可靠性但标准用法建议使用LOG_*。24.printk功能内核级打印不依赖日志子系统。项目场景Shell 输出和扫描结果打印确保实时显示。十、内存分配25.k_malloc/k_free功能动态内存分配支持K_FOREVER等待但项目未使用。项目场景分配消息队列缓冲区和大数据重组缓冲区。十一、原子操作26.ATOMIC_DEFINE/atomic_cas/atomic_clear功能原子变量操作用于无锁标志。项目场景discovery_in_progress防止服务发现重入。开发建议与最佳实践连接状态机使用connectingconnected 延时工作项实现非阻塞超时和重连。GATT 发现采用链式回调逐步发现服务→特征→描述符并在完成后自动启用通知。数据接收使用消息队列从回调上下文传递到线程避免阻塞蓝牙堆栈。并发保护所有对共享设备数组的访问必须加mutex写 GATT 时也用mutex防止并发写。资源释放连接断开时务必bt_conn_unref并清理缓存的 GATT 信息。超时策略连接、读取、写入都应有超时机制防止永久阻塞。内存管理预分配静态结构如设备数组、消息队列避免运行时动态分配失败。常用宏与常量宏/常量用途BT_ADDR_LE_STR_LEN地址字符串长度BT_UUID_STR_LENUUID 字符串长度BT_ATT_FIRST_ATTRIBUTE_HANDLE/BT_ATT_LAST_ATTRIBUTE_HANDLE服务发现范围BT_GATT_CHRC_NOTIFY/BT_GATT_CHRC_INDICATE特征属性掩码BT_GATT_CCC_NOTIFY/BT_GATT_CCC_INDICATE订阅值K_FOREVER/K_NO_WAIT/K_MSEC()/K_SECONDS()超时参数BT_HCI_ERR_*HCI 错误码用于断开原因k_work_schedule在 Zephyr 中用于延迟执行一个函数其功能在 FreeRTOS 中主要由软件定时器Software Timers实现。两者在核心思想上完全一致都是将一个任务函数的执⾏从当前上下⽂中剥离交给⼀个专门的后台任务在指定的未来时间点运⾏。核心概念对比功能特性Zephyr (k_work_schedule)FreeRTOS (软件定时器)核心思想延迟执行一个“工作项”延迟执行一个“回调函数”执行上下文系统工作队列一个后台线程定时器服务任务一个后台守护任务一次性执行支持调度一次执行一次支持创建为“一次性定时器”周期性执行不支持需在回调中再次调用k_work_schedule支持创建为“自动重载定时器”取消执行k_work_cancel_delayable()xTimerStop()调用上下文允许在中断服务程序ISR中调用提供专用于中断的 API如xTimerStartFromISR关键APIk_work_init_delayable(),k_work_schedule()xTimerCreate(),xTimerStart()本指南聚焦于项目实战希望帮助您快速上手 Zephyr BLE 开发。如需查阅函数详细参数请参考 Zephyr 官方文档。祝开发顺利