議棧全解析)
在調(diào)試 NUCLEO-WB55 USBDongle 時上電不廣播這個問題我前前后后碰到過三次。每次原因都不一樣一次是出廠固件里壓根沒燒 BLE 程序一次是 SWD 引腳被代碼占用了導(dǎo)致燒錄失敗還有一次是 USB 供電電流不夠Dongle 插上去之后射頻部分根本沒起來。這篇文章就把這三類問題、排查過程和最終解決辦法一次性講清楚給正在被這個不廣播搞得頭疼的朋友一條完整的排障路線。NUCLEO-WB55 USBDongle 是 ST 推出的基于 STM32WB55RG 的 USB 樣式開發(fā)板官方定位是配合 BLE 調(diào)試工具做演示和抓包但在實際項目中很多人拿它做自定義 Beacon、透傳網(wǎng)關(guān)、甚至 OTA 測試工具。它的核心是雙核 MCUCortex-M4 負(fù)責(zé)應(yīng)用Cortex-M0 只跑藍(lán)牙協(xié)議棧相當(dāng)于一個獨立協(xié)處理器所以 BLE 協(xié)議棧運行和應(yīng)用邏輯是隔離的。這既是它的優(yōu)勢也是很多人調(diào)試時懵圈的地方——你在 M4 上寫的代碼未必能把廣播跑起來因為廣播服務(wù)的真正調(diào)度在 M0 那邊。提示標(biāo)題里的advertizing是 advertising 的常見拼寫錯誤搜索引擎里這個拼法搜出來的討論反而不少。不過不影響下面所有內(nèi)容圍繞BLE 廣播不工作來展開。1. 先搞清楚硬件和固件的匹配關(guān)系1.1 NUCLEO-WB55 USBDongle 到底是個什么板子STM32WB55RG 是一個雙核無線 MCU主核 Cortex-M4 跑應(yīng)用代碼協(xié)同核 Cortex-M0 運行 ST 預(yù)編譯好的藍(lán)牙協(xié)議棧二進(jìn)制文件稱為 FUS / BLE Stack 固件。NUCLEO-WB55 USBDongle 只是把這塊芯片做成 USB Stick 形態(tài)板上引出了 USB-C 接口、RGB LED、兩個按鍵、SWD 調(diào)試接口和天線。它和常見的 NUCLEO-WB55RG 開發(fā)板最大的區(qū)別是Dongle 版本沒有板載 ST-LINK不能直接插 USB 線就調(diào)試必須外接一個 ST-LINK 或者借助另一塊 NUCLEO-WB55RG 板載的 ST-LINK 通過 SWD 來燒錄調(diào)試。很多朋友拿到 Dongle 的第一反應(yīng)是拿 USB 線插電腦然后打開手機(jī)藍(lán)牙搜設(shè)備結(jié)果什么都搜不到。這是正常的因為出廠固件默認(rèn)燒的是ST HID或者BLE Sensor相關(guān)的演示程序而且這取決于你買到的批次和出廠燒錄內(nèi)容。它不是一塊插上就能廣播 Beacon的板子。USB 枚舉成功只代表芯片的 USB 外設(shè)在跑不代表 BLE 射頻在上電后就啟動廣播了。USB Dongle 的板載天線是 PCB 天線走的是 2.4G 頻段官方標(biāo)稱輸出功率可以調(diào)到 6 dBm 左右。板子沒有電池供電電路必須靠 USB 口取電這也是后面供電問題的根源。調(diào)試時建議先看板子上的 LED默認(rèn)程序里 LED 會閃爍或常亮如果 LED 完全沒反應(yīng)先懷疑供電和枚舉問題如果 LED 正常但無廣播再往固件方向排查。1.2 默認(rèn)出廠固件不是 Beacon別指望上電就廣播為了確認(rèn)出廠固件內(nèi)容最直接的辦法是用 STM32CubeProgrammer 讀一下芯片的 Flash。連接好 ST-LINK 后打開 STM32CubeProgrammer選擇 ST-LINK 接口點擊 Connect。如果連接正常在 Memory 視圖里看一眼地址 0x08000000 開始的區(qū)域或者直接讀取 Option Bytes。值得注意的是Dongle 版本的 ST-LINK 連接方式不是板載虛擬串口而是 SWD 四線SWDIO、SWCLK、GND、3.3V。我建議第一次拿到 Dongle 的朋友不要急著寫自己的應(yīng)用先 STM32CubeProgrammer 全片擦除然后燒錄官方 BLE_Beacon 例程驗證射頻通路是否正常。這一步能隔離硬件壞了還是固件不對兩個問題。官方例程在 STM32CubeWB 固件包里Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_Beacon。需要注意的是BLE 協(xié)議棧固件stm32wb5x_BLE_Stack_full_fw.bin和用戶應(yīng)用固件是分開燒錄的FUSFirmware Upgrade Service固件也要提前燒好。出廠時芯片內(nèi)部一般已經(jīng)燒好了 FUS 和 BLE Stack但如果你執(zhí)行過全片擦除或者拿到了不帶協(xié)議棧的芯片就必須按順序重新燒錄先燒 FUS再燒 BLE Stack最后燒應(yīng)用。順序錯了M0 就起不了協(xié)議棧廣播自然跑不起來。具體的地址分配在 STM32CubeWB 包里的Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/BLE_Beacon/README.md寫得非常清楚。1.3 硬件供電和 USB 枚舉的坑USB Dongle 對供電品質(zhì)很敏感。它的射頻部分在廣播瞬間會有比較大的電流尖峰如果插在劣質(zhì) USB HUB 或老舊電腦的前置 USB 口上電壓跌落會導(dǎo)致 M0 協(xié)議棧異常復(fù)位表現(xiàn)就是偶爾廣播一下然后消失或者完全沒有廣播。我第三次遇到不廣播就是插在一個不帶外部供電的 USB 3.0 HUB 上。Dongle 的 LED 正常亮USB 枚舉也正常但手機(jī)始終搜不到。用萬用表量 USB 的 5V空載時 5.05V插上 Dongle 后瞬間跌到 4.72V射頻一開就掉到 4.5V 以下。換到電腦后置 USB 口或者帶供電的 HUB 后問題直接消失。所以排查順序里把供電放在前三位是必要的。另外提醒一點Dongle 的 USB-C 口不是所有線都能用。我遇到過一根只支持充電不支持?jǐn)?shù)據(jù)傳輸?shù)?USB-C 線導(dǎo)致 STM32CubeProgrammer 無法識別設(shè)備但 BLE 廣播其實正常。這時候用手機(jī)能看到廣播卻以為板子掛了。遇到怎么都連不上的情況先換一根確認(rèn)能傳數(shù)據(jù)的線。2. 固件燒錄這關(guān)過不去廣播就是空中樓閣2.1 燒錄用的是哪個工具鏈NUCLEO-WB55 USBDongle 沒有板載調(diào)試器燒錄前需要準(zhǔn)備一個 ST-LINK/V2 或者 ST-LINK/V3。我用的是 ST-LINK/V2 的克隆版某寶幾十塊那種配合 STM32CubeProgrammer 完全夠用。接線是標(biāo)準(zhǔn) SWD 四線SWDIO、SWCLK、GND、3.3V。板上 SWD 引腳是印在背面的注意看絲印別焊反。如果你手頭正好有一塊 NUCLEO-WB55RG 開發(fā)板也可以把它板載的 ST-LINK 當(dāng)作調(diào)試器給 Dongle 燒錄只需要把 NUCLEO 板上的 CN2 跳線帽拔掉斷開板載 ST-LINK 與目標(biāo) MCU 的 SWD 連接然后從 ST-LINK 輸出引腳飛線到 Dongle 的 SWD 引腳。這樣省一個調(diào)試器但操作麻煩一點我建議還是單獨買個 ST-LINK幾十塊錢節(jié)省大量時間。連接好之后打開 STM32CubeProgrammer選擇 ST-LINK 模式把 Mode 設(shè)為 Under reset 或者 Hot Plug一般 Hot Plug 就夠用。點擊 Connect 后軟件會讀出芯片型號 STM32WB55RG并在左下角顯示當(dāng)前保護(hù)級別Read Out Protection 應(yīng)該是 Level 0如果顯示 Level 1 會限制讀取和燒錄需要先解除保護(hù)。2.2 固件選擇官方示例 vs 自建工程官方固件包 STM32CubeWB 里針對 USBDongle 的 BLE 應(yīng)用主要放在Projects/P-NUCLEO-WB55.USBDongle/Applications/BLE/目錄下包含 BLE_Beacon、BLE_HeartRate、BLE_Throughput 等。BLE_Beacon 是最小的工程邏輯最簡單特別適合做驗證射頻通路這件事。如果你用的是 STM32CubeMX 自建工程注意選擇正確的 BoardP-NUCLEO-WB55.USBDongle。在 CubeMX 里如果不選對板子引腳分配、射頻匹配、天線開關(guān)控制這些配置就會對不上。STM32WB55 需要外部 32MHz 晶振HSE32作為射頻參考時鐘CubeMX 生成的時鐘樹如果配置錯了BLE 協(xié)議棧初始化會直接卡在hci_init()或者干脆不廣播。官方案例工程不需要手動配置時鐘因為工程文件里已經(jīng)寫好了。這也是我建議新手先用官方案例跑通再改自己工程的原因。如果你用的不是 STM32CubeWB 里的工程而是網(wǎng)上找的第三方模板一定要核對三個關(guān)鍵點協(xié)議棧地址、FUS 地址和應(yīng)用起始地址。這三個地址只要錯一個下載后大概率是程序跑飛或協(xié)議棧起不來。ST 官方工程里這些地址是通過鏈接腳本預(yù)置好的不熟悉的朋友不要自己亂改。2.3 燒錄后復(fù)位和連接器的問題燒錄完成不是終點Dongle 需要斷電重新上電或者按一下板上的復(fù)位按鈕如果有才能正常進(jìn)入廣播狀態(tài)。很多人燒完固件后不手動復(fù)位以為程序會自動運行結(jié)果一直沒廣播。實際上 STM32CubeProgrammer 燒錄完成后默認(rèn)會復(fù)位并運行但如果你用的是第三方燒錄工具不一定有這個行為手動斷電重插一次最穩(wěn)。另外一個容易踩的坑是 SWD 引腳被復(fù)用了。有些 BLE 應(yīng)用會把 PB3、PB4、PA15 這些 SWD 相關(guān)引腳配置成 GPIO 或者射頻控制腳一旦代碼運行調(diào)試接口就被切斷了。這會導(dǎo)致你燒錄完第一次程序后第二次再也連不上 ST-LINK。解決辦法是燒錄時把 BOOT0 拉高讓芯片從系統(tǒng)存儲器啟動先中斷用戶程序然后用 STM32CubeProgrammer 重新連接并擦除 Flash。但我實際操作下來STM32WB55 的 BOOT0 引腳拉高有講究Dongle 板上沒有專門引出來得飛線。更省事的辦法是使用 STM32CubeProgrammer 的 Connect under reset 模式把復(fù)位引腳也接上在復(fù)位釋放的瞬間拉低 SWD 請求成功率更高。SWD 連接不上是一個高頻問題。如果你確認(rèn)接線正確、驅(qū)動正常但 STM32CubeProgrammer 始終報 No ST-LINK detected 或 Target connection failed優(yōu)先檢查 Option Bytes 里的 RDP 級別。我之前買過一批二手 Dongle里面 RDP 被設(shè)置成了 Level 1直接導(dǎo)致無法連接必須先用 STM32CubeProgrammer 的 Remove protection 功能解除。注意解除保護(hù)會全片擦除之后需要重新燒錄 FUS 和 BLE Stack。3. 從 Beacon 示例開始一步一步讓 Dongle 廣播起來3.1 打開官方 Beacon 例程改參數(shù)前先理解參數(shù)STM32CubeWB 的 BLE_Beacon 例程位置我上面已經(jīng)給了用 IAR、Keil 或者 STM32CubeIDE 打開都可以。我自己主要用 STM32CubeIDE開箱即用不需要額外配置工程鏈。打開之后先不要編譯先在app_conf.h和hci_tl.h里確認(rèn)協(xié)議棧相關(guān)配置再看app_ble.c。BLE_Beacon 例程的核心就是adv_data[]這個數(shù)組它定義了廣播數(shù)據(jù)的內(nèi)容。例程默認(rèn)發(fā)的是一個簡單的自定義 Beacon廣播間隔默認(rèn)參數(shù)通常是ADV_INTERVAL_MIN_MS和ADV_INTERVAL_MAX_MS單位換算成 BLE 的時間單位是 0.625ms。官方默認(rèn)值看兩個宏但最終的值會被aci_gap_set_discoverable()這個 HCI 命令的Advertising_Interval_Min、Advertising_Interval_Max參數(shù)覆蓋。有一點很多新手會搞錯BLE 廣播間隔不是一個固定數(shù)值而是一個區(qū)間實際廣播間隔由協(xié)議棧在這個區(qū)間內(nèi)隨機(jī)選取這是藍(lán)牙規(guī)范用來減少同頻干擾的機(jī)制。所以如果你配置的 min100ms、max100ms實際廣播串間隔也不會完全是 100.000ms而是在 100ms 附近抖動。用手機(jī) App 觀察時別因為每次廣播間隔有幾毫秒偏差就覺得有問題。廣播數(shù)據(jù)里除了用戶自定義的 Manufacturer Specific Data還有必要的 Flags 字段表示這個設(shè)備支持LE General Discoverable Mode。如果 Flags 缺失很多手機(jī) App 會直接過濾掉這個廣播包表現(xiàn)為設(shè)備可見但不顯示。所以自建廣播數(shù)據(jù)時Flags0x02 0x01 0x06這 3 個字節(jié)一定不要省。3.2 編譯燒錄和串口日志驗證BLE_Beacon 例程默認(rèn)不開串口日志但 NUCLEO-WB55 USBDongle 的虛擬串口是通過 ST-LINK 的 CDC 實現(xiàn)的Dongle 本身并沒有獨立的 USB-UART 橋接芯片。所以如果你用的是外接 ST-LINK它是沒有虛擬串口的你只能在 STM32CubeProgrammer 的 Serial Wire ViewerSWV里看 printf 輸出或者直接忽略日志靠 LED 狀態(tài)判斷。這個板子有一個 RGB LED在 BLE_Beacon 例程里如果廣播正常LED 會進(jìn)入一個周期閃爍狀態(tài)。具體顏色和頻率在app_ble.c里可以通過BUTTON_LED相關(guān) API 調(diào)整。我的判斷方法是如果上電后 RGB LED 有周期性閃爍說明 M4 應(yīng)用已經(jīng)跑起來了再配合手機(jī)端看到廣播包基本可以確認(rèn)整個鏈路沒問題。編譯燒錄這步要注意先用 STM32CubeProgrammer 確認(rèn) Flash 里已經(jīng)燒好了 BLE Stack。檢查方法是在 Memory 視圖里讀協(xié)議棧地址比如 0x08008000 或 0x08080000取決于工程配置如果全是 0xFF 說明協(xié)議棧沒燒進(jìn)去。BLE_Beacon 例程的鏈接腳本里定義了BLE_STACK_ADDRESS不同版本偏移不同所以直接用 .bin 燒的時候一定要按 README 里的偏移地址來。我犯過的錯誤是把 BLE_Stack 固件用默認(rèn) 0x08000000 地址燒進(jìn)去直接把應(yīng)用固件覆蓋了然后整板變磚重新燒了三次才搞對。3.3 用手機(jī)和抓包器確認(rèn)廣播包廣播跑沒跑起來最直觀的手段是手機(jī)。iOS 上推薦用 LightBlue 或 nRF ConnectAndroid 上我用的是 nRF Connect 和BLE 調(diào)試助手這類 App。打開 App 掃描如果看到廣播名比如ST Beacons或你自定義的設(shè)備名說明廣播已經(jīng)發(fā)出去了。但這只是第一步廣播包的內(nèi)容是否合法、功率是否達(dá)標(biāo)單靠手機(jī)看不詳細(xì)。深入排查時必須上抓包器。低成本方案是再拿一塊 NUCLEO-WB55 開發(fā)板刷成 BLE Sniffer配合 Wireshark 抓包。ST 官方提供了STM32WB BLE Sniffer工具用起來比 nRF Sniffer 稍微麻煩一點但配置無誤的話抓包結(jié)果很干凈。抓包主要看三點廣播事件是否周期性出現(xiàn)、廣播通道37/38/39是否都能抓到、RSSI 是否符合預(yù)期。如果只有單個通道出現(xiàn)廣播說明射頻鏈路有問題如果三個通道都有但 RSSI 極低優(yōu)先懷疑天線匹配或供電。手機(jī)能搜到廣播但 RSSI 顯示特別弱比如 -80 dBm 以下而且人靠近板子也只有 -60 左右這種一般不是軟件問題而是射頻硬件或天線問題。NUCLEO-WB55 USBDongle 的 PCB 天線區(qū)域務(wù)必保持干凈不要用手大面積握住天線部分也不要用 USB 延長線把 Dongle 懸在金屬桌面附近。金屬物體對 2.4G 天線的吸收效應(yīng)非常明顯實測同一塊板子放在金屬底座上和放在塑料支架上RSSI 能差 15 到 20 個 dB。注意BLE 的廣播通道固定在 2402MHz、2426MHz、2480MHz這三個頻點旁邊往往有 Wi-Fi 的 2.4G 信號。如果現(xiàn)場 Wi-Fi 信道恰好落在這些頻點附近廣播包碰撞概率會增大但不是廣播消失的根因。只要廣播間隔正常協(xié)議棧會在后續(xù)間隔里重試不會出現(xiàn)永久看不到的現(xiàn)象。4. 常見問題與排查技巧實錄4.1 上電后完全沒有廣播手機(jī)和抓包器都找不到這是最典型的情況優(yōu)先級最高的是確認(rèn)協(xié)議棧是否起來了??梢栽赼pp_ble.c的APP_BLE_Init()里臨時加一個 GPIO 翻轉(zhuǎn)用示波器或者邏輯分析儀看 M0 初始化完成后有沒有執(zhí)行到。實際上更快的辦法是檢查hci_init()的返回值STM32WB55 的 HCI 層和 M0 通信是通過內(nèi)部 IPC 完成的如果返回錯誤說明 M0 沒有正常運行協(xié)議棧。常見的錯誤返回是HCI_UNSUPPORTED_FEATURE或者HCI_COMMAND_DISALLOWED這兩種情況通常不是應(yīng)用代碼問題而是 FUS 和 BLE Stack 版本不匹配。去 ST 官網(wǎng)下載最新版 STM32CubeWB里面固件和 FUS 是配套的不建議混搭不同版本。版本不匹配的典型現(xiàn)象就是編譯燒錄都成功、LED 正常、就是不廣播排查成本極高所以我開頭就說先確認(rèn)協(xié)議棧版本匹配。還有一個隱蔽問題FUS 的啟動狀態(tài)影響整個協(xié)議棧加載。在 STM32CubeProgrammer 的 FUS 頁面操作時如果看到 FUS is not running說明 FUS 沒有啟動需要先發(fā)送 Start Wirestack 命令或者重新燒錄 FUS。這個狀態(tài)在出廠芯片里一般沒問題但如果你對 Flash 做過擦除就得重新走一遍 FUS 啟動流程。4.2 廣播時有時無間隔一大就消失廣播時有時無通常不是節(jié)點本身的問題而是環(huán)境干擾或供電跌落。我遇到過一種情況板子放在電腦旁邊靠近 USB3.0 HUB 時廣播正常但放到金屬機(jī)箱上后廣播消失拿起來懸空廣播又回來了。這個屬于天線阻抗受周圍環(huán)境變化導(dǎo)致發(fā)射效率下降協(xié)議棧本身沒有報錯。解決辦法很粗暴把 Dongle 放到干凈的位置再測試。另一種可能是ENTER_LOW_POWER_MODE沒有關(guān)閉導(dǎo)致 MCU 進(jìn)入低功耗狀態(tài)后射頻子系統(tǒng)的時鐘或供電被間歇性關(guān)斷廣播間隔被拉長到幾秒甚至十幾秒一次。在官方例程里CFG_LOW_POWER_MODE這個宏默認(rèn)是啟用的它在電池設(shè)備上很有用但在 USB 供電的 Dongle 上沒意義。如果你發(fā)現(xiàn)廣播間隔比配置值大很多看看這個宏是否被定義成了 1改成 0 后問題通常馬上消失。低功耗設(shè)計本身沒有錯但在 USB Dongle 這種持續(xù)供電設(shè)備上省電邏輯只會引入不必要的復(fù)雜度。還有一次我的現(xiàn)象是手機(jī)掃到廣播后不斷重連連上就斷開用抓包器看廣播正常但連接請求CONNECT_REQ階段設(shè)備沒有回應(yīng)。檢查后發(fā)現(xiàn)是代碼里沒有正確處理連接事件回調(diào)M4 沒有及時調(diào)用aci_gap_connection_complete_event之后的程序相當(dāng)于只廣播但不參與連接。這個屬于應(yīng)用層邏輯問題不是射頻問題排查方向要分開。4.3 手機(jī)看不到但抓包器能正常抓到廣播這種場景很有迷惑性抓包器確認(rèn)廣播在發(fā)手機(jī)卻掃不到很多人會懷疑手機(jī)壞了。其實大概率是廣播數(shù)據(jù)格式或廣播參數(shù)不滿足手機(jī)端過濾條件。如果廣播包設(shè)置了ADV_TYPE為不可連接廣播Non-connectable undirected advertising很多手機(jī)在掃碼界面會直接忽略因為這種廣播不可連接掃了也沒用。Beacon 類應(yīng)用常用這個類型但如果是想做連接類應(yīng)用要選擇可連接廣播。另一種情況是廣播周期太長。如果把廣播間隔調(diào)到 1000ms 以上手機(jī)端掃描窗口通常是 10.24 秒為一個周期其中約 3.84 秒在掃描就有概率漏掉你表現(xiàn)為時有時無。藍(lán)牙規(guī)范里若廣播間隔小于等于 100ms掃描器幾乎必能發(fā)現(xiàn)間隔大于 1s 時就要碰運氣了。排查時把廣播間隔臨時調(diào)小到 50~100ms如果手機(jī)馬上能看到問題就在廣播參數(shù)上。手機(jī)上裝了某些過濾類 App比如防廣告攔截類的可能會屏蔽未知 BLE 設(shè)備。我自己的 Android 手機(jī)上裝了個網(wǎng)絡(luò)管控工具它會把廠商 ID 是 0xFFFF 的廣播包當(dāng)成可疑設(shè)備自動過濾掉。換個手機(jī)或者換 App 試試能避免被這種軟件玄學(xué)帶偏方向。4.4 RSSI 和天線布局為什么廣播功率調(diào)了沒效果官方例程里通常有aci_hal_set_tx_power_level()這個 API可以設(shè)置發(fā)射功率比如 0 dBm、3 dBm、6 dBm。很多人調(diào)大功率后發(fā)現(xiàn)手機(jī) RSSI 沒有明顯提升就以為 API 沒生效。實際上 STM32WB55 的發(fā)射功率有多個等級最大 6 dBm 時電流消耗明顯增加但 RSSI 的提升不是線性的——從 0 dBm 調(diào)到 6 dBm理論上只增加 6 dB反映在手機(jī)上通常只有幾個 dB 的改善而環(huán)境的反射、路徑損耗、天線方向帶來的影響遠(yuǎn)不止 6 dB。天線布局對 RSSI 的影響更大。NUCLEO-WB55 USBDongle 的天線區(qū)域在 PCB 一端距離 USB 接口較遠(yuǎn)。使用時要保證天線周圍 1cm 以內(nèi)沒有金屬遮擋。如果 Dongle 是插在電腦后面板或者顯示器集線器上天線部分可能被金屬殼包圍信號衰減會非常明顯。最好用一根 USB 延長線把 Dongle 拖出來讓天線區(qū)域懸空實測 RSSI 能從 -70 dBm 提到 -55 dBm。RSSI 調(diào)試時還要注意測量環(huán)境的一致性。我會固定一個測試位置板子放在塑料泡沫支架上手機(jī)固定在 1 米外的同一地點然后把所有變量廣播間隔、信道、發(fā)射功率、天線方向逐個調(diào)整每次只改一個變量。如果不控制變量連續(xù)測得 RSSI 波動能有 ±10 dB根本無法判斷改動效果。5. 幾個值得收藏的排查習(xí)慣和工具搭配5.1 遇到問題先做減法而不是做加法不廣播這個問題的排查思路我建議遵循從底層往上的減法原則先確認(rèn)供電和硬件再確認(rèn)調(diào)試連接再確認(rèn)協(xié)議棧是否運行最后才是應(yīng)用代碼邏輯。很多朋友一上來就懷疑自己寫的廣播數(shù)據(jù)有問題改了半天發(fā)現(xiàn)是 ST-LINK 線接觸不良浪費時間。我的排障順序是固定的萬用表量 USB 5V 電壓插上 Dongle 后看壓降是否超過 0.3V確認(rèn) STM32CubeProgrammer 能正常連接并讀出 Flash 內(nèi)容確認(rèn) Flash 里存在的固件類型和地址是否符合預(yù)期燒官方 BLE_Beacon 例程驗證射頻通路手機(jī) nRF Connect 掃描看 RSSI 和廣播名如果還不行用抓包器看協(xié)議棧行為這套順序能覆蓋我遇到過的所有不廣播場景。不需要每次都走完但遇到玄學(xué)問題時從頭走一遍往往能發(fā)現(xiàn)前面遺漏的細(xì)節(jié)。5.2 工具搭配建議調(diào)試器ST-LINK/V2 或 V3建議用原版或者質(zhì)量好的兼容版劣質(zhì)克隆版在 SWD 高速模式下容易不穩(wěn)定。燒錄工具STM32CubeProgrammer版本盡量新注意它和 STM32CubeWB 固件包版本的配套關(guān)系。抓包工具另一塊 NUCLEO-WB55 開發(fā)板 STM32WB BLE Sniffer 固件 Wireshark成本低效果好。手機(jī) AppnRF ConnectAndroid/iOS 都有、LightBlue各裝一個交叉驗證掃描結(jié)果。萬用表普通的 3 位半萬用表就夠主要量電壓。邏輯分析儀排查低功耗模式問題時有用看 GPIO 翻轉(zhuǎn)狀態(tài)和時序。這套工具加起來成本不高但能把軟件能看到和射頻實際發(fā)出去這兩件事同時覆蓋排障時不用來回猜。5.3 現(xiàn)場環(huán)境對 BLE 廣播的影響比想象中大最后提醒一點BLE 廣播的現(xiàn)場環(huán)境因素非常容易被忽略。我曾在辦公室里調(diào)試一塊 Dongle手機(jī)就在旁邊但始終搜不到廣播抓包器一抓發(fā)現(xiàn)廣播事件一直在發(fā)。反復(fù)排查后發(fā)現(xiàn)辦公桌旁邊有一個 USB 3.0 高速硬盤盒它的金屬外殼和內(nèi)部高速信號正好在 2.4G 頻段產(chǎn)生強(qiáng)干擾。把硬盤盒挪遠(yuǎn)半米之后手機(jī)立即就搜到了。如果你在辦公室或者測試臺調(diào)試先把周圍的大塊金屬物體、USB 3.0 設(shè)備、無線鼠標(biāo)接收器都移開能排除一大批環(huán)境干擾。無線鼠標(biāo)接收器這個很多人都沒注意。2.4G 無線鼠標(biāo)用的頻段和 BLE 部分重疊而且無線鼠標(biāo)是持續(xù)占信道發(fā)射的對 BLE 廣播的干擾比 Wi-Fi 還明顯。我實測過無線鼠標(biāo)接收器離 Dongle 10cm 以內(nèi)廣播包丟包率能從 1% 漲到接近 10%手機(jī)掃描成功率明顯下降。調(diào)試時把這些設(shè)備拿遠(yuǎn)一點能省很多排查時間。6. 結(jié)合實際項目如果 Dongle 做自定義 Beacon建議怎么改6.1 廣播數(shù)據(jù)的組織和注意事項如果確認(rèn)板子能正常廣播接下來就是把它改成自己想要的 Beacon。廣播數(shù)據(jù)最大是 31 字節(jié)包括頭字節(jié)、長度字節(jié)和數(shù)據(jù)內(nèi)容。BLE_Beacon 例程里的adv_data[]是按 TLV 格式組織的第一個字節(jié)是長度Length第二個字節(jié)是類型Type后面是數(shù)據(jù)Value。例如0x02, 0x01, 0x06表示長度為 2、類型為 Flags、數(shù)據(jù)為 0x06。自建 Beacon 時Manufacturer Specific Data 是常用的自定義載體。它由公司 IDCompany ID2 字節(jié)和自定義數(shù)據(jù)組成。普通開發(fā)者沒有購買 SIG 的公司 ID可以用 0xFFFF 作為測試用 ID。要注意的是廣播數(shù)據(jù)總長不能超過 31 字節(jié)如果超了協(xié)議棧會直接返回錯誤廣播可能不啟動。我把一個 28 字節(jié)的 UID 放進(jìn)去之后忘了算長度結(jié)果廣播完全沒發(fā)出來排查了半天才發(fā)現(xiàn)是數(shù)組越界。廣播名Device Name也占用廣播數(shù)據(jù)的空間如果名字設(shè)得很長剩下的空間就少了。我的建議是廣播數(shù)據(jù)里只放必要的信息名字盡量短比如 5 個字符以內(nèi)把空間留給自己的數(shù)據(jù)。如果確實需要完整設(shè)備名可以把名字放到 Scan Response Data 里手機(jī)掃描時也能看到但廣播包本身會更精簡。6.2 廣播事件類型和連接配置的選擇Beacon 類應(yīng)用一般用不可連接廣播non-connectable這樣可以減少功耗和協(xié)議開銷但缺點是手機(jī)不能連上來做數(shù)據(jù)交互。如果 Dongle 后面要做數(shù)據(jù)透傳或者 OTA就要改回可連接廣播。STM32WB55 的 HCI 命令里aci_gap_set_discoverable()的 advertising type 參數(shù)不同對應(yīng)行為也不同。調(diào)試時先用可連接廣播跑通了再根據(jù)需求調(diào)整減少變量。連接間隔Connection Interval和從機(jī)延遲Slave Latency在連接場景下同樣重要。這兩個參數(shù)由主機(jī)在連接請求里指定但從機(jī)可以在aci_gap_set_peripheral_configuration()里設(shè)置可接受范圍。如果從機(jī)設(shè)置的范圍和主機(jī)請求的差異太大連接會失敗或頻繁斷開。我遇到過一個問題Dongle 廣播正常但手機(jī)連接后 3 秒就斷實時排查發(fā)現(xiàn)是連接間隔沖突。把從機(jī)可接受范圍放寬后連接就穩(wěn)定了。這類問題在 Beacon 階段不會暴露但后續(xù)要轉(zhuǎn)成連接模式時一定會碰到。7. 最后分享一點個人體會NUCLEO-WB55 USBDongle 不廣播這個問題說大不大說小不小但每一次排查下來我對 STM32WB55 的協(xié)議棧結(jié)構(gòu)、FUS 機(jī)制、低功耗模式都有更深的理解。其實絕大多數(shù)不廣播問題都不是板子壞了而是供電、協(xié)議棧版本、燒錄地址、廣播參數(shù)這幾個環(huán)節(jié)里某個細(xì)節(jié)沒對上。把這些環(huán)節(jié)逐個驗證一遍花的時間不會太長。我個人在實際操作中的體會是調(diào)試這類雙核無線芯片最好先建立M4 應(yīng)用日志、BLE 協(xié)議棧狀態(tài)、射頻抓包三個視角同時看問題的習(xí)慣。M4 的日志能告訴你應(yīng)用代碼跑到哪一步協(xié)議棧狀態(tài)能告訴你 M0 是否正常抓包能告訴你射頻數(shù)據(jù)是否真的發(fā)到空中。三個視角對齊后問題定位基本就是時間問題。另外一個不算技巧的技巧每次燒錄前先把要用的固件版本記下來包括 FUS、BLE Stack、App 三個版本。很多難啃的問題最后發(fā)現(xiàn)只是某個組件被更新后引入了不兼容。調(diào)試記錄寫清楚能省下大量的重復(fù)排查時間。希望這篇基于實際踩坑經(jīng)驗整理的內(nèi)容能幫你少走彎路。如果你也遇到類似的廣播問題不妨按照上面的順序排查一遍大概率能在半小時內(nèi)定位到根因。