借助藍(lán)牙 5 的網(wǎng)狀網(wǎng)絡(luò)功能,開(kāi)發(fā)人員可以增強(qiáng)無(wú)線連接系統(tǒng)(如物聯(lián)網(wǎng)設(shè)備)的通信范圍和網(wǎng)絡(luò)可用性。但是,網(wǎng)狀網(wǎng)絡(luò)的低功耗無(wú)線硬件設(shè)計(jì)與網(wǎng)狀網(wǎng)絡(luò)軟件開(kāi)發(fā)之間存在著復(fù)雜的層次,這可能會(huì)使開(kāi)發(fā)人員迅速陷入混亂并危及項(xiàng)目進(jìn)度。
隨著支持藍(lán)牙 5 的智能手機(jī)和其他移動(dòng)平臺(tái)的出現(xiàn),時(shí)間成為一個(gè)關(guān)鍵因素,因?yàn)閹缀跛行袠I(yè)領(lǐng)域和應(yīng)用對(duì)藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)能力都有需求,而且預(yù)計(jì)需求會(huì)爆炸式增長(zhǎng),開(kāi)發(fā)人員需要快速響應(yīng)。作為回應(yīng),硅片和軟件供應(yīng)商正在推出簡(jiǎn)化和加速開(kāi)發(fā)流程的解決方案。
本文將概述藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)的基本原理,然后使用 Silicon Labs 支持網(wǎng)狀網(wǎng)絡(luò)的藍(lán)牙 5 模塊系列中的特定設(shè)備逐步介紹開(kāi)發(fā)流程。利用這種集成式藍(lán)牙 5 解決方案,開(kāi)發(fā)人員可以快速部署聯(lián)網(wǎng)設(shè)備和應(yīng)用,從而充分利用藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)。
本文最后介紹 Silicon Labs 藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)軟件開(kāi)發(fā)包,其中詳細(xì)說(shuō)明了使用樣例網(wǎng)狀網(wǎng)絡(luò)應(yīng)用代碼演示的事件驅(qū)動(dòng)模型。
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)需求
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)超越了傳統(tǒng)藍(lán)牙技術(shù)的點(diǎn)對(duì)點(diǎn)連接能力。通過(guò)相鄰聯(lián)網(wǎng)設(shè)備中繼消息,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)將低功耗設(shè)備的有效覆蓋范圍擴(kuò)展到其發(fā)射器功率輸出和接收器靈敏度所能支持的實(shí)際范圍以外。最重要的是,智能手機(jī)和其他移動(dòng)設(shè)備的普及使得大家對(duì)藍(lán)牙應(yīng)用非常熟悉,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)藉由這一事實(shí),為更復(fù)雜的網(wǎng)狀網(wǎng)絡(luò)連接應(yīng)用提供自然的演進(jìn)。
在網(wǎng)狀網(wǎng)絡(luò)支持下,使用藍(lán)牙的開(kāi)發(fā)人員現(xiàn)在能夠輕松連接家庭自動(dòng)化、樓宇管理和任意數(shù)量物聯(lián)網(wǎng)應(yīng)用涉及的大量設(shè)備。
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)工作原理
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)使用概念上很簡(jiǎn)單的網(wǎng)絡(luò)節(jié)點(diǎn)交互模型(圖 1)。專(zhuān)用節(jié)點(diǎn)類(lèi)型可提供節(jié)點(diǎn)之間中繼消息所需的附加功能,從而擴(kuò)展通過(guò)代理節(jié)點(diǎn)與支持藍(lán)牙的移動(dòng)設(shè)備進(jìn)行交互的網(wǎng)絡(luò)的有效范圍。
圖 1:除基本邊緣節(jié)點(diǎn)外,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)還能使用特殊節(jié)點(diǎn)類(lèi)型為其他節(jié)點(diǎn)傳遞消息(中繼),充當(dāng)?shù)凸墓?jié)點(diǎn)的緩存(好友),或者將網(wǎng)絡(luò)(代理)連接到支持藍(lán)牙的移動(dòng)設(shè)備。(圖片來(lái)源:Silicon Labs)
其他專(zhuān)用節(jié)點(diǎn)類(lèi)型則可應(yīng)對(duì)降低功耗的要求,使用好友節(jié)點(diǎn)緩存消息,以供低功耗節(jié)點(diǎn)在長(zhǎng)時(shí)間休眠狀態(tài)之間定期輪詢(xún)。盡管具有這種附加功能,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)設(shè)備仍然可以利用通用屬性配置文件 (GATT) 服務(wù)來(lái)與使用早期藍(lán)牙版本的舊設(shè)備進(jìn)行連接。因此,網(wǎng)狀網(wǎng)絡(luò)設(shè)備可以充分利用現(xiàn)有低功耗藍(lán)牙 (BLE) 能力(例如信標(biāo)),以生成區(qū)域特定消息并發(fā)送給智能手機(jī),或者將自身標(biāo)識(shí)為資產(chǎn)管理應(yīng)用。
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)還能解決日益增長(zhǎng)的對(duì)樓宇自動(dòng)化或其他物聯(lián)網(wǎng)應(yīng)用所需受保護(hù)網(wǎng)絡(luò)的安全性的關(guān)注。與提供可選安全性以保護(hù)單個(gè)設(shè)備的 BLE 不同,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)實(shí)施的安全性試圖保護(hù)整個(gè)網(wǎng)狀網(wǎng)絡(luò)。
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)實(shí)現(xiàn)安全的方法特別有意義。其安全方案將“關(guān)注點(diǎn)分離”概念引入到網(wǎng)狀網(wǎng)絡(luò)中,為每個(gè)設(shè)備、網(wǎng)絡(luò)和整體應(yīng)用使用單獨(dú)的安全措施。與每個(gè)設(shè)備相關(guān)聯(lián)的私有設(shè)備密鑰 (DevKey) 為僅涉及該節(jié)點(diǎn)的配置和調(diào)配等操作提供安全性。每個(gè)設(shè)備都需要網(wǎng)絡(luò)密鑰 (NetKey),才能與網(wǎng)絡(luò)或子網(wǎng)中的其他節(jié)點(diǎn)進(jìn)行通信。最后,應(yīng)用級(jí)交互(例如發(fā)送消息以開(kāi)燈)則需要應(yīng)用密鑰 (AppKey)。其他安全措施可用于防范中間人或重放攻擊等常見(jiàn)威脅。所有措施相互配合,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)中的安全機(jī)制為更復(fù)雜的物聯(lián)網(wǎng)應(yīng)用所需的信任提供了關(guān)鍵基礎(chǔ)。
然而,實(shí)現(xiàn)藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)連接應(yīng)用給開(kāi)發(fā)人員帶來(lái)了很大困難。大多數(shù)使用網(wǎng)狀網(wǎng)絡(luò)的應(yīng)用是建立在功耗受限的設(shè)備之上,依靠網(wǎng)狀網(wǎng)絡(luò)來(lái)擴(kuò)展低功耗無(wú)線電子系統(tǒng)的有效覆蓋范圍。創(chuàng)建支持網(wǎng)狀網(wǎng)絡(luò)的合適低功耗硬件設(shè)備所涉及的挑戰(zhàn),甚至能讓最有經(jīng)驗(yàn)的硬件開(kāi)發(fā)人員停滯不前。即使在完成其定制藍(lán)牙設(shè)計(jì)之后,為滿足國(guó)家認(rèn)證要求,開(kāi)發(fā)人員也可能面臨巨大的成本壓力和曠日持久的延遲。軟件開(kāi)發(fā)人員在尋找兼容的藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)堆棧并利用其來(lái)構(gòu)建軟件層以便能支持自己的應(yīng)用時(shí),也會(huì)發(fā)生延遲。然而,借助 Silicon Laboratories 的藍(lán)牙硬件和軟件,開(kāi)發(fā)人員可以在低功耗設(shè)備中快速部署藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)功能,以滿足自己的應(yīng)用需求。
藍(lán)牙模塊
Silicon Labs 的藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)解決方案基于其低功耗藍(lán)牙 BGM13P 硬件模塊,該模塊結(jié)合了無(wú)線處理器和全套藍(lán)牙堆棧,以 12.9×15.0×2.2 mm 的封裝提供經(jīng)過(guò)認(rèn)證的完整藍(lán)牙系統(tǒng)。該模塊的核心是 EFR32BG13 Blue Gecko 無(wú)線片上系統(tǒng) (SoC),可提供核心功能。EFR32BG13 SoC 集成了 32 位 Arm? Cortex?-M4 內(nèi)核、2.4 GHz 無(wú)線電子系統(tǒng)、512 KB 閃存、64 KB RAM 以及豐富的模擬和數(shù)字外設(shè)。除了片上硬件加密加速器之外,該 SoC 還通過(guò)安全管理單元支持不斷增長(zhǎng)的更高安全性需求;該安全管理單元為外設(shè)提供的細(xì)粒度訪問(wèn)控制與存儲(chǔ)器保護(hù)單元為存儲(chǔ)器提供的相同。
EFR32BG13 SoC 可作為定制藍(lán)牙硬件設(shè)計(jì)的基礎(chǔ)。使用 SoC 時(shí),開(kāi)發(fā)人員不僅要負(fù)責(zé)滿足 SoC 支持電路等設(shè)計(jì)要求,還要對(duì)完成的設(shè)計(jì)進(jìn)行必要的認(rèn)證。該模塊提供有全面認(rèn)證的設(shè)計(jì),其中的 EFR32BG13 帶有所需的支持電路,包括數(shù)個(gè)振蕩器源、兩個(gè)晶體和端口驅(qū)動(dòng)器。與此同時(shí),該模塊還提供了一系列省電特性,因此開(kāi)發(fā)人員能夠響應(yīng)持續(xù)存在的低功耗設(shè)備需求。
該模塊在活動(dòng)模式下僅消耗 87 μA/MHz,在全 RAM 保持的深度休眠模式下僅消耗 1.4 μA。為了幫助最大限度地延長(zhǎng)停留在低功耗深度休眠模式下的時(shí)間,工程師可以利用低能耗傳感器接口和低能耗定時(shí)器等特性。使用低能耗傳感器接口,工程師可以對(duì)模塊的集成有限狀態(tài)機(jī)和模擬外設(shè)進(jìn)行編程,以在處理器保持深度休眠模式的同時(shí)采集和處理傳感器信號(hào)。類(lèi)似地,通過(guò)低能耗定時(shí)器,工程師可以輸出簡(jiǎn)單波形并監(jiān)控實(shí)時(shí)時(shí)鐘/計(jì)數(shù)器,以便在指定時(shí)間內(nèi)執(zhí)行操作,而無(wú)需處理器參與。
當(dāng)然,無(wú)線設(shè)備的功耗一般取決于無(wú)線電子系統(tǒng)的效率。本例中,該模塊的 2.4 GHz 無(wú)線電子系統(tǒng)在接收模式下僅消耗 9.9 mA,在 0 dBm 輸出功率的發(fā)射模式下僅消耗 8.5 mA。即便如此,該模塊還提供了通過(guò)射頻控制節(jié)省功耗的額外特性。開(kāi)發(fā)人員可以對(duì)模塊中的射頻檢測(cè)功能進(jìn)行編程,以在檢測(cè)到寬帶射頻能量時(shí)喚醒處理器。通過(guò)這種方法,開(kāi)發(fā)人員可以在無(wú)活動(dòng)期間使模塊保持深度休眠而不會(huì)喪失通信。但是,如前所述,開(kāi)發(fā)人員也可以將某個(gè)設(shè)備配置為藍(lán)牙 5 低功耗節(jié)點(diǎn),其能夠簡(jiǎn)單地定期從深度休眠中喚醒以輪詢(xún)好友節(jié)點(diǎn),獲取緩存的消息。
系統(tǒng)開(kāi)發(fā)
針對(duì)其所有特性,該模塊在實(shí)現(xiàn)方面幾乎沒(méi)有任何困難。開(kāi)發(fā)人員可以簡(jiǎn)單地將該模塊放入一個(gè)帶有處理器的設(shè)計(jì)中,將其用作藍(lán)牙網(wǎng)絡(luò)協(xié)處理器(圖 2A)?;蛘?,開(kāi)發(fā)人員可以將該模塊用作完整的系統(tǒng)解決方案(圖 2B)。在這種獨(dú)立模式下,開(kāi)發(fā)人員可以在模塊的 EFR32BG13 處理器上運(yùn)行應(yīng)用代碼,并使用 EFR32BG13 集成的模擬和數(shù)字外設(shè)在簡(jiǎn)單的物聯(lián)網(wǎng)設(shè)計(jì)中進(jìn)行信號(hào)采集。
圖 2:設(shè)計(jì)人員可以將 BGM13P 模塊用作主機(jī) CPU 的藍(lán)牙協(xié)處理器 (A),或者單獨(dú)使用 (B),利用模塊集成的 EFR32BG13 SoC 執(zhí)行應(yīng)用程序甚至采集傳感器數(shù)據(jù)。(圖片來(lái)源:Silicon Labs)
開(kāi)發(fā)人員可以使用該模塊的一個(gè)集成天線的版本 BGM13P22F512GA-V2,以進(jìn)一步簡(jiǎn)化藍(lán)牙設(shè)計(jì)。針對(duì)要應(yīng)對(duì)更具挑戰(zhàn)性射頻環(huán)境的設(shè)計(jì),開(kāi)發(fā)人員可以采用 BGM13P22F512GE-V2,這是一個(gè)帶有 U.FL 連接器的版本,可以連接藍(lán)牙兼容的平貼片天線,例如 Taoglas 的 FXP74.07.0100A。
Silicon Labs 甚至通過(guò) SLWSTK6101C 開(kāi)發(fā)套件消除了該級(jí)別的硬件實(shí)現(xiàn)。SLWSTK6101C 設(shè)計(jì)用于配合其不同藍(lán)牙設(shè)備的插件板使用,提供代表性的物聯(lián)網(wǎng)設(shè)計(jì),包含 Macronix 的 MX25R8035F 8 Mb 閃存、Sharp Microelectronics 的 LS013B7DH03 128 x 128 LCD 和 Silicon Labs 的 Si7021 溫度與濕度傳感器。在這種情況下,開(kāi)發(fā)人員將包含 BGM13P 模塊的 SLWRB4306A 無(wú)線電電路板插入 SLWSTK6101C 板。
除了作為可立即投產(chǎn)的設(shè)計(jì)之外,全套電路板還提供經(jīng)過(guò)驗(yàn)證的參考設(shè)計(jì),工程師可以使用它來(lái)檢查與閃存、LCD 和傳感器等設(shè)備接口的不同方法。
例如,8 Mb 閃存和 LCD 通過(guò)其 SPI 總線連接到模塊,而 Si7021 傳感器的 I2C 接口與開(kāi)發(fā)板上的外部針座共享總線。Silicon Labs 演示了一種設(shè)計(jì)簡(jiǎn)單接口的方法,它使傳感器在正常情況下保持禁用并與共享總線電氣隔離。當(dāng)模塊的 PD15 輸入變?yōu)楦唠娖綍r(shí),SENSOR_ENABLE 輸出變?yōu)楦唠娖?,將傳感器連接到 3.3 V VMCU 電源軌和 I2C 總線(圖 3)。
圖 3:除了提供硬件評(píng)估平臺(tái)之外,Silicon Labs SLWSTK6101C 開(kāi)發(fā)套件還可充當(dāng)參考設(shè)計(jì),展示與此處所示的 Silicon Labs Si7021 傳感器等外部設(shè)備接口的方法。(圖片來(lái)源:Silicon Labs)
共享 I2C 總線針座只是設(shè)計(jì)用來(lái)支持該平臺(tái)開(kāi)發(fā)的幾個(gè)特性之一(圖 4)。除了板載 J-Link 調(diào)試器之外,該板還提供了數(shù)據(jù)包追蹤接口 (PTI),允許工程師詳細(xì)分析數(shù)據(jù)包。PTI 建立在 EFR32BG13 SoC 內(nèi)置的數(shù)據(jù)包和狀態(tài)追蹤單元之上,提供對(duì)系統(tǒng)發(fā)送和接收的所有數(shù)據(jù)包的非侵入式捕捉。為了分析藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)等復(fù)雜協(xié)議,該數(shù)據(jù)包追蹤功能提供了一個(gè)對(duì)于優(yōu)化和調(diào)整低級(jí)網(wǎng)絡(luò)通信至關(guān)重要的工具。
圖 4:Silicon Labs SLWSTK6101C 套件有多個(gè)接口用于數(shù)據(jù)包追蹤、能量監(jiān)測(cè)和低級(jí) Arm 嵌入式追蹤宏單元 (ETM) 追蹤,為工程師深入分析設(shè)計(jì)操作和性能提供了豐富的工具集。(圖片來(lái)源:Silicon Labs)
雖然網(wǎng)絡(luò)專(zhuān)家需要 PTI 這樣的功能來(lái)優(yōu)化網(wǎng)絡(luò),但系統(tǒng)開(kāi)發(fā)人員需要能幫助其發(fā)現(xiàn)可能導(dǎo)致功耗過(guò)大的應(yīng)用低效問(wèn)題的工具。對(duì)于此類(lèi)應(yīng)用級(jí)功耗優(yōu)化,Silicon Labs Simplicity Studio 能量分析器可提供代碼級(jí)功耗分析。
同數(shù)據(jù)包追蹤工具一樣,能量分析器也是對(duì)底層硬件加以利用。在這種情況下,電路板包括一個(gè)專(zhuān)用能量監(jiān)測(cè)電路,其由電流傳感器電阻、電流檢測(cè)放大器和增益級(jí)組成,將輸出傳送到電路板的控制器,供開(kāi)發(fā)主機(jī)系統(tǒng)訪問(wèn)(圖 5)。并聯(lián)增益級(jí)允許能量監(jiān)測(cè)器以?xún)蓚€(gè)不同的分辨率級(jí)別測(cè)量 0.1 μA 至 95 mA 的電流:250 μA 以上使用 0.1 mA 分辨率;低于 250 μA 閾值使用 1 μA 分辨率。
圖 5:內(nèi)置于 BGM13P 藍(lán)牙模塊的專(zhuān)用能量監(jiān)測(cè)電路和處理控制器可提供 0.1 μA 至 95 mA 的非侵入式電流測(cè)量。(圖片來(lái)源:Silicon Labs)
當(dāng)能量監(jiān)測(cè)電路產(chǎn)生電流測(cè)量結(jié)果時(shí),EFR32BG13 內(nèi)置的低級(jí)追蹤機(jī)制可以定期對(duì)處理器的程序計(jì)數(shù)器進(jìn)行采樣,并將結(jié)果通過(guò)設(shè)備的串行線輸出引腳輸出。通過(guò)將能量監(jiān)測(cè)器的結(jié)果與此程序追蹤輸出相結(jié)合,能量分析器可以實(shí)時(shí)顯示與設(shè)備上運(yùn)行的代碼相關(guān)的能耗(圖 6)
圖 6:Simplicity Studio 能量分析器將能量監(jiān)測(cè)器輸出與程序追蹤數(shù)據(jù)相結(jié)合,以實(shí)時(shí)顯示與實(shí)際代碼相關(guān)的電流消耗。(圖片來(lái)源:Silicon Labs)
網(wǎng)狀網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)
硬件工程師可以使用開(kāi)發(fā)套件來(lái)優(yōu)化其硬件設(shè)計(jì),而軟件開(kāi)發(fā)人員可以利用 Silicon Labs 的綜合軟件開(kāi)發(fā)環(huán)境來(lái)快速創(chuàng)建網(wǎng)狀網(wǎng)絡(luò)應(yīng)用。Silicon Labs 的藍(lán)牙 5 網(wǎng)狀網(wǎng)絡(luò)堆棧隨同 Simplicity Studio 提供,其用特定網(wǎng)狀網(wǎng)絡(luò)資源擴(kuò)展了基本藍(lán)牙堆棧。因此,開(kāi)發(fā)人員可以輕松地從較傳統(tǒng)的藍(lán)牙協(xié)議(如信標(biāo)或點(diǎn)對(duì)點(diǎn)通信)轉(zhuǎn)移到全網(wǎng)狀網(wǎng)絡(luò)拓?fù)洌▓D 7)。
圖 7:Silicon Labs 藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)堆棧用網(wǎng)狀網(wǎng)絡(luò)層(綠色)擴(kuò)展了早期藍(lán)牙功能(藍(lán)色),使得開(kāi)發(fā)人員能夠充分利用從信標(biāo)到全網(wǎng)狀網(wǎng)絡(luò)配置的全部藍(lán)牙特性。(圖片來(lái)源:Silicon Labs)
Simplicity Studio 與基于 Silicon Labs BGM13P 的 SLWRB4306A 和 SLWSTK6101C 開(kāi)發(fā)板一起使用,讓開(kāi)發(fā)人員能利用適當(dāng)?shù)能浖_(kāi)發(fā)套件 (SDK) 配置其環(huán)境。對(duì)于藍(lán)牙開(kāi)發(fā),Studio 提供了 Silicon Labs 的藍(lán)牙網(wǎng)狀網(wǎng)絡(luò) SDK 以及預(yù)先構(gòu)建的演示二進(jìn)制文件和源代碼。在此環(huán)境中,開(kāi)發(fā)人員可以使用實(shí)現(xiàn)了完整藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)應(yīng)用的樣例代碼。
這些樣例應(yīng)用程序與開(kāi)發(fā)板和移動(dòng)應(yīng)用配合使用,旨在演示藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)的操作,讓開(kāi)發(fā)人員能全面了解典型網(wǎng)狀網(wǎng)絡(luò)的操作,包括調(diào)配、配置和應(yīng)用相關(guān)的使用。為了部署樣例應(yīng)用程序,工程師針對(duì)一組開(kāi)發(fā)板運(yùn)行 Simplicity Studio,這些開(kāi)發(fā)板分別配置為聯(lián)網(wǎng)照明應(yīng)用中的燈或開(kāi)關(guān)。通過(guò)使用樣例代碼和硬件,工程師可以更好地了解典型網(wǎng)狀網(wǎng)絡(luò)應(yīng)用從設(shè)備上電開(kāi)始的各個(gè)操作階段。
借助 Silicon Labs 的軟件架構(gòu),藍(lán)牙操作可以一系列事件展開(kāi),使用預(yù)定義的事件 ID 來(lái)表示事件的性質(zhì)。在樣例軟件包中,main() 例程在上電或復(fù)位時(shí)運(yùn)行,先調(diào)用一系列初始化例程,然后進(jìn)入主循環(huán),本例中主循環(huán)只包含兩行代碼(列表 1)。
int main()
{
#ifdef FEATURE_SPI_FLASH
/* Put the SPI flash into Deep Power Down mode for those radio boards where it is available */
MX25_init();
MX25_DP();
/* We must disable SPI communication */
USART_Reset(USART1);
#endif /* FEATURE_SPI_FLASH */
enter_DefaultMode_from_RESET();
#if (EMBER_AF_BOARD_TYPE == BRD4304A)
LNA_init();
#endif
gecko_init(&config);
#ifdef FEATURE_PTI_SUPPORT
APP_ConfigEnablePti();
#endif // FEATURE_PTI_SUPPORT
RETARGET_SerialInit();
/* initialize LEDs and buttons.Note: some radio boards share the same GPIO for button & LED.* Initialization is done in this order so that default configuration will be button for those
* radio boards with shared pins.led_init() is called later as needed to (re)initialize the LEDs
* */
led_init();
button_init();
LCD_init();
while (1) {
struct gecko_cmd_packet *evt = gecko_wait_event();
handle_gecko_event(BGLIB_MSG_ID(evt-》header), evt);
}
}
列表 1:Simplicity Studio 提供了一個(gè)綜合開(kāi)發(fā)環(huán)境,其中包括樣例代碼,例如此網(wǎng)狀網(wǎng)絡(luò)照明主例程,其演示了初始化和事件處理循環(huán)。(代碼來(lái)源:Silicon Labs)
在主循環(huán)的第一行中,函數(shù) gecko_wait_event() 在阻塞流程的同時(shí)等待事件出現(xiàn),事件隊(duì)列由較低級(jí)別填充。雖然開(kāi)發(fā)人員往往會(huì)避免使用阻塞功能,但此方法在這種情況下特別有效,因?yàn)樗{(lán)牙堆棧在此阻斷模式下會(huì)自動(dòng)管理低功耗休眠狀態(tài)。對(duì)于不能容許阻塞等待的特定應(yīng)用要求,SDK 還提供了一個(gè)非阻塞函數(shù),如果隊(duì)列為空,則返回下一個(gè)事件或 NULL。但使用此函數(shù)時(shí),開(kāi)發(fā)人員需要自行處理低功耗休眠管理。
在主循環(huán)的第二行中,處理函數(shù) handle_gecko_event() 根據(jù)其事件 ID 處理最新事件 (evt)(列表 2)。當(dāng)設(shè)備上電時(shí),堆棧發(fā)出系統(tǒng)引導(dǎo)事件 (gecko_evt_system_boot_id)。事件處理程序進(jìn)而調(diào)用一系列初始化函數(shù),包括 gecko_cmd_mesh_node_init(),其會(huì)初始化藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)堆棧。然后,處理程序調(diào)用其他函數(shù)來(lái)提供與該事件類(lèi)型(由其相關(guān)事件 ID 表示)相關(guān)聯(lián)的功能。
/**
* Handling of stack events.Both Bluetooth LE and Bluetooth mesh events are handled here.*/
static void handle_gecko_event(uint32_t evt_id, struct gecko_cmd_packet *evt)
{
struct gecko_bgapi_mesh_node_cmd_packet *node_evt;
struct gecko_bgapi_mesh_generic_server_cmd_packet *server_evt;
struct gecko_msg_mesh_node_provisioning_failed_evt_t *prov_fail_evt;
if (NULL == evt) {
return;
}
switch (evt_id) {
case gecko_evt_system_boot_id:
// check pushbutton state at startup.If either PB0 or PB1 is held down then do factory reset
if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) == 0 || GPIO_PinInGet(BSP_GPIO_PB1_PORT, BSP_GPIO_PB1_PIN) == 0) {
initiate_factory_reset();
} else {
struct gecko_msg_system_get_bt_address_rsp_t *pAddr = gecko_cmd_system_get_bt_address();
set_device_name(&pAddr-》address);
// Initialize Mesh stack in Node operation mode, wait for initialized event
gecko_cmd_mesh_node_init();
// re-initialize LEDs (needed for those radio board that share same GPIO for button/LED)
led_init();
}
break;
。。.case gecko_evt_mesh_node_initialized_id:
printf(node initialized\r\n);
struct gecko_msg_mesh_node_initialized_evt_t *pData = (struct gecko_msg_mesh_node_initialized_evt_t *)&(evt-》data);
if (pData-》provisioned) {
。。.} else {
printf(node is unprovisioned\r\n);
LCD_write(unprovisioned, LCD_ROW_STATUS);
printf(starting unprovisioned beaconing.。。\r\n);
gecko_cmd_mesh_node_start_unprov_beaconing(0x3); // enable ADV and GATT provisioning bearer
}
break;
case gecko_evt_mesh_node_provisioning_started_id:
printf(Started provisioning\r\n);
LCD_write(provisioning.。。, LCD_ROW_STATUS);
// start timer for blinking LEDs to indicate which node is being provisioned
gecko_cmd_hardware_set_soft_timer(32768 / 4, TIMER_ID_PROVISIONING, 0);
break;
case gecko_evt_mesh_node_provisioned_id:
_my_index = 0; // index of primary element hardcoded to zero in this example
lightbulb_state_init();
printf(node provisioned, got index=%x\r\n, _my_index);
// stop LED blinking when provisioning complete
gecko_cmd_hardware_set_soft_timer(0, TIMER_ID_PROVISIONING, 0);
LED_set_state(LED_STATE_OFF);
LCD_write(provisioned, LCD_ROW_STATUS);
break;
case gecko_evt_mesh_node_provisioning_failed_id:
prov_fail_evt = (struct gecko_msg_mesh_node_provisioning_failed_evt_t *)&(evt-》data);
printf(provisioning failed, code %x\r\n, prov_fail_evt-》result);
LCD_write(prov failed, LCD_ROW_STATUS);
/* start a one-shot timer that will trigger soft reset after small delay */
gecko_cmd_hardware_set_soft_timer(2 * 32768, TIMER_ID_RESTART, 1);
break;
。。.}
}
列表 2:開(kāi)發(fā)人員可以檢查 Silicon Labs 網(wǎng)狀網(wǎng)絡(luò)樣例代碼中的關(guān)鍵設(shè)計(jì)模式,例如調(diào)配事件處理,相關(guān)代碼片段位于網(wǎng)狀網(wǎng)絡(luò)燈主程序中調(diào)用的 handle_gecko_event() 事件處理程序(參見(jiàn)列表 1)。(代碼來(lái)源:Silicon Labs)
藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)中的關(guān)鍵事件系列之一與調(diào)配過(guò)程有關(guān)。設(shè)備上電并完成其初始化序列之后,便進(jìn)入信標(biāo)模式,向網(wǎng)絡(luò)宣告其自身以供調(diào)配。當(dāng)調(diào)配完畢(或失?。r(shí),樣例代碼會(huì)使用開(kāi)發(fā)套件 LCD 和 LED 來(lái)指示狀態(tài)。通過(guò)檢查事件處理程序針對(duì)每個(gè)調(diào)配狀態(tài)的代碼塊,開(kāi)發(fā)人員可以快速了解該調(diào)配序列和選項(xiàng)。
同樣,軟件工程師可以使用樣例處理程序代碼作為創(chuàng)建其應(yīng)用級(jí)功能的指南。例如,藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)中的一個(gè)關(guān)鍵概念是使用發(fā)布-訂閱模型將共享某些功能關(guān)系的節(jié)點(diǎn)關(guān)聯(lián)起來(lái)(圖 8)。
圖 8:應(yīng)用開(kāi)發(fā)人員使用藍(lán)牙的發(fā)布-訂閱模型將設(shè)備組合成功能分組,例如由一個(gè)或多個(gè)開(kāi)關(guān)控制的一組燈。(圖片來(lái)源:Silicon Labs)
通過(guò)這種方法,數(shù)個(gè)智能燈泡可以訂閱一個(gè)開(kāi)關(guān)發(fā)布者。當(dāng)最終用戶激活該開(kāi)關(guān)時(shí),其將發(fā)布 ON/OFF 事件。該事件將通過(guò)網(wǎng)狀網(wǎng)絡(luò)級(jí)聯(lián)到訂閱的智能燈泡,其事件處理程序?qū)⒉扇∵m當(dāng)?shù)牟僮?。Silicon Labs 樣例代碼演示了這一過(guò)程:首先是網(wǎng)狀網(wǎng)絡(luò)中的聯(lián)網(wǎng)開(kāi)關(guān)發(fā)布 ON/OFF 請(qǐng)求(列表 3),然后是聯(lián)網(wǎng)燈的相應(yīng)響應(yīng)(列表 4)。
/**
* This function publishes one on/off request to change the state of light(s) in the group.* Global variable switch_pos holds the latest desired light state, possible values are
* switch_pos = 1 -》 PB1 was pressed, turn lights on
* switch_pos = 0 -》 PB0 was pressed, turn lights off
*
* This application sends multiple requests for each button press to improve reliability.* Parameter retrans indicates whether this is the first request or a re-transmission.* The transaction ID is not incremented in case of a re-transmission.*/
void send_onoff_request(int retrans)
{
uint16 resp;
uint16 delay;
struct mesh_generic_request req;
req.kind = mesh_generic_request_on_off;
req.on_off = switch_pos ?MESH_GENERIC_ON_OFF_STATE_ON : MESH_GENERIC_ON_OFF_STATE_OFF;
// increment transaction ID for each request, unless it‘s a retransmission
if (retrans == 0) {
trid++;
}
/* delay for the request is calculated so that the last request will have a zero delay and each
* of the previous request have delay that increases in 50 ms steps.For example, when using three
* on/off requests per button press the delays are set as 100, 50, 0 ms
*/
delay = (request_count - 1) * 50;
resp = gecko_cmd_mesh_generic_client_publish(
MESH_GENERIC_ON_OFF_CLIENT_MODEL_ID,
_my_index,
trid,
0, // transition
delay,
0, // flags
mesh_generic_request_on_off, // type
1, // param len
&req.on_off /// parameters data
?。?》result;
if (resp) {
printf(gecko_cmd_mesh_generic_client_publish failed,code %x\r\n, resp);
} else {
printf(request sent, trid = %u, delay = %d\r\n, trid, delay);
}
}
列表 3:這個(gè)來(lái)自 Silicon Labs 網(wǎng)狀網(wǎng)絡(luò)開(kāi)關(guān)樣例應(yīng)用程序的代碼片段說(shuō)明了如何使用藍(lán)牙 5 發(fā)布過(guò)程 (gecko_cmd_mesh_generic_client_publish) 來(lái)請(qǐng)求訂閱該事件流的燈的狀態(tài)改變(開(kāi)或關(guān))。(代碼來(lái)源:Silicon Labs)
static void onoff_request(uint16_t model_id,
uint16_t element_index,
uint16_t client_addr,
uint16_t server_addr,
uint16_t appkey_index,
const struct mesh_generic_request *request,
uint32_t transition_ms,
uint16_t delay_ms,
uint8_t request_flags)
{
printf(ON/OFF request: requested state=《%s》, transition=%u, delay=%u\r\n,
request-》on_off ?ON : OFF, transition_ms, delay_ms);
if (lightbulb_state.onoff_current == request-》on_off) {
printf(Request for current state received; no op\n);
} else {
printf(Turning lightbulb 《%s》\r\n, request-》on_off ?ON : OFF);
if (transition_ms == 0 && delay_ms == 0) { // Immediate change
lightbulb_state.onoff_current = request-》on_off;
lightbulb_state.onoff_target = request-》on_off;
if (lightbulb_state.onoff_current == MESH_GENERIC_ON_OFF_STATE_OFF) {
LED_set_state(LED_STATE_OFF);
} else {
LED_set_state(LED_STATE_ON);
}
} else {
// Current state remains as is for now
lightbulb_state.onoff_target = request-》on_off;
LED_set_state(LED_STATE_TRANS); // set LEDs to transition mode
gecko_cmd_hardware_set_soft_timer(TIMER_MS_2_TIMERTICK(delay_ms + transition_ms), TIMER_ID_TRANSITION, 1);
}
lightbulb_state_store();
}
if (request_flags & MESH_REQUEST_FLAG_RESPONSE_REQUIRED) {
onoff_response(element_index, client_addr, appkey_index);
} else {
onoff_update(element_index);
}
}
列表 4:Silicon Labs 網(wǎng)狀網(wǎng)絡(luò)燈樣例包括用于特定應(yīng)用級(jí)事件的例程,例如這個(gè)打開(kāi)或關(guān)閉 LED 以響應(yīng)開(kāi)關(guān)所發(fā)布請(qǐng)求的函數(shù)(參見(jiàn)列表 3)。(代碼來(lái)源:Silicon Labs)
除了用于節(jié)點(diǎn)開(kāi)發(fā)的藍(lán)牙堆棧和 SDK 之外,Silicon Labs 還提供了藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)的最終環(huán)節(jié)——連接移動(dòng)設(shè)備。大多數(shù)移動(dòng)設(shè)備支持藍(lán)牙 4,雖然其無(wú)線電可以支持藍(lán)牙 5 要求,但它們沒(méi)有支持藍(lán)牙 5 網(wǎng)狀網(wǎng)絡(luò)層的堆棧。Silicon Labs 為移動(dòng)應(yīng)用開(kāi)發(fā)人員提供了額外的軟件堆棧來(lái),而該堆??商峁┚W(wǎng)狀網(wǎng)絡(luò)功能,因此便能克服這一局限性(圖 9)。
圖 9:開(kāi)發(fā)人員可以將 Silicon Labs 針對(duì)移動(dòng)設(shè)備的網(wǎng)狀網(wǎng)絡(luò)堆棧添加到其移動(dòng)應(yīng)用中,使得藍(lán)牙 4 移動(dòng)設(shè)備可以在藍(lán)牙 5 網(wǎng)狀網(wǎng)絡(luò)中使用。(圖片來(lái)源:Silicon Labs)
總結(jié)
藍(lán)牙 5 網(wǎng)狀網(wǎng)絡(luò)為各種各樣已經(jīng)利用智能手機(jī)和其他移動(dòng)設(shè)備進(jìn)行點(diǎn)對(duì)點(diǎn)通信的應(yīng)用提供了一個(gè)自然的過(guò)渡。然而,藍(lán)牙 5 網(wǎng)狀網(wǎng)絡(luò)的部署對(duì)硬件和軟件設(shè)計(jì)提出了重大挑戰(zhàn),特別是在物聯(lián)網(wǎng)等功耗受限的應(yīng)用中。此外,硬件工程師需要滿足最小基底面和低功耗的要求,軟件工程師則需要構(gòu)建使用最少資源來(lái)執(zhí)行復(fù)雜通信協(xié)議的軟件。BGM13P 模塊、SLWSTK6101C 開(kāi)發(fā)板以及節(jié)點(diǎn)和移動(dòng)設(shè)備的藍(lán)牙堆棧的結(jié)合,使工程師有一個(gè)綜合性平臺(tái)來(lái)快速開(kāi)發(fā)使用藍(lán)牙網(wǎng)狀網(wǎng)絡(luò)的應(yīng)用
評(píng)論
查看更多