




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第十五節(jié) BLE藍牙4.0協(xié)議棧啟動分析 TI的這款CC2540/CC2541器件可以單芯片實現(xiàn)BLE藍牙協(xié)議棧結構圖的所有組件,包括應用程序。從這章開始我們來剖析協(xié)議棧源碼,我們選用SimpleBLEPeripheral工程開刀,這是一個從機的例程,基本的工作是對外廣播,等待主機來連接,讀寫展示的屬性。 首先打開工程文件,打開后可以看到整個工程的結構。 我們按照系統(tǒng)的啟動順序來一步一步走,我們都知道在C代碼中,一般啟動的首個函數(shù)為main,這個函數(shù)在SimpleBLEPeripheral_Main.c中,打開文件,
2、可以看到這個文件只有一個main函數(shù)和一個函數(shù)的申明,我們暫時不理會那個申明的函數(shù),先看main都做了些什么工作:?12345678910111213141516171819202122232425262728293031323334Int main(void) /* Initialize hardware */ HAL_BOARD_INIT(); / 硬件初始化 / Initialize board I
3、/O InitBoard( OB_COLD ); / 板級初始化 /* Initialze the HAL driver */ HalDriverInit(); / Hal驅動初始化 /* Initialize NV system */ &
4、#160;osal_snv_init(); / Flash存儲SNV初始化 /* Initialize LL */ /* Initialize the operating system */ osal_init_system(); / OSAL初始化
5、 /* Enable interrupts */ HAL_ENABLE_INTERRUPTS(); / 使能總中斷 / Final board initialization InitBoard( OB_READY ); / 板級初始化 #if defined ( POWER_SAVING )
6、0;osal_pwrmgr_device( PWRMGR_BATTERY ); / 低功耗管理 #endif /* Start OSAL */ osal_start_system(); / No Return from here 啟動OSAL return 0; 通過代碼我們可以看到,系統(tǒng)啟動的過程,主要是做了一些初始化,如果開啟了低功耗,則還需要開啟低功耗管理。我們先不去理會初始化做了什么,但是我們知道在main函數(shù)的最后啟動了OSA
7、L,那么我們就進去看看OSAL是如何運作的。 在IAR中如果需要跳轉到某個函數(shù)或變量的定義,可以在此函數(shù)名中右擊然后選擇Go To Definition就可以調到相應的定義。?123456789void osal_start_system( void ) #if !defined ( ZBIT ) && !defined ( UBIT ) for(;) / Forever Loop #endif osal_run_system();
8、; 這里看到我們進入了一個死循環(huán),并且一直調用osal_run_system(),那我們再進入此函數(shù)。?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849</blockquote></div><div style="text-align: left;"><div class="blockcode"><blockquote>void
9、 osal_run_system( void ) uint8 idx = 0; #ifndef HAL_BOARD_CC2538 osalTimeUpdate(); / 定時器更新 #endif Hal_ProcessPoll(); / Hal層信息處理 do if (tasksEventsidx) / Task is highest priority th
10、at is ready. break; while (+idx < tasksCnt); / 檢查每個人任務是否有事件 if (idx < tasksCnt) / 有事件發(fā)生 uint16 events; &
11、#160;halIntState_t intState; HAL_ENTER_CRITICAL_SECTION(intState); / 進入臨界區(qū) events = tasksEventsidx; tasksEventsidx = 0; / Clear the Events for this task. 清除事件標志 HAL_EXIT_CRITICAL_SECTION
12、(intState); / 退出臨界區(qū) activeTaskID = idx; events = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù) activeTaskID = TASK_NO_TASK; HAL_ENTER_CRITICAL_SECTION(intState);
13、 / 進入臨界區(qū) tasksEventsidx |= events; / Add back unprocessed events to the current task. HAL_EXIT_CRITICAL_SECTION(intState); / 退出臨界區(qū) #if defined( POWER_SAVING ) / 沒有事件發(fā)生
14、,并且開啟了低功耗模式 else / Complete pass through all task events with no activity? / 系統(tǒng)進入低功耗模式 osal_pwrmgr_powerconserve(); / Put the processor/system into sleep #endif /* Yield in case cooperative scheduling is being used
15、. */ #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION = 0) osal_task_yield(); #endif 在這里可以看到這個OSAL的核心,整個OSAL通過檢測每個任務是否有事件發(fā)生,如果有則執(zhí)行相應的任務,處理相應的事件。如果沒有事件需要處理并且開啟了低功耗模式,則系統(tǒng)就會進入低功耗模式。 這里有一個很關鍵的地方,OSAL是如何知道哪個事件
16、需要哪個任務來處理呢??1events = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù) 我們看這里有一個很關鍵的數(shù)組tasksArr,很顯然,這是一個函數(shù)指針數(shù)組,我們看看它的定義。?1234567891011121314151617const pTaskEventHandlerFn tasksArr = LL_ProcessEvent,
17、160; / task 0 Hal_ProcessEvent,
18、; / task 1 HCI_ProcessEvent,
19、160; / task 2 #if define
20、d ( OSAL_CBTIMER_NUM_TASKS ) OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), / task 3 #endif L2CAP_ProcessEvent,
21、 / task 4 GAP_ProcessEvent,
22、60; / task 5 GATT_ProcessEvent,
23、; / task 6 SM_ProcessEvent,
24、60; / task 7 GAPRole_ProcessEvent,
25、160; / task 8 GAPBondMgr_ProcessEvent,
26、0; / task 9 GATTServApp_ProcessEvent,
27、; / task 10 SimpleBLEPeripheral_ProcessEvent
28、0; / task 11 ; 可以看到在這個數(shù)組的定義中,每個成員都是任務的執(zhí)行函數(shù),按照任務的優(yōu)先級排序,并且在osalInitTasks中初始化的時候,我們可以看到每個任務都有一個對應的初始化函數(shù),并且傳遞了一
29、個taskID,此ID從0開始自增,這里有一點非常重要,初始化的順序和任務數(shù)組的定義順序是一樣的,這就保證了我們給任務發(fā)生消息或事件時能夠準確的傳遞到相應的任務處理函數(shù)。?12345678910111213141516171819202122232425262728293031323334353637383940414243void osalInitTasks( void ) uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt)
30、; osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt); /* LL Task */ LL_Init( taskID+ ); /* Hal Task */ Hal_Init( taskID+ ); /* HCI Task */ HCI_Init( taskID+ ); #if defined ( OSAL_CBTIMER_NUM_TASKS )
31、60;/* Callback Timer Tasks */ osal_CbTimerInit( taskID ); taskID += OSAL_CBTIMER_NUM_TASKS; #endif /* L2CAP Task */ L2CAP_Init( taskID+ ); /* GAP Task */ GAP_Init( taskID+ ); /* GATT Task */ GATT_Init( ta
32、skID+ ); /* SM Task */ SM_Init( taskID+ ); /* Profiles */ GAPRole_Init( taskID+ ); GAPBondMgr_Init( taskID+ ); GATTServApp_Init( taskID+ ); /* Application */ SimpleBLEPeripheral_Init( taskID );
33、60; 應用層的初始化SimpleBLEPeripheral_Init,SimpleBLEPeripheral_Init( uint8task_id )主要對 GAP 和 GATT 進行配置,最后調用osal_set_event(simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT )啟動設備。 設備啟動后應用層就能接收到這個設置的事件并進行處理,可以看到設備啟動中主要是啟動設備,注冊綁定管理,并且啟動了一個定時器,這個定時器是一個周期事件的第一次啟動。 周期事件中每次都會重啟這個定時器,并且處理周
34、期事件。 在初始化的時候我們注冊了一個很重要的函數(shù),設備狀態(tài)改變時的回調函數(shù),這個函數(shù)在設備的狀態(tài)改變時會被底層的協(xié)議棧回調,我們可以從這個回調函數(shù)中看的設備的狀態(tài)的改變。 static void peripheralStateNotificationCB( gaprole_States_t newState); 從函數(shù)的定義可以看出,設備的狀態(tài)類型都在數(shù)據(jù)類型gaprole_States_t中定義了,我們看一下這個數(shù)據(jù)類型的定義:?1234567891011typedef enum GAPR
35、OLE_INIT = 0, /!< Waiting to be started GAPROLE_STARTED, /!< Started but not advertising GAPROLE_ADVERTISING,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公路波形欄桿施工合同范本
- 小學音樂教學中體態(tài)律動的應用
- 全款買房房屋合同范本
- 單位訂制酒瓶合同范本
- 北京租地種菜合同范本
- 動力變檢修合同范本
- 農家菠菜售賣合同范本
- 醫(yī)院建筑改造合同范本
- 農村水果收購合同范本
- 修車工合同范本模板
- 前交叉韌帶損傷PPT
- 數(shù)學四年級下冊口算題(每頁60道直接打印)
- 膳食委員會工作方案
- 四大名著《西游記》語文課件PPT
- 《儒林外史》課件(共53張PPT)
- GB/T 33144-2016超硬磨料沖擊韌性測定方法
- GB/T 12496.19-2015木質活性炭試驗方法鐵含量的測定
- 中醫(yī)藥膳學全套課件
- 新目標英語七年級期末考試質量分析
- 經(jīng)濟學論文的選題與寫作課件
- 廣東省開平市人民法院執(zhí)行款收取賬戶確認書【模板】
評論
0/150
提交評論