藍牙4.0之二 OSAL(操作系統抽象)層工作原理

1、BLE系統架構

2、OSAL啓動流程

Main()

==> HAL_BOARD_INIT();//初始化硬件

==> InitBoard( OB_COLD );//初始化板卡IO

==> HalDriverInit(); //hal層驅動初始化

==> osal_snv_init();//初始化Flash

==> osal_init_system();   //初始化OSAL

===>osal_mem_init();//初始化內存分配系統

===>osal_qHead = NULL;//初始化消息隊列

===>osalTimerInit();//初始化定時器

===>osal_pwrmgr_init();//初始化電源管理系統

===>osalInitTasks(); //初始化系統任務

===> 建立任務事件位圖內存 uint16  XXX[taskCnt] (tasksEvents 爲uint16 *指針)

===>初始化任務ID taskID = 0;

===> LL_Init( taskID++ );  //鏈路層任務初始化;對應tasksArr[0]=LL_ProcessEvent()

===> Hal_Init( taskID++ ); //硬件抽象層  ;對應tasksArr[1]=Hal_ProcessEvent()

===> HCI_Init( taskID++ ); //主機控制器接口;對應tasksArr[2]=HCI_ProcessEvent()

===>osal_CbTimerInit(taskID); //定時器任務初始化; 對應tasksArr[3]=osal_CbTimerProcessEvent()

===> GAP_Init( taskID++ );  //通用訪問 配置文件層 ;對應tasksArr[4]=GAP_ProcessEvent()

===> GAPRole_Init( taskID++ );   //通用屬性 配置文件層;對應tasksArr[5]=GAPRole_ProcessEvent()

===>設置全局變量gapRole_TaskID=task_id;

===> gapRole_state = GAPROLE_INIT; // 設定角色的狀態爲 <等待被啓動>

//GAPROLE_STARTED<啓動但未廣播>、GAPROLE_ADVERTISING<當前正在廣播>、GAPROLE_WAITING<當前未廣播>、GAPROLE_ERROR<當前是無效的狀態>

===>GAP_RegisterForHCIMsgs()  //註冊控制接口的任務ID

===>//初始化廣播配置文件和連接參數

===>gapRole_profileRole = GAP_PROFILE_BROADCASTER;

// 設置設備配置角色;爲一種只發送廣播事件的設備

===>gapRole_AdvEventType = GAP_ADTYPE_ADV_NONCONN_IND;

// 設置事件類型:爲不可以被連接,不可以被掃描。

===>gapRole_AdvDirectType = ADDRTYPE_PUBLIC;

// 設置GAP地址類型:ADDRTYPE_PUBLIC

===>gapRole_AdvChanMap = GAP_ADVCHAN_ALL;

// 廣播頻道選擇(3個)GAP_ADVCHAN_ALL

===>gapRole_AdvFilterPolicy = GAP_FILTER_POLICY_ALL;

// 廣播過濾策略選擇;

===>simpleBLEBroadcaster_Init( taskID ); //應用層的初始化;對應tasksArr[6]=SimpleBLEBroadcaster_ProcessEvent()

===>//廣播的開啓/關閉

uint8 initial_advertising_enable = TRUE;

GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );

===>// 無限期關閉廣播,直到廣播再次使能。

uint16 gapRole_AdvertOffTime = 0;

GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );

===>// 設置廣播掃描響應數據

GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );

===>// 設置廣播數據

GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( mb_advertData ), advertData );

===>// 設置廣播的類型爲.

uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; (不可被連接,可被掃描)

GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );

===>// 廣播時間間隔設置;

uint16 advInt = DEFAULT_ADVERTISING_INTERVAL; (100ms)

GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );

GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );

GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );

GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );

===>// 如何定義了 CC2540_MINIDK 宏,註冊所有的按鍵事件到本任務

RegisterForKeys( simpleBLEBroadcaster_TaskID );

===>// 如何定義了 CC2540_MINIDK 宏,關閉所有的LED

HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );

===>// 如何定義了 CC2540_MINIDK 宏,GPIO使能、輸入輸出模式、認輸出電平的配置。

===>// LED提示字符串顯示

HalLcdWriteString( "BLE Broadcaster", HAL_LCD_LINE_1 );

===>//通過osal_set_event() 註冊一個延遲的事件:SBP_START_DEVICE_EVT(設備啓動觸發事件)

osal_set_event( simpleBLEBroadcaster_TaskID, SBP_START_DEVICE_EVT );

===>osal_mem_kick()

==> HAL_ENABLE_INTERRUPTS(); //使能中斷

==> InitBoard( OB_READY ); //板卡最後初始化

==> osal_start_system(); // No Return from here (啓動OSAL)

===>for(;;){osal_run_system()} // 死循環,不斷執行osal_run_system()

===>osal_run_system() // 循環體

===>Hal_ProcessPoll() //處理輪詢

===>HalUARTPoll() //串口輪詢

===>usbHidProcessEvents()//人性化接口輪詢(如本接口的鍵盤)

===>遍歷1遍任務事件位圖 tasksEvents[idx],有任務中的事件註冊觸發了就退出,以便處理.

===>記錄任務中的事件到uint16 events;並清0任務事件位圖中的相應任務域。

===>根根據taskid,回調不同的任務處理函數 tasksArr[idx],(傳入事件events量);並返回一個events。

===>SimpleBLEBroadcaster_ProcessEvent() // 用戶定義的事件處理函數(爲例子分析)

===> if ( events & SYS_EVENT_MSG ) //若有pMsg等待接收事件

===>if ( (pMsg = osal_msg_receive( simpleBLEBroadcaster_TaskID )) != NULL )// 獲得pMsg

===>simpleBLEBroadcaster_ProcessOSALMsg()// 處理pMsg(osal_event_hdr_t類型)

===> switch判斷pMsg->event == KEY_CHANGE // 是按鍵事件嗎,否退出

===>將osal_event_hdr_t 強制轉換爲具體事件描述--按鍵事件類型 keyChange_t。

===>simpleBLEBroadcaster_HandleKeys() // 處理按鍵事件

===>if ( keys & HAL_KEY_SW_2 )//若按下ringht鍵就執行一定處理(如開關廣播)。

===>osal_msg_deallocate() //清除消息pMsg內存

===> if ( events & SBP_START_DEVICE_EVT )  //若有啓動設備事件

===>GAPRole_StartDevice() //處理啓動設備事件

===>if ( gapRole_state == GAPROLE_INIT ) //如果鏈路狀態是初始化狀態

===>將GAP回調函數集simpleBLEBroadcaster_BroadcasterCBs記錄到全局的便利pGapRoles_AppCGs,等待被執行。

===> 執行gapRole_SetupGAP() // 開始建立鏈路;

===>將新的返回的events任務寫回註冊到tasksEvents[idx],等待被處理。


3、OSAL工作原理示意圖

 

4、事件表和函數表

 

5、OSAL層API接口

https://blog.csdn.net/u014647208/article/details/52637067?utm_source=blogxgwz6

 

6、感謝華清創客學院  makeru.com.cn

        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章