本文從功能需求的角度分析一般藍牙BLE單芯片的應用框架(SDK Framework)的接口設計過程,並以TI CC2541為例說明BLE的應用開發方法。
一、應用框架(Framework)
我們熟知的Framework包括Android Framework、Linux QT、Windows MFC。應用框架抽象並封裝實現了一般應用場景的需求,完成應用開發的80%,剩下的20%則以回調(callback)和接口的方式供應用開發人員調用以完成具體的需求。
一般Framework完成的工作包括:任務分發、消息通信和UI等。例如以上三種框架所屬的IDE都能夠實現所見即所得的UI可視化編程,框架完成了UI控件的大部分工作,而開發人員只需要完成UI控件的消息處理邏輯即可,如點擊了這個button后如何進行響應等。
藍牙BLE單芯片的系統架構包括操作系統、SOC硬件抽象接口和藍牙應用框架等組成部分,操作系統和SOC硬件抽象接口的理解請理解《如何快速理解一個全新的嵌入式操作系統》(發送55獲取)和《如何快速理解一個全新的嵌入式操作系統(續)》(發送56獲取)。本文只討論藍牙應用方面框架接口設計和應用開發。
二、 藍牙BLE的應用需求
我們都知道BLE是為了實現連接后的通信傳輸和控制。BLE設計的初衷是為了完成少數據量的通信,側重於通信控制。所以我們可以理解BLE的協議棧包括兩大組成部分:一個是藍牙連接;另一個是通信控制。前者即對應GAP(General Access Profile),后者對應GATT(General Attribute Profile)。Profile在藍牙術語里面相應於特定的應用場景協議。
三、 藍牙BLE的應用需求分析
我們分別對連接和通信控制進行分析。這里以藍牙設備Peripheral角色進行分析,簡單理解即是從設備。手機APP所用的藍牙一般充當central角色,即主設備。
1. 連接
連接部分,藍牙外設要完成的功能包括:
1) 藍牙外設要被發現,其必須要進行廣播
2) 在主設備掃描時要給出掃描響應。這時藍牙設備還是處於廣播狀態。
3) 主設備發起連接時,其可以要求密碼配對,而也可以選擇無需密碼驗證。
4) 主設備發起連接過程的握手,接受連接。
5) 藍牙外設連接成功后才會開啟通信服務。
2. 通信控制
1) 藍牙外設在連接后通過GATT來提供服務發現(service discover),這樣主設備能夠從中獲取藍牙外設提供的各種服務profile。
2) 主設備在獲取藍牙外設服務后,會對GATT profile的各種特征字(characteristics)進行讀寫傳輸控制。
3) 特征字主要包含write、read、notify和indicate等主要通信方式。對於藍牙外設的write特征字,主設備(如手機)可以進行寫操作;對於read,主設備則可以從中讀取信息;write和read對於藍牙外設來說,其屬於被動控制,即藍牙外設被動接受主控制的通信控制。而notify和indicate則是藍牙外設主動向主設備傳輸數據,前提是主設備要預先訂閱對應的characteristics的信息更新。Notify數據后,主設備不需要應答響應,而indicate則需要應答響應。
四、 藍牙BLE的應用框架(framework)設計
我們之前已經分析過,framework應該完成應用開發的80%工作,即基本完成了常見的應用需求。剩下20%則是由各個具體應用的具體場景需求來決定的。例如,藍牙底層連接時怎么握手,咱們應用開發人員不需要關心吧;GATT的characteristics value值的通信過程,我們不要關心吧。當藍牙外設有新的數據要傳輸給主設備時,只需要調用notify或者indicate接口就可以了,至於底層怎么實現,那是協議棧開發人員的工作。
OK,咱們根據第三部分的需求分析來找出應用開發人員所關心的20%工作任務。換句話來說,剩下的80%工作量即是藍牙應用框架Framework所要完成的任務。一般藍牙單芯片都會給用戶提供SDK進行開發,其里面已經實現framework了。我們應用開發人員應當重點關注這20%的任務。
1. 連接
1) 對於廣播來說,不同的應用需要廣播的信息並不一樣,如ibeacon和微信airsync協議的廣播數據格式要求是不一樣的。所以,framework應該提供給用戶一個自定義廣播數據的接口。
2) 同理,framework應該提供給用戶一個自定義掃描響應數據的接口。
3) 對於密碼配對過程,常見的做法是framework給應用開發提供一個回調接口,當收到主設備傳送過來的密碼后,對這個接口進行回調,並將這個密碼以參數的形式傳遞給這個接口,以讓用戶自己判斷密碼是否跟預設的一致。
4) Framework應該對連接的狀態進行管理,分別提供用戶回調接口,在連接成功時對接口進行回調,以讓用戶在連接成功時做一些特定的操作,如閃燈標識、開啟GATT服務等;在斷開連接時也應該回調用戶接口,以讓用戶在斷開連接時做一些特定的操作。
2. 通信控制
我們這里還是只分析藍牙外設Peripheral角色的framework,不探討主設備的framework,讀者可以相應進行分析。
1)framework應該明確如何用最簡單的方式定義並添加一個藍牙GATT profile服務。藍牙BLE有自己的協議標准,一個藍牙服務service包括一個或者多個characteristics,而每個characteristics都包含對應UUID、屬性描述(如可讀、可寫、長度等)、屬性值value、屬性配置(代表訂閱信息)等等。
為了簡化后續的數據處理,一般framework會設置一個handle來對應一個characteristics。
2)framework提供接口給用戶來對各個characteristics的屬性value進行設置和獲取。
3)framework提供回調接口給用戶,當主設備讀characteristics回調讀接口,以讓用戶進行特定操作后再進行傳輸;當主設備寫characteristics時回調寫接口,以讓用戶完成相應的操作。
4)framework提供用戶接口,完成主動的notify和indicate操作。
OK,以上即是藍牙BLE單芯片普遍的framework設計需求。我們在接觸一款新的BLE單芯片時,只要能夠重點把握好以上這20%的編程方法,就能快速進行應用開發。
五、Ti CC2541應用開發
TI CC2541 SDK有一個簡單的示例工程SimpleBLEPeripheral,向開發人員展現如何進行藍牙應用開發。我們通過這個工程來理解上述框架設計和編程。
1. 連接
1)定義廣播數據
GAPRole_SetParameter(GAPROLE_ADVERT_DATA,…);
2)自定義掃描響應數據
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA,…);
3)密碼管理回調
ProcessPasscodeCB()
4)狀態管理回調
peripheralStateNotificationCB()
2.通信控制
1)添加GATT服務
GATTServApp_RegisterService()
2)讀回調
simpleProfile_ReadAttrCB()
3)寫回調
simpleProfile_WriteAttrCB()
4 )屬性值設置和獲取
SimpleProfile_SetParameter()
SimpleProfile_GetParameter()
5)主動傳輸
GATT_Notification()
GATT_Indication()
參數可以對照具體的接口進行分析。我們在看具體的接口之前,可以思考一下,這些接口的參數應該包括什么東西,如果你能想到包括什么,恭喜你,你的應用框架設計能力已經大大提高了。
