在作者之前發表的《全球最低功耗藍牙單芯片DA14580的系統架構和應用開發框架分析》、《全球最低功耗藍牙單芯片DA14580的硬件架構和低功耗》、《全球最低功耗藍牙單芯片DA14580的軟件體系-RW內核和消息處理機制》三篇文章分析了DA14580的SDK開發目錄結構、硬件架構、低功耗、RW內核和消息處理機制。本篇文章將深入到具體的源碼去分析DA14580平台的軟件層次架構和具體的BLE消息處理過程,以此佐證前面發表的文章。
一、軟件層次架構
1.1 BLE協議棧
從中,我們可以看到,BLE協議棧可以大致分為應用層、profile服務層、BLE Host層(軟件實現)、BLE controller層(硬件實現,屬於基帶部分),實際上硬件物理層還有射頻層radio,即將基帶信息調制到2.4G進行發射或者進行解調。
BLE host實現數據適配L2CAP、鏈路管理GAP、基礎屬性協議ATT,GATT是基於ATT進行封裝並向上層提供接口服務,以讓用戶更方便地使用ATT來進行數據交互。他們都分別對應RW內核的一個或者多個task,例如GAP包括GAP管理和GAP控制兩個task。
Profile層是基於GATT來向應用層提供數據通信服務的,每個profile都負責自己的專有的服務功能。例如,有電池服務、設備信息服務和自定義的一些profile等等。
GATT是負責基礎的數據通信,而profile則是在GATT的基礎上進行數據的本地處理。例如,GATT收到對方的寫請求時會通知profile,由profile來決定怎么處理接收到的數據,可以寫到屬性字段中,也可以不寫,profile也可以進一步給task_app發送通知。
各個profile是獨立並且平等的,因為各個GATT都是平等服務的。每個profile都對應RW內核的一個task。
應用層是基於多個profile來實現自己的需求。由於RW內核實質是一個單任務內核,所以應用層是一個特別的task。其和所有的profile打交道,其控制所有profile,並處理各個profile的消息回調。
1.2 task層次
根據上面的分析,我們可以得到以下task層次圖:
1.3 task列表
其定義在rwip_config.h中,如下:
可見,RW內核最大支持64個task,鏈路層task的優先級高,接着是profile,再是TASK_APP。
二、基於狀態機的RW內核消息處理機制
Task數據結構如下:
RW內核是基於狀態機對消息進行處理的。從ke_task_desc看來,一個task包括顯式的狀態處理state_handler和默認的狀態處理default_handler。
state是task的狀態機變量,task可能有多個狀態,那么state_handler是狀態處理集合,每個狀態可能會處理多個消息回調,例如上層task會發送消息來執行調用,或者下層task發送消息來執行回調。
default_handler處理的消息代表該task在任意狀態時都可能受到的消息,例如底層task發出的斷開連接消息。
我們也可以得出,ke_state_handler代表一個狀態下的多個消息處理。因此,state_handler是一個ke_state_handler數組,而default_handler則是ke_state_handler元素。
三、app_task
如上所述,app_task是一個特殊的task,它和所有的profile_tasks進行交互,執行調用和回調。基於RW內核的狀態機消息處理機制,調用和回調都是通過發送消息來進行完成回調的。
app_task是通過ke_task_create(TASK_APP, &TASK_DESC_APP)來注冊消息回調的,而TASK_DESC_APP賦值為:
TASK_DESC_APP= {NULL, &app_default_handler, app_state,APP_STATE_MAX, APP_IDX_MAX};
可見,app_task只有默認的消息回調接口集app_default_handler。如下:
默認的消息回調接口集包括了GAP相關的消息(紅色圈的部分),如BLE初始化過程的消息事件,和profile應用相關的數據通信消息事件。
接下來,我們着重分析GAP相關的消息事件,闡述BLE初始化的主要過程。
四、初始化過程
4.1 BLE初始化
Main_func函數中調用rwip_init()接口對RW的BLE部分進行初始化。該接口是固化代碼,不對外公開。BLE初始化執行的過程中會發出相應的消息事件給app_task,以告訴app_task相應的狀態,便於app_task主動執行調用下一階段的初始化。
4.2 初始化過程分析
1. GAPM_DEVICE_READY_IND
可見,當BLE初始化好后發出的第一個消息事件是GAPM_DEVICE_READY_IND。內核會執行回調gapm_device_ready_ind_handler,在該回調里面會向TASK_GAPM發出GAPM_RESET_CMD消息,即reset GAP管理模塊。
2. GAPM_CMP_EVT
當TASK_GAPM reset好管理模塊后,會向task_app發出GAPM_CMP_EVT消息事件,內核會執行gapm_cmp_evt_handler,該回調會向TASK_GAPM發出GAPM_SET_DEV_CONFIG_CMD命令,以完成BLE設備配置。
3. GAPM_CMP_EVT
當TASK_GAPM完成設備配置時,會再次向task_app發送GAPM_CMP_EVT消息,內核會執行gapm_cmp_evt_handler,這時會調用app_set_dev_config_complete_func,里面調用app_db_init創建GATT屬性數據庫。
app_db_init里面會向各個profileXXX_task發送一條XXX_CREATE_DB_REQ創建屬性數據庫的命令消息。
4. XXX_CREATE_DB_CFM
各個profile調用GATT接口完成創建后,會向task_app發送XXX_CREATE_DB_CFM消息事件。內核會執行相應的回調,回調會向task_app(即自己發給自己)發送一個APP_MODULE_INIT_CMP_EVT消息。
5. APP_MODULE_INIT_CMP_EVT
內核會執行app_module_init_cmp_evt_handler回調,該回調會再次調用app_db_init,回到第4步繼續進行。當app_db_init發現所有profile的屬性數據庫都創建完畢時,會調用app_db_init_complete_func接口,該接口會開始廣播,並開始應用相關的處理過程。
五、GAP建立連接過程的消息回調
Todo
六、數據通信過程中的消息回調
Todo
參考文獻:《UM-B-015_DA14580 Software architecture v4.0.pdf》、《RW-BT-KERNEL-SW-FS.pdf》。
下一篇:
全球最低功耗藍牙單芯片DA14580的軟件體系
-GAP建立連接和數據通信過程
-
嵌入式企鵝圈原創團隊由阿里、魅族、nvidia、龍芯、炬力、拓爾思等資深工程師組成。百分百原創,每周兩篇,分享嵌入式、Linux、物聯網、GPU、Android、自動駕駛等技術。歡迎掃碼關注微信公眾號:嵌入式企鵝圈,實時推送原創文章!