目錄
概述
1 函數接口
2 主要函數介紹
2.1 bt_le_adv_start函數
2.1.1 函數功能介紹
2.1.2?典型使用示例
2.1.3 廣播間隔
2.1.4?注意事項
2.2?bt_le_adv_stop 函數
2.2.1??函數功能
?2.2.2 使用方法介紹
2.2.3?實際應用示例
2.2.4?關鍵注意事項
?2.2.5?常見問題解決
2.2.6?應用總結?
2.3?bt_enable
2.3.1 函數功能
?2.3.2?典型使用模式
2.3.3?關鍵處理流程
?2.3.4?注意事項
?2.3.5?初始化失敗常見原因
2.3.6??實際應用示例
2.3.7 應用總結
2.4?bt_le_adv_update_data函數
2.4.1 函數功能
?2.4.2?典型使用場景
2.4.3?關鍵特性
?2.4.4?實現原理
2.4.5?注意事項
?2.4.6?錯誤處理最佳實踐
2.4.7?典型應用案例
2.4.8 應用總結
概述
本文主要介紹zephyr架構下Bluetooth advertising一些接口函數的功能和使用方法,這些函數是bluetooth的最重要的一些接口,掌握這些函數的用法是進行藍牙功能開發的基礎。
1 函數接口
基于zephyr OS架構下實現Bluetooth advertising功能其使用的函數接口有如下這些
函數名稱 | 功能 | 說明 |
bt_le_adv_start | 實現廣播功能 | BLE模塊被使能后,啟用該函數進行廣播,可通過設置不同的參數,實現不同的廣播方式 |
bt_enable | 使能BLE | 使能BLE的功能,該函數 |
bt_le_adv_stop | 停止廣播 | 關閉廣播功能,下次要重新廣播時,需要調用bt_le_adv_start |
bt_le_adv_update_data | 更新廣播數據 |
2 主要函數介紹
2.1 bt_le_adv_start函數
2.1.1 函數功能介紹
bt_le_adv_start
?是藍牙低功耗 (BLE) 協議棧中的一個關鍵 API 函數,用于啟動設備的廣播(Advertising)功能。這個函數允許 BLE 設備(Peripheral 角色)向周圍設備廣播自己的存在,并攜帶相關信息。bt_le_adv_start
?是 BLE 設備廣播功能的核心 API,合理配置廣播參數和數據可以優化設備發現性、連接速度和功耗表現。開發者需要根據具體應用場景(如 Beacon、可連接外設等)選擇合適的廣播模式和數據結構。
1)功能概述
作用:啟動 BLE 設備的廣播功能
適用角色:Peripheral(外設)或 Broadcaster(廣播者)
廣播模式:可配置為可連接廣播、不可連接廣播、可掃描廣播等
廣播數據:可攜帶設備名稱、服務 UUID、廠商數據等
2)函數原型:
int bt_le_adv_start(const struct bt_le_adv_param *param,const struct bt_data *ad,size_t ad_len,const struct bt_data *sd,size_t sd_len);
3)參數說明
參數 | 類型 | 說明 |
---|---|---|
param | bt_le_adv_param* | 廣播參數配置(廣播類型、間隔等) |
ad | bt_data* | 廣播數據(Advertising Data) |
ad_len | size_t | 廣播數據項數量 |
sd | bt_data* | 掃描響應數據(Scan Response Data) |
sd_len | size_t | 掃描響應數據項數量 |
4)廣播參數配置(bt_le_adv_param)
struct bt_le_adv_param {uint8_t id; // 廣播集 IDuint32_t options; // 廣播選項(如 BT_LE_ADV_OPT_CONNECTABLE)uint16_t interval_min; // 最小廣播間隔(單位:0.625ms)uint16_t interval_max; // 最大廣播間隔(單位:0.625ms)uint8_t peer[6]; // 定向廣播的目標地址(可選)
};
常用廣播選項(options)
BT_LE_ADV_OPT_CONNECTABLE
?- 可連接廣播
BT_LE_ADV_OPT_USE_NAME
?- 在廣播中包含設備名稱
BT_LE_ADV_OPT_SCANNABLE
?- 允許掃描響應
BT_LE_ADV_OPT_ONE_TIME
?- 僅廣播一次
?5)廣播數據類型(bt_data)
struct bt_data {uint8_t type; // 數據類型(如 BT_DATA_NAME_COMPLETE)uint8_t data_len;const uint8_t *data;
};
2.1.2?典型使用示例
1)1. 基本可連接廣播
static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};static const struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_USE_NAME,BT_GAP_ADV_FAST_INT_MIN_1,BT_GAP_ADV_FAST_INT_MAX_1,NULL
);bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
2)不可連接廣播(Beacon 模式)
static const uint8_t beacon_data[] = {0x01, 0x02, 0x03, 0x04, // 廠商特定數據
};static const struct bt_data ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NONCONN_IND),BT_DATA(BT_DATA_MANUFACTURER_DATA, beacon_data, sizeof(beacon_data)),
};bt_le_adv_start(BT_LE_ADV_NCONN, ad, ARRAY_SIZE(ad), NULL, 0);
2.1.3 廣播間隔
BLE 廣播間隔以?0.625ms?為單位:
-
快速廣播:20ms - 60ms(
BT_GAP_ADV_FAST_INT_MIN_1
?= 32 = 20ms) -
慢速廣播:100ms - 150ms(
BT_GAP_ADV_SLOW_INT_MIN
?= 160 = 100ms)
返回值
-
0
:廣播啟動成功 -
負值:錯誤碼(如?
-EINVAL
?參數錯誤,-ENOMEM
?內存不足)
2.1.4?注意事項
廣播數據總長度不能超過?31 字節
掃描響應數據也受 31 字節限制
廣播間隔影響功耗和可發現性
某些廣播模式(如定向廣播)有額外限制
2.2?bt_le_adv_stop 函數
2.2.1??函數功能
bt_le_adv_stop
?是藍牙低功耗 (BLE) 協議棧中的一個關鍵 API 函數,用于停止正在進行的廣播。它通常與?bt_le_adv_start
?配對使用,用于控制 BLE 設備的廣播生命周期。
1)核心功能
停止廣播:立即終止當前正在進行的 BLE 廣播
釋放資源:釋放與廣播相關的協議棧資源
配合廣播控制:通常用于動態廣播管理場景
?2)函數原型(基于 Zephyr BLE 協議棧)
int bt_le_adv_stop(void);
參數
-
無參數:直接停止當前活躍的廣播
返回值
返回值 | 說明 |
---|---|
0 | 停止廣播成功 |
-EALREADY | 當前沒有活躍的廣播 |
其他負值 | 其他錯誤(如協議棧錯誤) |
?2.2.2 使用方法介紹
1)?基本啟停控制
// 啟動廣播
bt_le_adv_start(...);// 一段時間后停止廣播
bt_le_adv_stop();
2)條件性停止廣播
if (need_to_stop_advertising) {int err = bt_le_adv_stop();if (err) {printk("Stop failed (err %d)\n", err);}
}
3)?廣播模式切換
// 先停止當前廣播
bt_le_adv_stop();// 更換參數后重新啟動
bt_le_adv_start(new_params, ...);
2.2.3?實際應用示例
場景:溫度傳感器按需廣播
void start_temp_advertising(void) {bt_le_adv_start(..., temp_ad_data, ...);
}void stop_advertising_when_connected(void) {// 當連接建立時自動停止廣播// 或手動調用:bt_le_adv_stop();
}void on_button_press(void) {// 按鈕按下時重新廣播bt_le_adv_stop(); // 先確保停止start_temp_advertising();
}
2.2.4?關鍵注意事項
無廣播時的調用
如果沒有活躍的廣播,調用會返回?-EALREADY
(非致命錯誤)線程安全性
建議在協議棧線程(如 Zephyr 的 Bluetooth 線程)上下文中調用與連接的交互
如果設備已通過廣播建立連接,廣播會自動停止,此時調用會返回?-EALREADY
低功耗場景
停止廣播會顯著降低功耗(廣播是功耗主要來源之一)廣播集支持
在支持多廣播集的協議棧中(如 Zephyr 2.7+),可能需要指定廣播集 ID
?2.2.5?常見問題解決
Q1:停止廣播后為什么設備仍可被掃描到?
A1:可能是其他廣播實例仍在運行,或廣播停止有延遲(檢查返回值)
Q2:如何確保廣播完全停止?
A2:
do {err = bt_le_adv_stop();
} while (err == 0); // 直到返回-EALREADY
Q3:停止廣播會影響已建立的連接嗎?
A3:不會,只影響廣播行為,不影響現有連接
2.2.6?應用總結?
bt_le_adv_stop
?是 BLE 設備廣播管理的核心控制點,合理使用可以實現:
精確的廣播生命周期控制
動態廣播策略切換
有效的功耗管理
在需要頻繁切換廣播模式或優化功耗的場景中,正確使用該API至關重要。
2.3?bt_enable
2.3.1 函數功能
bt_enable
?是藍牙協議棧中的核心初始化函數,用于啟用和初始化藍牙控制器及協議棧。它是任何藍牙應用程序的第一個關鍵調用,為后續所有藍牙操作建立基礎環境。
函數原型(基于Zephyr等常見協議棧)
int bt_enable(bt_ready_cb_t cb);
參數說明
參數 | 類型 | 說明 |
---|---|---|
cb | bt_ready_cb_t | 藍牙初始化完成后的回調函數(可設為NULL) |
?回調函數類型定義:
typedef void (*bt_ready_cb_t)(int err);
核心功能
硬件初始化
初始化藍牙射頻控制器(Radio)
配置底層硬件(如時鐘、電源等)
協議棧加載
加載HCI層、L2CAP、ATT/GATT等協議棧組件
初始化安全管理器(SM)
默認配置應用
設置默認藍牙MAC地址
應用編譯時配置的默認參數
狀態切換
將藍牙控制器從OFF狀態切換到READY狀態
返回值
返回值 | 說明 |
---|---|
0 | 初始化流程成功啟動(注意:實際結果通過回調返回) |
-EALREADY | 藍牙協議棧已啟用 |
-ENOMEM | 內存不足 |
-EIO | 硬件初始化失敗 |
?2.3.2?典型使用模式
1)?同步初始化(無回調)
int err = bt_enable(NULL);
if (err) {printk("Bluetooth init failed (err %d)\n", err);return;
}
// 繼續其他藍牙操作
2)異步初始化(帶回調)
void bt_ready(int err) {if (err) {printk("Bluetooth init failed (err %d)\n", err);return;}printk("Bluetooth initialized\n");// 在這里啟動廣播/掃描等操作
}void main(void) {int err = bt_enable(bt_ready);if (err) {printk("Bluetooth enable failed (err %d)\n", err);}
}
2.3.3?關鍵處理流程
?2.3.4?注意事項
單次調用限制
多數實現要求全局只調用一次
重復調用需先調用
bt_disable()
回調上下文
回調函數通常在藍牙線程執行
避免在回調中進行阻塞操作
依賴關系
必須在所有其他藍牙API前調用
通常應在系統初始化完成后調用
調試支持
可通過
CONFIG_BT_DEBUG
等選項啟用調試日志
?2.3.5?初始化失敗常見原因
硬件問題
藍牙芯片未正確供電
射頻電路故障
配置沖突
與其他無線服務(如WiFi)共用資源
錯誤的時鐘配置
資源不足
內存池大小不足(檢查
CONFIG_BT_*_TX_COUNT
等配置)中斷沖突
2.3.6??實際應用示例
1)?簡單外設初始化
void main(void)
{bt_enable(NULL); // 同步初始化bt_le_adv_start(...); // 立即開始廣播
}
2)帶錯誤恢復的初始化
void bt_retry_init(int err)
{if (err) {k_sleep(K_SECONDS(1));bt_enable(bt_retry_init); // 重試初始化}
}void main(void)
{bt_enable(bt_retry_init);
}
2.3.7 應用總結
bt_enable
?是藍牙開發的第一個關鍵調用,其核心價值在于:
-
建立藍牙操作的基礎環境
-
提供同步/異步兩種初始化模式
-
協調硬件和協議棧的啟動
正確使用該API需要注意:
-
調用時機(早于其他藍牙操作)
-
錯誤處理機制
-
特定協議棧的特殊要求
在復雜應用中,建議使用異步回調模式,以便在初始化完成后自動執行后續藍牙操作流程。
2.4?bt_le_adv_update_data函數
2.4.1 函數功能
bt_le_adv_update_data
?是藍牙低功耗 (BLE) 協議棧中的一個關鍵 API 函數,用于動態更新正在進行的廣播數據或掃描響應數據,而無需停止并重新啟動廣播。
核心功能
動態更新廣播數據:修改廣播包(Advertising Data)或掃描響應包(Scan Response Data)內容
無需重啟廣播:保持廣播持續進行,避免廣播中斷導致的設備不可見期
實時數據刷新:適用于需要頻繁更新廣播信息的場景(如傳感器數據變化)
?函數原型(基于Zephyr等常見協議棧)
int bt_le_adv_update_data(const struct bt_data *ad, size_t ad_len,const struct bt_data *sd,size_t sd_len);
參數說明
參數 | 類型 | 說明 |
---|---|---|
ad | bt_data* | 新的廣播數據數組 |
ad_len | size_t | 廣播數據項數量 |
sd | bt_data* | 新的掃描響應數據數組 |
sd_len | size_t | 掃描響應數據項數量 |
返回值
返回值 | 說明 |
---|---|
0 | 數據更新成功 |
-EINVAL | 參數無效(如數據長度超限) |
-ENOMEM | 內存不足 |
-EAGAIN | 協議棧繁忙,需重試 |
-ENOTCONN | 當前未進行廣播 |
?2.4.2?典型使用場景
1)?傳感器數據實時更新
// 初始廣播
bt_le_adv_start(..., initial_ad, ...);// 當溫度變化時更新數據
void update_temp_data(float new_temp)
{uint8_t temp_encoded = (uint8_t)(new_temp * 2);struct bt_data new_ad[] = {BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL),BT_DATA(BT_DATA_MANUFACTURER_DATA, &temp_encoded, 1)};bt_le_adv_update_data(new_ad, ARRAY_SIZE(new_ad), NULL, 0);
}
2)?動態切換廣播模式
// 從普通廣播切換到信標模式
struct bt_data beacon_ad[] =
{BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NONCONN_IND),BT_DATA(BT_DATA_MANUFACTURER_DATA, beacon_payload, sizeof(beacon_payload))
};bt_le_adv_update_data(beacon_ad, ARRAY_SIZE(beacon_ad), NULL, 0);
2.4.3?關鍵特性
原子性更新
1)數據更新在單個廣播間隔內完 ;
?2)接收端不會看到部分更新的數據
廣播連續
1)保持現有廣播間隔不變;
2)避免傳統"停止-修改-重啟"方式導致的 ~300ms 廣播中斷
數據限制
1)仍需遵守31字節的廣播數據長度限制;?
2)數據類型需符合藍牙規范(不能動態修改AD Type)
?2.4.4?實現原理
2.4.5?注意事項
廣播必須處于活躍狀態
1)需在bt_le_adv_start之后調用
2)已連接的設備會自動停止廣播
數據一致性
1)更新期間應避免修改原始數據緩沖區
2)建議使用靜態或全局數據數組
性能考量
1)頻繁更新(如每秒多次)可能影響射頻穩定性
2)建議合并更新(如每200ms批量更新一次)
廠商限制
1)某些低端藍牙芯片可能不支持實時更新
2)需要檢查協議棧實現是否支持該功能
?2.4.6?錯誤處理最佳實踐
int err = bt_le_adv_update_data(new_ad, ad_len, NULL, 0);
if (err == -ENOTCONN)
{// 廣播未激活,重新啟動bt_le_adv_start(...);
}
else if (err){printk("Update failed (err %d), retrying...\n", err);k_sleep(K_MSEC(100));// 重試邏輯}
2.4.7?典型應用案例
電子價簽系統
不建立連接,通過廣播更新價格信息
每15分鐘更新一次廣播數據
運動傳感器
實時廣播心率/步數變化
保持低功耗的同時更新數據
智能信標
動態調整廣播內容(如店鋪促銷信息)
基于位置切換廣播UUID
2.4.8 應用總結
bt_le_adv_update_data
?提供了高效的廣播數據動態更新機制,特別適合:
需要保持持續廣播可見性的場景
實時數據傳輸但無需建立連接的用例
低功耗設備的數據更新需求
正確使用該API可以避免傳統重啟廣播方式帶來的連接中斷風險,同時保證數據更新的實時性和可靠性。開發者應注意目標平臺的協議棧實現差異,并進行充分的錯誤場景測試。