鲗?shí)戰(zhàn):從環(huán)境搭建到量產(chǎn)測(cè)試)
1. 為什么選PHY6252做BLE串口透?jìng)?.1 這顆芯片到底適合誰PHY6252是一顆面向低功耗藍(lán)牙應(yīng)用的SoC集成BLE射頻、MCU內(nèi)核和豐富外設(shè)主打的就是小體積、低功耗、低成本。我第一次接觸它是因?yàn)橐粋€(gè)工業(yè)傳感器采集項(xiàng)目現(xiàn)場(chǎng)設(shè)備只有UART口但客戶要求手機(jī)能直接看數(shù)據(jù)布線又不允許。這種場(chǎng)景下BLE串口透?jìng)骶褪亲钍∈碌姆桨浮延芯€串口翻譯成無線BLE服務(wù)手機(jī)端當(dāng)作一個(gè)虛擬串口來收發(fā)。如果你手上有STM32、nRF52這類平臺(tái)的經(jīng)驗(yàn)轉(zhuǎn)到PHY6252不會(huì)太痛苦因?yàn)樗腟DK結(jié)構(gòu)類似底層驅(qū)動(dòng)、協(xié)議棧、應(yīng)用層分離。但如果你是完全沒碰過BLE協(xié)議棧的新手我建議先把GATT、Service、Characteristic這幾個(gè)概念搞清楚再動(dòng)手否則調(diào)透?jìng)鞯臅r(shí)候會(huì)一頭霧水。PHY6252的典型應(yīng)用場(chǎng)景包括工業(yè)設(shè)備參數(shù)配置與數(shù)據(jù)回傳醫(yī)療健康類設(shè)備的短距離數(shù)據(jù)同步智能家居中控與子設(shè)備的調(diào)試通道傳感器節(jié)點(diǎn)的無線數(shù)據(jù)采集這些場(chǎng)景的共同點(diǎn)是數(shù)據(jù)量不大、實(shí)時(shí)性要求中等、對(duì)功耗敏感、成本敏感。PHY6252在這幾個(gè)維度上表現(xiàn)均衡尤其是它的休眠電流控制得不錯(cuò)適合電池供電的場(chǎng)合。1.2 串口透?jìng)鞯谋举|(zhì)是什么很多人以為BLE串口透?jìng)骶褪荁LE協(xié)議里有個(gè)串口服務(wù)其實(shí)不是。BLE協(xié)議棧本身沒有串口這個(gè)概念透?jìng)魇俏覀冏约憾x的一套數(shù)據(jù)搬運(yùn)邏輯把UART收到的字節(jié)通過BLE的Notify或Write發(fā)出去把BLE收到的字節(jié)通過UART的TX腳發(fā)出去。中間不解析、不打包、不改內(nèi)容所以叫透?jìng)?。理解這一點(diǎn)很關(guān)鍵因?yàn)樗鼪Q定了你的代碼結(jié)構(gòu)。你需要兩個(gè)數(shù)據(jù)緩沖區(qū)一個(gè)收UART一個(gè)收BLE一個(gè)狀態(tài)機(jī)來管理連接狀態(tài)以及一套流控機(jī)制防止緩沖區(qū)溢出。PHY6252的SDK里通常會(huì)有類似的例程但例程往往只做了最簡(jiǎn)版本實(shí)際項(xiàng)目里要補(bǔ)的東西不少。提示透?jìng)鞑坏扔跓o腦轉(zhuǎn)發(fā)。UART的波特率和BLE的連接間隔如果不匹配很容易丟數(shù)據(jù)。后面我會(huì)專門講怎么算這個(gè)賬。1.3 開發(fā)前需要準(zhǔn)備的東西動(dòng)手之前把下面這些備齊能省掉很多來回折騰的時(shí)間硬件PHY6252開發(fā)板一塊、USB轉(zhuǎn)TTL模塊一個(gè)、杜邦線若干軟件官方SDK從官網(wǎng)或代理渠道獲取、Keil或IAR看SDK支持哪個(gè)、串口調(diào)試助手、手機(jī)端BLE調(diào)試App比如nRF Connect或LightBlue文檔PHY6252數(shù)據(jù)手冊(cè)、SDK里的API參考、BLE協(xié)議棧的GATT說明這里有個(gè)坑要提前說PHY6252的SDK版本比較多不同版本之間的API可能有差異。我建議你拿到SDK后先看它的Release Note確認(rèn)版本號(hào)和例程的對(duì)應(yīng)關(guān)系別拿著舊教程調(diào)新SDK會(huì)浪費(fèi)很多時(shí)間。2. 環(huán)境搭建與SDK工程結(jié)構(gòu)拆解2.1 SDK目錄里哪些東西必須看PHY6252的SDK目錄通常長(zhǎng)這樣不同版本略有差異SDK_ROOT/ ├── components/ # 協(xié)議棧、驅(qū)動(dòng)、中間件 │ ├── ble/ # BLE協(xié)議棧相關(guān) │ ├── drivers/ # 外設(shè)驅(qū)動(dòng) │ └── ... ├── examples/ # 例程 │ ├── ble_uart/ # 串口透?jìng)骼倘绻?│ └── ... ├── projects/ # 工程文件 └── tools/ # 燒錄、調(diào)試工具你必須重點(diǎn)看的是components/ble/和examples/這兩個(gè)目錄。前者是協(xié)議棧的API后者是官方給的參考實(shí)現(xiàn)。我的習(xí)慣是先把例程跑通再在例程基礎(chǔ)上改而不是從零建工程——從零建工程容易漏掉協(xié)議棧的初始化順序排查起來很痛苦。2.2 工程配置里最容易忽略的三個(gè)地方第一協(xié)議棧的RAM分配。BLE協(xié)議棧需要一塊獨(dú)立的RAM區(qū)域通常在鏈接腳本或工程配置里指定。如果這塊區(qū)域太小協(xié)議棧跑不起來太大應(yīng)用層就沒內(nèi)存用了。PHY6252的SDK一般會(huì)給一個(gè)推薦值但你要根據(jù)自己應(yīng)用的數(shù)據(jù)緩沖區(qū)大小調(diào)整。第二中斷優(yōu)先級(jí)。BLE協(xié)議棧對(duì)中斷時(shí)序很敏感UART中斷的優(yōu)先級(jí)不能高于協(xié)議棧相關(guān)的中斷否則會(huì)出現(xiàn)連接不穩(wěn)定甚至斷連。這個(gè)在SDK文檔里通常有說明但很多人不看直接默認(rèn)配置然后就遇到手機(jī)連上一會(huì)兒就掉的問題。第三時(shí)鐘配置。PHY6252的BLE射頻需要精確的時(shí)鐘源通常是外部晶振。如果你用的是內(nèi)部RC振蕩器BLE的連接間隔和時(shí)序會(huì)不準(zhǔn)表現(xiàn)為連接參數(shù)協(xié)商失敗或者通信丟包。這個(gè)坑我在早期項(xiàng)目里踩過換了晶振之后問題消失。2.3 編譯與燒錄的實(shí)操步驟以Keil為例流程大致如下打開projects/下對(duì)應(yīng)的工程文件.uvprojx在Options for Target里確認(rèn)芯片型號(hào)和下載器配置編譯看是否有報(bào)錯(cuò)。常見報(bào)錯(cuò)是頭文件路徑?jīng)]配全去C/C選項(xiàng)卡里補(bǔ)上連接開發(fā)板選擇下載算法燒錄復(fù)位后用手機(jī)App掃描看是否能發(fā)現(xiàn)設(shè)備燒錄的時(shí)候注意有些PHY6252開發(fā)板需要先按住某個(gè)按鍵再上電才能進(jìn)入下載模式具體看板子說明。如果燒錄失敗先檢查這個(gè)。注意燒錄前最好把之前的固件擦除干凈尤其是協(xié)議棧的綁定信息bonding info存在Flash里的時(shí)候殘留數(shù)據(jù)會(huì)導(dǎo)致新固件行為異常。3. BLE服務(wù)與特征值的定義邏輯3.1 透?jìng)鞣?wù)該怎么設(shè)計(jì)BLE的數(shù)據(jù)交互是通過GATT層完成的。你要定義一個(gè)Service里面至少放兩個(gè)Characteristic一個(gè)用于手機(jī)發(fā)給設(shè)備Write一個(gè)用于設(shè)備發(fā)給手機(jī)Notify。這是最經(jīng)典的透?jìng)髂P汀UID的選擇上調(diào)試階段可以用16位的標(biāo)準(zhǔn)UUID或者自定義的128位UUID。正式產(chǎn)品建議用128位自定義UUID避免和標(biāo)準(zhǔn)服務(wù)沖突。PHY6252的SDK里通常有UUID生成的宏你按格式填就行。一個(gè)典型的透?jìng)鞣?wù)定義如下角色方向?qū)傩哉f明RX Characteristic手機(jī)→設(shè)備Write / Write Without Response手機(jī)寫入數(shù)據(jù)設(shè)備從BLE收到后轉(zhuǎn)發(fā)到UARTTX Characteristic設(shè)備→手機(jī)Notify設(shè)備從UART收到數(shù)據(jù)后通過Notify推給手機(jī)這里有個(gè)細(xì)節(jié)Write Without Response和Write With Response的區(qū)別。前者速度快但不保證送達(dá)后者有ACK但吞吐低。透?jìng)鲌?chǎng)景下如果數(shù)據(jù)量小且允許偶爾丟包用Without Response如果要求可靠用With Response但要接受速度下降。3.2 連接參數(shù)對(duì)透?jìng)餍阅艿挠绊態(tài)LE的連接參數(shù)包括連接間隔Connection Interval、從機(jī)延遲Slave Latency和超時(shí)時(shí)間Supervision Timeout。這三個(gè)參數(shù)直接決定了透?jìng)鞯耐掏铝亢脱舆t。連接間隔的范圍是7.5ms到4s。間隔越小吞吐越高但功耗越大。對(duì)于串口透?jìng)魑乙话憬ㄗh波特率9600以下連接間隔20~30ms足夠波特率115200連接間隔建議7.5~15ms波特率更高需要評(píng)估MTU大小和連接間隔的配合MTU最大傳輸單元默認(rèn)是23字節(jié)實(shí)際可用載荷20字節(jié)。你可以通過MTU協(xié)商把它提到247字節(jié)甚至更高這樣每次Notify能帶更多數(shù)據(jù)減少協(xié)議開銷。PHY6252的協(xié)議棧支持MTU協(xié)商但需要手機(jī)端也支持。計(jì)算一下假設(shè)MTU協(xié)商到247連接間隔15ms那么理論吞吐大約是247字節(jié)/15ms ≈ 16.5KB/s。實(shí)際因?yàn)閰f(xié)議開銷和調(diào)度延遲打個(gè)七折大概11KB/s。這對(duì)應(yīng)115200波特率約11.5KB/s剛好夠用。如果你的數(shù)據(jù)量更大要么減小連接間隔要么提高M(jìn)TU要么兩者都調(diào)。3.3 屬性表配置的實(shí)操細(xì)節(jié)在PHY6252的SDK里屬性表通常是一個(gè)數(shù)組每個(gè)元素描述一個(gè)Attribute的句柄、類型、權(quán)限和值。配置的時(shí)候要注意句柄順序GATT要求Service Declaration在前Characteristic Declaration在后然后是Characteristic Value和Descriptor。順序錯(cuò)了手機(jī)端可能識(shí)別不了。權(quán)限設(shè)置Write特征值要設(shè)成可寫Notify特征值要設(shè)成可通知并且要加CCCDClient Characteristic Configuration Descriptor否則手機(jī)端無法開啟Notify。CCCD的處理手機(jī)端開啟Notify時(shí)會(huì)寫CCCD你的代碼要捕獲這個(gè)寫操作把對(duì)應(yīng)的標(biāo)志位置位后續(xù)才能往這個(gè)特征值發(fā)Notify。這部分代碼在SDK例程里一般都有但例程可能只做了一個(gè)特征值。你要擴(kuò)展到兩個(gè)RX和TX需要復(fù)制并修改句柄和回調(diào)邏輯。改的時(shí)候仔細(xì)核對(duì)句柄索引錯(cuò)一個(gè)就會(huì)導(dǎo)致數(shù)據(jù)發(fā)到錯(cuò)誤的特征值上。4. UART與BLE之間的數(shù)據(jù)搬運(yùn)實(shí)現(xiàn)4.1 數(shù)據(jù)緩沖區(qū)的設(shè)計(jì)透?jìng)鞯暮诵氖莾蓚€(gè)緩沖區(qū)UART接收緩沖區(qū)和BLE發(fā)送緩沖區(qū)。UART中斷收到數(shù)據(jù)后先存入緩沖區(qū)然后由主循環(huán)或BLE事件回調(diào)把數(shù)據(jù)通過Notify發(fā)出去。反過來BLE收到Write后存入另一個(gè)緩沖區(qū)由主循環(huán)通過UART發(fā)送。緩沖區(qū)的設(shè)計(jì)要考慮幾個(gè)問題大小太小會(huì)溢出太大會(huì)占RAM。一般建議UART接收緩沖區(qū)至少能存兩倍于最大數(shù)據(jù)包的長(zhǎng)度。環(huán)形還是線性環(huán)形緩沖區(qū)更適合持續(xù)數(shù)據(jù)流線性緩沖區(qū)適合定長(zhǎng)包。透?jìng)鲌?chǎng)景推薦環(huán)形緩沖區(qū)。并發(fā)保護(hù)UART中斷和BLE回調(diào)可能同時(shí)訪問緩沖區(qū)需要關(guān)中斷或加鎖保護(hù)。我在實(shí)際項(xiàng)目里用的環(huán)形緩沖區(qū)結(jié)構(gòu)大概是這樣的typedef struct { uint8_t *buf; uint16_t size; volatile uint16_t head; volatile uint16_t tail; } ring_buf_t; bool ring_buf_put(ring_buf_t *rb, uint8_t data) { uint16_t next (rb-head 1) % rb-size; if (next rb-tail) return false; // full rb-buf[rb-head] data; rb-head next; return true; } bool ring_buf_get(ring_buf_t *rb, uint8_t *data) { if (rb-head rb-tail) return false; // empty *data rb-buf[rb-tail]; rb-tail (rb-tail 1) % rb-size; return true; }這個(gè)結(jié)構(gòu)簡(jiǎn)單可靠head和tail用volatile修飾單生產(chǎn)者單消費(fèi)者場(chǎng)景下不需要額外加鎖。4.2 UART中斷服務(wù)函數(shù)的寫法UART中斷里只做一件事把收到的字節(jié)塞進(jìn)環(huán)形緩沖區(qū)。不要在里面做數(shù)據(jù)處理更不要在里面調(diào)用BLE的發(fā)送函數(shù)因?yàn)锽LE發(fā)送可能阻塞會(huì)拖垮中斷響應(yīng)。void UART_IRQHandler(void) { if (UART_GetITStatus(UART, UART_IT_RX)) { uint8_t data UART_ReceiveData(UART); ring_buf_put(uart_rx_buf, data); UART_ClearITPendingBit(UART, UART_IT_RX); } }主循環(huán)里定期檢查uart_rx_buf是否有數(shù)據(jù)有的話就通過BLE Notify發(fā)出去。發(fā)送的時(shí)候要注意MTU限制一次不要超過協(xié)商后的MTU減3ATT頭開銷。4.3 BLE Notify的觸發(fā)時(shí)機(jī)Notify不能隨便發(fā)必須在連接建立、CCCD被開啟之后才能發(fā)。而且發(fā)送頻率受連接間隔限制你不能在一個(gè)連接事件里發(fā)多次Notify除非協(xié)議棧支持隊(duì)列。我的做法是在主循環(huán)里檢查ble_tx_buf如果有數(shù)據(jù)且連接已建立且CCCD已開啟就調(diào)用SDK的Notify API發(fā)送。發(fā)送成功后再?gòu)木彌_區(qū)取下一包。如果發(fā)送失敗比如協(xié)議棧忙就等下一輪循環(huán)再試。這里有個(gè)經(jīng)驗(yàn)不要在主循環(huán)里用while循環(huán)把緩沖區(qū)里的數(shù)據(jù)一次性全發(fā)完因?yàn)閰f(xié)議棧的發(fā)送隊(duì)列有限發(fā)太快會(huì)丟包。正確的做法是每次循環(huán)發(fā)一包讓協(xié)議棧有時(shí)間處理。4.4 流控與丟包處理透?jìng)髯钆碌木褪莵G包。丟包的來源有兩個(gè)UART緩沖區(qū)溢出和BLE發(fā)送隊(duì)列滿。UART緩沖區(qū)溢出的預(yù)防如果UART數(shù)據(jù)來得太快主循環(huán)來不及搬運(yùn)緩沖區(qū)就會(huì)滿。解決辦法是加流控——當(dāng)緩沖區(qū)快滿時(shí)通過BLE發(fā)一個(gè)暫停信號(hào)給手機(jī)端讓手機(jī)端慢點(diǎn)發(fā)?;蛘哂糜布骺豏TS/CTS但PHY6252的UART是否支持硬件流控要看具體型號(hào)。BLE發(fā)送隊(duì)列滿的處理SDK的Notify API通常會(huì)返回一個(gè)狀態(tài)碼如果返回busy說明協(xié)議棧隊(duì)列滿了這時(shí)候不要重試等下一次連接事件再發(fā)。重試會(huì)導(dǎo)致協(xié)議棧狀態(tài)混亂。提示調(diào)試透?jìng)鞯臅r(shí)候建議在手機(jī)端和UART端同時(shí)打時(shí)間戳對(duì)比數(shù)據(jù)到達(dá)時(shí)間這樣能快速定位是UART慢了還是BLE慢了。5. 實(shí)測(cè)中遇到的典型問題與排查鏈路5.1 手機(jī)連不上或連上就斷這個(gè)問題我遇到過好幾次排查下來原因主要有三類第一類廣播參數(shù)不對(duì)。廣播間隔太長(zhǎng)手機(jī)掃描不到廣播數(shù)據(jù)格式錯(cuò)誤手機(jī)解析失敗。檢查廣播間隔是否在20ms到1s之間廣播數(shù)據(jù)是否符合BLE規(guī)范。第二類連接參數(shù)不兼容。手機(jī)端發(fā)起的連接參數(shù)比如連接間隔超出了PHY6252協(xié)議棧的支持范圍導(dǎo)致連接建立后立即斷開。解決辦法是在協(xié)議棧里配置可接受的連接參數(shù)范圍或者讓手機(jī)端用默認(rèn)參數(shù)。第三類電源問題。BLE射頻在連接建立瞬間電流會(huì)跳變?nèi)绻娫垂╇姴蛔阈酒瑫?huì)復(fù)位。用示波器看電源紋波如果跳變超過100mV就要加電容或者換LDO。排查鏈路先用手機(jī)App看能否掃描到廣播 → 能掃描到但連不上看廣播數(shù)據(jù) → 能連上但馬上斷看連接參數(shù)和電源 → 都正常看協(xié)議棧日志。5.2 數(shù)據(jù)發(fā)出去但手機(jī)收不到這種情況通常是CCCD沒開啟或者Notify的句柄用錯(cuò)了。排查步驟用手機(jī)App查看透?jìng)鞣?wù)的TX特征值確認(rèn)CCCD是否顯示Notify enabled如果沒有手動(dòng)開啟看是否能收到數(shù)據(jù)如果能收到說明代碼里沒有正確處理CCCD的寫事件去檢查CCCD回調(diào)如果還是收不到檢查Notify API的句柄參數(shù)是否和TX特征值的句柄一致我踩過一次坑SDK例程里TX特征值的句柄是硬編碼的我加了RX特征值之后句柄偏移了但Notify還是用的舊句柄結(jié)果數(shù)據(jù)發(fā)到了RX特征值上手機(jī)端當(dāng)然收不到。這種問題看日志很難發(fā)現(xiàn)只能對(duì)著屬性表一個(gè)個(gè)核對(duì)。5.3 大數(shù)據(jù)量下丟包嚴(yán)重?cái)?shù)據(jù)量一大就丟包通常是緩沖區(qū)太小或者流控沒做好。先算賬假設(shè)UART波特率115200每秒最多11520字節(jié)。BLE連接間隔15msMTU 247每秒最多發(fā)66包每包244字節(jié)理論吞吐16KB/s??雌饋韷虻珜?shí)際因?yàn)閰f(xié)議棧調(diào)度有效吞吐可能只有10KB/s。如果UART持續(xù)以11520字節(jié)/秒的速度發(fā)BLE發(fā)不過來緩沖區(qū)就會(huì)滿。解決辦法增大UART接收緩沖區(qū)比如從256字節(jié)加到2048字節(jié)降低UART波特率或者讓發(fā)送端加流控提高BLE吞吐減小連接間隔、增大MTU、用Write Without Response實(shí)測(cè)下來115200波特率配15ms連接間隔和247 MTU持續(xù)傳輸時(shí)偶爾會(huì)丟幾個(gè)字節(jié)。把連接間隔降到7.5ms后丟包率明顯下降。但7.5ms對(duì)手機(jī)端功耗有影響需要權(quán)衡。5.4 功耗比預(yù)期高PHY6252標(biāo)稱的休眠電流很低但實(shí)際項(xiàng)目里如果配置不當(dāng)功耗會(huì)高一個(gè)數(shù)量級(jí)。常見的功耗問題廣播間隔太短廣播間隔從1s降到100ms平均功耗可能翻幾倍連接間隔太短7.5ms的連接間隔比100ms的功耗高很多GPIO漏電未使用的GPIO如果懸空可能產(chǎn)生漏電流配置成下拉或模擬輸入U(xiǎn)ART一直開著UART的RX引腳如果有數(shù)據(jù)翻轉(zhuǎn)會(huì)喚醒芯片不用的時(shí)候關(guān)掉我的做法是在滿足功能的前提下盡量用大的連接間隔和廣播間隔。如果應(yīng)用允許用Slave Latency讓從機(jī)跳過一些連接事件進(jìn)一步省電。6. AT指令擴(kuò)展與量產(chǎn)考慮6.1 為什么要在透?jìng)骰A(chǔ)上加AT指令純透?jìng)髦荒軅鲾?shù)據(jù)沒法配置參數(shù)。實(shí)際產(chǎn)品里客戶可能需要改設(shè)備名、改波特率、改連接參數(shù)這些都需要一套配置接口。AT指令是最通用的做法手機(jī)端發(fā)ATNAMEXXX設(shè)備解析后改名字并保存到Flash。AT指令的解析要和透?jìng)鲾?shù)據(jù)區(qū)分開。我的做法是在UART接收緩沖區(qū)里檢測(cè)AT前綴如果是AT指令就進(jìn)解析流程否則走透?jìng)?。但這樣有個(gè)問題如果透?jìng)鲾?shù)據(jù)里恰好包含AT會(huì)誤判。更可靠的做法是用一個(gè)獨(dú)立的配置特征值手機(jī)端通過寫這個(gè)特征值來發(fā)AT指令透?jìng)鲾?shù)據(jù)走另一個(gè)特征值。這樣物理隔離不會(huì)誤判。6.2 AT指令解析的狀態(tài)機(jī)設(shè)計(jì)AT指令解析用狀態(tài)機(jī)最穩(wěn)妥。狀態(tài)包括空閑、收到A、收到AT、收到AT、解析命令、解析參數(shù)、執(zhí)行、返回結(jié)果。typedef enum { AT_STATE_IDLE, AT_STATE_A, AT_STATE_AT, AT_STATE_CMD, AT_STATE_PARAM, AT_STATE_DONE } at_state_t;每個(gè)狀態(tài)處理一個(gè)字符遇到非法字符就回退到IDLE。解析完成后查表找到對(duì)應(yīng)的處理函數(shù)執(zhí)行并返回結(jié)果。指令表可以用結(jié)構(gòu)體數(shù)組typedef struct { const char *cmd; void (*handler)(const char *param); } at_cmd_t; const at_cmd_t at_cmds[] { {NAME, at_handler_name}, {BAUD, at_handler_baud}, {RESET, at_handler_reset}, {NULL, NULL} };這種結(jié)構(gòu)擴(kuò)展方便加新指令只需要加一行。6.3 參數(shù)保存與掉電恢復(fù)配置參數(shù)要存到Flash里掉電不丟。PHY6252的SDK通常提供Flash讀寫API但要注意Flash寫入前要先擦除擦除是按扇區(qū)的寫入次數(shù)有限不要頻繁寫參數(shù)變了才寫寫入過程中如果掉電數(shù)據(jù)可能損壞建議加校驗(yàn)和或者雙備份我的做法是參數(shù)結(jié)構(gòu)體加一個(gè)CRC字段上電時(shí)讀出來校驗(yàn)校驗(yàn)失敗就用默認(rèn)值。雙備份就是存兩份讀的時(shí)候選校驗(yàn)通過的那份。6.4 量產(chǎn)測(cè)試的注意事項(xiàng)量產(chǎn)的時(shí)候每臺(tái)設(shè)備都要測(cè)BLE連接和串口透?jìng)鳌H绻謩?dòng)測(cè)效率太低。我的做法是做一個(gè)自動(dòng)化測(cè)試工裝工裝上的主控通過UART連設(shè)備手機(jī)端或者另一個(gè)BLE主設(shè)備連設(shè)備然后自動(dòng)跑一遍連接、發(fā)數(shù)據(jù)、收數(shù)據(jù)、斷開的流程結(jié)果通過UART返回給工裝。測(cè)試項(xiàng)包括測(cè)試項(xiàng)方法合格標(biāo)準(zhǔn)廣播掃描10秒能發(fā)現(xiàn)設(shè)備連接發(fā)起連接3秒內(nèi)連接成功透?jìng)靼l(fā)1000字節(jié)收到1000字節(jié)無誤碼斷開主動(dòng)斷開1秒內(nèi)斷開可重新連接功耗測(cè)休眠電流小于規(guī)格值量產(chǎn)固件和調(diào)試固件要分開。調(diào)試固件開日志量產(chǎn)固件關(guān)日志否則日志輸出會(huì)影響功耗和時(shí)序。7. 一些個(gè)人經(jīng)驗(yàn)與后續(xù)擴(kuò)展方向透?jìng)髯鐾曛笪疫€試過在PHY6252上跑一些簡(jiǎn)單的數(shù)據(jù)處理比如在透?jìng)魍ǖ郎霞右粚有r?yàn)和重傳提高可靠性。這個(gè)思路適合數(shù)據(jù)量不大但對(duì)可靠性要求高的場(chǎng)景代價(jià)是吞吐下降。另一個(gè)方向是BLE主從切換。PHY6252支持同時(shí)做從機(jī)和主機(jī)這意味著它可以一邊和手機(jī)透?jìng)饕贿吶ミB別的BLE傳感器。這個(gè)在網(wǎng)關(guān)類應(yīng)用里很有用但協(xié)議棧的配置會(huì)復(fù)雜不少需要仔細(xì)規(guī)劃連接數(shù)和資源分配。還有一點(diǎn)PHY6252的SDK更新比較頻繁建議關(guān)注官方的Release Note新版本可能修復(fù)了舊版本的bug也可能引入了新的API。升級(jí)SDK之前先在測(cè)試環(huán)境驗(yàn)證別直接上量產(chǎn)。最后說一個(gè)調(diào)試技巧如果BLE行為異常先用手機(jī)端的抓包工具比如nRF Connect的日志功能看空口數(shù)據(jù)確認(rèn)是設(shè)備端的問題還是手機(jī)端的問題。很多時(shí)候問題出在手機(jī)端的連接參數(shù)或者緩存上清一下手機(jī)端的BLE緩存就能解決。