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