由淺入深藍(lán)牙40BLE協(xié)議棧開(kāi)發(fā)攻略大全3_第1頁(yè)
由淺入深藍(lán)牙40BLE協(xié)議棧開(kāi)發(fā)攻略大全3_第2頁(yè)
由淺入深藍(lán)牙40BLE協(xié)議棧開(kāi)發(fā)攻略大全3_第3頁(yè)
由淺入深藍(lán)牙40BLE協(xié)議棧開(kāi)發(fā)攻略大全3_第4頁(yè)
由淺入深藍(lán)牙40BLE協(xié)議棧開(kāi)發(fā)攻略大全3_第5頁(yè)
已閱讀5頁(yè),還剩18頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、本系列教程將結(jié)合TI推出的CC254x SoC 系列,講解從環(huán)境的搭建到藍(lán)牙4.0協(xié)議棧的開(kāi)發(fā)來(lái)深入學(xué)習(xí)藍(lán)牙4.0的開(kāi)發(fā)過(guò)程。教程共分為六部分,本文為第三部分:第三部分知識(shí)點(diǎn):第十一節(jié) 串口通信第十二節(jié) Flash的讀寫第十三節(jié) BLE協(xié)議棧簡(jiǎn)介第十四節(jié) OSAL工作原理第十五節(jié) BLE藍(lán)牙4.0協(xié)議棧啟動(dòng)分析有關(guān)TI 的CC254x芯片介紹,可點(diǎn)擊下面鏈接查看:主流藍(lán)牙BLE控制芯片詳解(1):TI CC2540同系列資料推薦:由淺入深,藍(lán)牙4.0/BLE協(xié)議棧開(kāi)發(fā)攻略大全(1)由淺入深,藍(lán)牙4.0/BLE協(xié)議棧開(kāi)發(fā)攻略大全(2)有關(guān)本文的工具下載,大家可以到以下這個(gè)地址:朱兆祺ForARM

2、第十一節(jié) 串口通信在軟件開(kāi)發(fā)過(guò)程中調(diào)試是一個(gè)很關(guān)鍵的過(guò)程,而調(diào)試用的最多的手段就是打印Log,嵌入式平臺(tái)很少有顯示設(shè)備,所以我們需要將信息通過(guò)串口打印到PC端。MT254xboard上已經(jīng)通過(guò)RS232芯片將UART0連接到DB9,我們只需要將DB9連接到電腦即可,UART0 對(duì)應(yīng)的外部設(shè)備 IO 引腳關(guān)系為:P0_2-RX,P0_3-TX。我們需要將這兩個(gè)IO配置為復(fù)用功能,CC2540的USART可以配置為SPI模式或者異步UART模式,這里我們需要配置為異步UART模式。首先配置IO為UART模式:PERCFG &= 0x01; / 配置UART為位置 1P0SEL = 0x3c; /

3、P0_2,P0_3,P0_4,P0_5用作串口功能P2DIR &= 0XC0; / P0 優(yōu)先作為UART0配置UART0寄存器,將UART0配置為8N1模式,波特率為115200。U0CSR |= 0x80; / UART 方式U0GCR |= 11; / U0GCR與U0BAUD配合U0BAUD |= 216; / 波特率設(shè)為115200UTX0IF = 0; / 清除中斷標(biāo)志U0CSR |= 0X40; / 允許接收IEN0 |= 0x84; / 開(kāi)總中斷,接收中斷這里采用中斷方式來(lái)接收串口數(shù)據(jù),并在中斷中回調(diào)應(yīng)用層的接收處理函數(shù)。#pragma vector = URX0_VECTOR

4、_interrupt void UART0_ISR(void)uint8 ch;URX0IF = 0; / 清中斷標(biāo)志ch = U0DBUF;if ( NULL != RecvCb ) / 調(diào)用回調(diào)函數(shù)RecvCb(ch);為了測(cè)試串口的通訊功能,這里我們通過(guò)串口接收命令的方式來(lái)控制LED的亮滅和蜂鳴器的響和停止,并且顯示當(dāng)前的狀態(tài)。根據(jù)串口輸出提示,發(fā)送對(duì)應(yīng)字符可以實(shí)現(xiàn)相應(yīng)功能,并且顯示狀態(tài)。第十二節(jié) Flash的讀寫嵌入式系統(tǒng)中需要存儲(chǔ)數(shù)據(jù),而片內(nèi)的Flash資源很匱乏,所以我們經(jīng)常需要使用SpiFlash來(lái)存儲(chǔ)數(shù)據(jù),MT254xboard中板載了一個(gè) 512Kbyte的Flash,下面我

5、們來(lái)驅(qū)動(dòng)此Flash。上一小節(jié)中我們用SPI的方式驅(qū)動(dòng)了LCD12864,這節(jié)我們繼續(xù)用SPI來(lái)驅(qū)動(dòng)板載的 Flash,詳細(xì)的說(shuō)明了如何驅(qū)動(dòng)這片F(xiàn)lash,在此不做累述,我們復(fù)制LCD12864工程,重命名為SpiFlash,在此工程中添加GD25Q40的兩個(gè)驅(qū)動(dòng)文件。下面我們來(lái)檢測(cè)這個(gè)Flash,檢測(cè)的方法為,全部寫入0xAA,然后再讀出,對(duì)比是否為0xAA,如果是,那Flash是沒(méi)有問(wèn)題的,否則Flash可能已經(jīng)有壞塊。具體的代碼見(jiàn)例程,這個(gè)過(guò)程所需要的時(shí)間取決于我們需要檢測(cè)的區(qū)域大小,如果完全檢測(cè),則可能需要幾分鐘的時(shí)間。int main(void)SysStartXOSC();LCD1

6、2864_Init(); / LCD初始化GD25Q40_Init(); / Flash初始化LCD12864_DisStr(0, “Flash Check.。”);sprintf(LCDBuf, “Flash ID :%04X”, GD25Q40_ReadID(); / 讀取器件IDLCD12864_DisStr(1, LCDBuf);GD25Q40_EraseChip(); / 擦除整片F(xiàn)lash 大約需要10SLCD12864_DisStr(2, “Erase Chip Complete”);uint32 iCnt = 0;/ 全部寫入0xAAconst uint8 Write = 0x

7、AA;for(iCnt=0; iCnt CHECK_ADDR_RANGE; iCnt+)GD25Q40_Write(&Write, iCnt, 1); / 寫入0xAA/ 讀取Flash內(nèi)部的值,與寫入的值對(duì)比uint8 Read;for(iCnt=0; iCnt = CHECK_ADDR_RANGE)LCD12864_DisStr(3, “Flash Check Success”);GD25Q40_EraseChip(); / 再次擦除while(1);return 0;MT254X藍(lán)牙4.0開(kāi)發(fā)板Flash效果:第十三節(jié) BLE協(xié)議棧簡(jiǎn)介TI的協(xié)議棧分為兩部分:控制器和主機(jī)。對(duì)于4.0以前

8、的藍(lán)牙,這兩部分是分開(kāi)的。所有profile和應(yīng)用都建構(gòu)在GAP或GATT之上。根據(jù)這張圖,我們從底層開(kāi)始介紹。TI的這款CC2540器件可以單芯片實(shí)現(xiàn)BLE藍(lán)牙協(xié)議棧結(jié)構(gòu)圖的所有組件,包括應(yīng)用程序。1.1.1 PHY層1Mbps自適應(yīng)跳頻GFSK(高斯頻移鍵控),運(yùn)行在免證的2.4GHz。1.1.2 LL層LL層為RF控制器,控制設(shè)備處于準(zhǔn)備(standby)、廣播、監(jiān)聽(tīng)/掃描(scan)、初始化、連接,這五種狀態(tài)中一種。五種狀態(tài)切換描述為:未連接時(shí),設(shè)備廣播信息,另外一個(gè)設(shè)備一直監(jiān)聽(tīng)或按需掃描,兩個(gè)設(shè)備連接初始化,設(shè)備連接上了。發(fā)起聊天的設(shè)備為主設(shè)備,接受聊天的設(shè)備為從設(shè)備,同一次聊天只能

9、有一個(gè)意見(jiàn)領(lǐng)袖,即主設(shè)備和從設(shè)備不能切換。1.1.3 HCI層HCI層為接口層,向上為主機(jī)提供軟件應(yīng)用程序接口(API),對(duì)外為外部硬件控制接口,可以通過(guò)串口、SPI、USB來(lái)實(shí)現(xiàn)設(shè)備控制。1.1.4 L2CAP層L2CAP層提供數(shù)據(jù)封裝服務(wù),允許邏輯上的點(diǎn)對(duì)點(diǎn)通訊。1.1.5 SM層SM層提供配對(duì)和密匙分發(fā),實(shí)現(xiàn)安全連接和數(shù)據(jù)交換。1.1.6 ATT層ATT層負(fù)責(zé)數(shù)據(jù)檢索,允許設(shè)備向另外一個(gè)設(shè)備展示一塊特定的數(shù)據(jù)稱之為屬性,在ATT環(huán)境中,展示屬性的設(shè)備稱之為服務(wù)器,與它配對(duì)的設(shè)備稱之為客戶端。鏈路層的主機(jī)從機(jī)和這里的服務(wù)器、客服端是兩種概念,主設(shè)備既可以是服務(wù)器,也可以是客戶端。從設(shè)備毅然

10、。1.1.7 GATT層GATT層定義了使用 ATT 的服務(wù)框架和配置文件(profiles)的結(jié)構(gòu)。BLE 中所有的數(shù)據(jù)通信都需要經(jīng)過(guò) GATT。GATT負(fù)責(zé)處理向上與應(yīng)用打交道,其關(guān)鍵工作是把為檢索工作提供合適的profile結(jié)構(gòu),而profile由檢索關(guān)鍵詞(characteristics)組成。1.1.8 GAP層GAP直接與應(yīng)用程序或配置文件(profiles)通信的接口,處理設(shè)備發(fā)現(xiàn)和連接相關(guān)服務(wù)。另外還處理安全特性的初始化。對(duì)上級(jí),提供應(yīng)用程序接口,對(duì)下級(jí),管理各級(jí)職能部門,尤其是指示LL層控制室五種狀態(tài)切換,指導(dǎo)保衛(wèi)處做好機(jī)要工作。1.2 TI協(xié)議棧源碼介紹在第二章我們講解了源

11、碼的安裝,這里我們就來(lái)剖析源碼的結(jié)構(gòu)。打開(kāi)協(xié)議棧目錄我們可以看到下圖:BLE源碼:目錄名內(nèi)容說(shuō)明Accessories一些工具和已經(jīng)編譯好的Hex文件此文件夾中有Btool的安裝包、USB-CDC的驅(qū)動(dòng)。ComponentsHal驅(qū)動(dòng),OSAL源碼、協(xié)議棧通用源碼此文件夾是OSAL各層組件的實(shí)現(xiàn)Documents幫助文檔協(xié)議棧說(shuō)明文檔,這是學(xué)習(xí)BLE最好的資料。Projects工程文件這里有一些TI的Demo,我們開(kāi)發(fā)一般是在Demo的基礎(chǔ)上進(jìn)行這里TI給出了很多Demo,這些例程都是經(jīng)過(guò)了SIG評(píng)審的,ble 文件夾中有很多工程文件,有些是具體的應(yīng)用,例如BloodPressure、Gluc

12、oseCollector 、GlucoseSensor 、 HeartRate 、HIDEmuKbd 等都為傳感器的實(shí)際應(yīng)用,有相應(yīng)標(biāo)準(zhǔn)的 Profile。其中有4種角色: SimpleBLEBroadcaster 、 SimpleBLECentral 、SimpleBLEObserver、SimpleBLEPeripheral。他們都有自己的特點(diǎn)。1.Broadcaster 廣播員 非連接性的信號(hào)裝置2.Observer 觀察者 掃描得到,但不能鏈接3.Peripheral 從機(jī) 可鏈接,在單個(gè)鏈路層鏈接中作為從機(jī)4.Central 主機(jī) 掃描設(shè)備并發(fā)起鏈接,在單鏈路層或多鏈路層中作為主機(jī)。

13、我們的講解將圍繞這主機(jī)和從機(jī)進(jìn)行。因?yàn)槠渌脑O(shè)備都是基于這兩種設(shè)備擴(kuò)展開(kāi)來(lái)的。第十四節(jié) OSAL工作原理藍(lán)牙為了實(shí)現(xiàn)同多個(gè)設(shè)備相連,或?qū)崿F(xiàn)多功能,也實(shí)現(xiàn)了功能擴(kuò)充,這就產(chǎn)生了調(diào)度問(wèn)題。因?yàn)?,雖然軟件和協(xié)議??蓴U(kuò)充,但終究最底層的執(zhí)行部門只有一個(gè)。為了實(shí)現(xiàn)多事件和多任務(wù)切換,需要把事件和任務(wù)對(duì)應(yīng)的應(yīng)用,并起一個(gè)名字OSAL操作系統(tǒng)抽象層。OSAL管理的實(shí)現(xiàn)如果實(shí)現(xiàn)軟件和硬件的低耦合,使軟件不經(jīng)改動(dòng)或很少改動(dòng)即可應(yīng)用在另外的硬件上,這樣就方便硬件改造、升級(jí)、遷移后,軟件的移植。HAL硬件抽象層正是用來(lái)抽象各種硬件的資源,告知給軟件。其作用類似于嵌入式系統(tǒng)設(shè)備驅(qū)動(dòng)的定義硬件資源的h頭文件。BLE低功

14、耗藍(lán)牙系統(tǒng)架構(gòu):OSAL作為調(diào)度核心,BLE協(xié)議棧、profile定義、所有的應(yīng)用都圍繞它來(lái)實(shí)現(xiàn)。OSAL不是傳統(tǒng)大家使用的操作系統(tǒng),而是一個(gè)允許軟件建立和執(zhí)行事件的循環(huán)。軟件功能是由任務(wù)事件來(lái)實(shí)現(xiàn)的,創(chuàng)建一個(gè)任務(wù)事件需要以下工作:1. 創(chuàng)建task identifier任務(wù)ID;2. 編寫任務(wù)初始化(task initialization routine)進(jìn)程,并需要添加到OSAL初始化進(jìn)程中,這就是說(shuō)系統(tǒng)啟動(dòng)后不能動(dòng)態(tài)添加功能;3. 編寫任務(wù)處理程序;4. 如有需要提供消息服務(wù)。BLE協(xié)議棧的各層都是以O(shè)SAL任務(wù)方式實(shí)現(xiàn),由于LL控制室的時(shí)間要求最為迫切,所以其任務(wù)優(yōu)先級(jí)最高。為了實(shí)現(xiàn)任

15、務(wù)管理,OSAL通過(guò)消息處理(messageprocess),存儲(chǔ)管理,計(jì)時(shí)器定時(shí)等附加服務(wù)實(shí)現(xiàn)。系統(tǒng)啟動(dòng)流程:為了使用OSAL,在main函數(shù)的最后要啟動(dòng)一個(gè)名叫osal_start_system的進(jìn)程,該進(jìn)程會(huì)調(diào)用由特定應(yīng)用決定的啟動(dòng)函數(shù) osalInitTasks(來(lái)啟動(dòng)系統(tǒng))。osalInitTasks逐個(gè)調(diào)用BLE協(xié)議棧各層的啟動(dòng)進(jìn)程來(lái)初始化協(xié)議棧。隨后,設(shè)置一個(gè)任務(wù)的 8bit任務(wù)ID(task ID),跳入循環(huán)等待執(zhí)行任務(wù),系統(tǒng)啟動(dòng)完成。1. 任務(wù)優(yōu)先級(jí)決定于任務(wù)ID,任務(wù)ID越小,優(yōu)先級(jí)越高2. BLE協(xié)議棧各層的任務(wù)優(yōu)先級(jí)比應(yīng)用程序的高3. 初始化協(xié)議棧后,越早調(diào)入的任務(wù),任

16、務(wù)ID越高,優(yōu)先級(jí)越低,即系統(tǒng)傾向于處理新到的任務(wù)每個(gè)事件任務(wù)由對(duì)應(yīng)的16bit事件變量來(lái)標(biāo)示,事件狀態(tài)由旗號(hào)(taskflag)來(lái)標(biāo)示。如果事件處理程序已經(jīng)完成,但其旗號(hào)并沒(méi)有移除,OSAL會(huì)認(rèn)為事情還沒(méi)有完成而繼續(xù)在該程序中不返回。比如,在SimpleBLEPeripheral實(shí)例工程中,當(dāng)事件START_DEVICE_EVT發(fā)生,其處理函數(shù)SimpleBLEPeripheral_ProcessEvent就運(yùn)行,結(jié)束后返回16bit事件變量,并清除旗語(yǔ) SBP_START_DEVICE_EVT。每當(dāng)OSAL事件檢測(cè)到了有任務(wù)事件,其相應(yīng)的處理進(jìn)程將被添加到由處理進(jìn)程指針構(gòu)成的事件處理表單中

17、,該表單名叫taskArr(taskarray)。taskArr中各個(gè)事件進(jìn)程的順序和osalInitTasks初始化函數(shù)中任務(wù)ID的順序是對(duì)應(yīng)的。有兩種,最簡(jiǎn)單的方法是使用osal_set_event函數(shù)(函數(shù)原型在OSAL.h文件中),在這個(gè)函數(shù)中,用戶可以像定義函數(shù)參數(shù)一樣設(shè)置任務(wù)ID 和事件旗語(yǔ)。第二種方法是使用osal_start_timerEx函數(shù)(函數(shù)原型在OSAL_Timers.h文件中),使用方法同 osal_set_event函數(shù),而第三個(gè)以毫秒為單位的參數(shù)osal_start_timerEx則指示該事件處理必須要在這個(gè)限定時(shí)間內(nèi),通過(guò)定時(shí)器來(lái)為事件處理計(jì)時(shí)。類似于Linu

18、x嵌入式系統(tǒng)內(nèi)存分配C函數(shù)mem_alloc,OSAL利用osal_mem_alloc提供基本的存儲(chǔ)管理,但osal_mem_alloc只有一個(gè)用于定義byte數(shù)的參數(shù)。對(duì)應(yīng)的內(nèi)存釋放函數(shù)為osal_mem_free。不同的子系統(tǒng)通過(guò)OSAL的消息機(jī)制通信。消息即為數(shù)據(jù),數(shù)據(jù)種類和長(zhǎng)度都不限定。消息收發(fā)過(guò)程描述如下:接收信息,調(diào)用函數(shù)osal_msg_allocate創(chuàng)建消息占用內(nèi)存空間(已經(jīng)包含了osal_mem_alloc函數(shù)功能),需要為該函數(shù)指定空間大小,該函數(shù)返回內(nèi)存空間地址指針,利用該指針就可把所需數(shù)據(jù)拷貝到該空間。發(fā)送數(shù)據(jù),調(diào)用函數(shù)osal_msg_send,需為該函數(shù)指定發(fā)送目

19、標(biāo)任務(wù),OSAL通過(guò)旗語(yǔ)SYS_EVENT_MSG告知目標(biāo)任務(wù),目標(biāo)任務(wù)的處理函數(shù)調(diào)用osal_msg_receive來(lái)接收發(fā)來(lái)的數(shù)據(jù)。建議每個(gè)OSAL任務(wù)都有一個(gè)消息處理函數(shù),每當(dāng)任務(wù)收到一個(gè)消息后,通過(guò)消息的種類來(lái)確定需要本任務(wù)做相應(yīng)處理。消息接收并處理完成,調(diào)用函數(shù)osal_msg_deallocate來(lái)釋放內(nèi)存(已經(jīng)包含了osal_mem_free函數(shù)功能)。為了實(shí)現(xiàn)更好的移植性,協(xié)議棧將硬件層抽象出了一個(gè)HAL硬件抽象層,當(dāng)新的硬件平臺(tái)做好后,只需修改HAL,而不需修改HAL之上的協(xié)議棧的其他組件和應(yīng)用程序。第十五節(jié) BLE藍(lán)牙4.0協(xié)議棧啟動(dòng)分析TI的這款CC2540/CC2541

20、器件可以單芯片實(shí)現(xiàn)BLE藍(lán)牙協(xié)議棧結(jié)構(gòu)圖的所有組件,包括應(yīng)用程序。從這章開(kāi)始我們來(lái)剖析協(xié)議棧源碼,我們選用 SimpleBLEPeripheral工程開(kāi)刀,這是一個(gè)從機(jī)的例程,基本的工作是對(duì)外廣播,等待主機(jī)來(lái)連接,讀寫展示的屬性。首先打開(kāi)工程文件,打開(kāi)后可以看到整個(gè)工程的結(jié)構(gòu)。我們按照系統(tǒng)的啟動(dòng)順序來(lái)一步一步走,我們都知道在C代碼中,一般啟動(dòng)的首個(gè)函數(shù)為main,這個(gè)函數(shù)在 SimpleBLEPeripheral_Main.c中,打開(kāi)文件,可以看到這個(gè)文件只有一個(gè)main函數(shù)和一個(gè)函數(shù)的申明,我們暫時(shí)不理會(huì)那個(gè)申明的函數(shù),先看main都做了些什么工作:Int main(void)/* Init

21、ialize hardware */HAL_BOARD_INIT(); / 硬件初始化/ Initialize board I/OInitBoard( OB_COLD ); / 板級(jí)初始化/* Initialze the HAL driver */HalDriverInit(); / Hal驅(qū)動(dòng)初始化/* Initialize NV system */osal_snv_init(); / Flash存儲(chǔ)SNV初始化/* Initialize LL */* Initialize the operating system */osal_init_system(); / OSAL初始化/* Enab

22、le interrupts */HAL_ENABLE_INTERRUPTS(); / 使能總中斷/ Final board initializationInitBoard( OB_READY ); / 板級(jí)初始化#if defined ( POWER_SAVING )osal_pwrmgr_device( PWRMGR_BATTERY ); / 低功耗管理#endif/* Start OSAL */osal_start_system(); / No Return from here 啟動(dòng)OSALreturn 0;通過(guò)代碼我們可以看到,系統(tǒng)啟動(dòng)的過(guò)程,主要是做了一些初始化,如果開(kāi)啟了低功耗,則還

23、需要開(kāi)啟低功耗管理。我們先不去理會(huì)初始化做了什么,但是我們知道在main函數(shù)的最后啟動(dòng)了OSAL,那么我們就進(jìn)去看看OSAL是如何運(yùn)作的。在IAR中如果需要跳轉(zhuǎn)到某個(gè)函數(shù)或變量的定義,可以在此函數(shù)名中右擊然后選擇Go To Definition就可以調(diào)到相應(yīng)的定義。void osal_start_system( void )#if !defined ( ZBIT ) & !defined ( UBIT )for(;) / Forever Loop#endifosal_run_system();這里看到我們進(jìn)入了一個(gè)死循環(huán),并且一直調(diào)用osal_run_system(),那我們?cè)龠M(jìn)入此函數(shù)。vo

24、id osal_run_system( void )uint8 idx = 0;#ifndef HAL_BOARD_CC2538osalTimeUpdate(); / 定時(shí)器更新#endifHal_ProcessPoll(); / Hal層信息處理do if (tasksEventsidx) / Task is highest priority that is ready.break; while (+idx tasksCnt); / 檢查每個(gè)人任務(wù)是否有事件if (idx tasksCnt) / 有事件發(fā)生uint16 events;halIntState_t intState;HAL_EN

25、TER_CRITICAL_SECTION(intState); / 進(jìn)入臨界區(qū)events = tasksEventsidx;tasksEventsidx = 0; / Clear the Events for this task. 清除事件標(biāo)志HAL_EXIT_CRITICAL_SECTION(intState); / 退出臨界區(qū)activeTaskID = idx;events = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù)activeTaskID = TASK_NO_TASK;HAL_ENTER_CRITICAL_SECTION(intState);

26、 / 進(jìn)入臨界區(qū)tasksEventsidx |= events; / Add back unprocessed events to the current task.HAL_EXIT_CRITICAL_SECTION(intState); / 退出臨界區(qū)#if defined( POWER_SAVING ) / 沒(méi)有事件發(fā)生,并且開(kāi)啟了低功耗模式else / Complete pass through all task events with no activity? / 系統(tǒng)進(jìn)入低功耗模式osal_pwrmgr_powerconserve(); / Put the processor/sy

27、stem into sleep#endif/* Yield in case cooperative scheduling is being used. */#if defined (configUSE_PREEMPTION) & (configUSE_PREEMPTION = 0)osal_task_yield();#endif在這里可以看到這個(gè)OSAL的核心,整個(gè)OSAL通過(guò)檢測(cè)每個(gè)任務(wù)是否有事件發(fā)生,如果有則執(zhí)行相應(yīng)的任務(wù),處理相應(yīng)的事件。如果沒(méi)有事件需要處理并且開(kāi)啟了低功耗模式,則系統(tǒng)就會(huì)進(jìn)入低功耗模式。這里有一個(gè)很關(guān)鍵的地方,OSAL是如何知道哪個(gè)事件需要哪個(gè)任務(wù)來(lái)處理呢?events

28、 = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù)我們看這里有一個(gè)很關(guān)鍵的數(shù)組tasksArr,很顯然,這是一個(gè)函數(shù)指針數(shù)組,我們看看它的定義。const pTaskEventHandlerFn tasksArr =LL_ProcessEvent, / task 0Hal_ProcessEvent, / task 1HCI_ProcessEvent, / task 2#if defined ( OSAL_CBTIMER_NUM_TASKS )OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), / t

29、ask 3#endifL2CAP_ProcessEvent, / task 4GAP_ProcessEvent, / task 5GATT_ProcessEvent, / task 6SM_ProcessEvent, / task 7GAPRole_ProcessEvent, / task 8GAPBondMgr_ProcessEvent, / task 9GATTServApp_ProcessEvent, / task 10SimpleBLEPeripheral_ProcessEvent / task 11;可以看到在這個(gè)數(shù)組的定義中,每個(gè)成員都是任務(wù)的執(zhí)行函數(shù),按照任務(wù)的優(yōu)先級(jí)排序,并且在

30、osalInitTasks中初始化的時(shí)候,我們可以看到每個(gè)任務(wù)都有一個(gè)對(duì)應(yīng)的初始化函數(shù),并且傳遞了一個(gè)taskID,此ID從0開(kāi)始自增,這里有一點(diǎn)非常重要,初始化的順序和任務(wù)數(shù)組的定義順序是一樣的,這就保證了我們給任務(wù)發(fā)生消息或事件時(shí)能夠準(zhǔn)確的傳遞到相應(yīng)的任務(wù)處理函數(shù)。void osalInitTasks( void )uint8 taskID = 0;tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);osal_memset( tasksEvents, 0, (sizeof( uint16 ) * task

31、sCnt);/* LL Task */LL_Init( taskID+ );/* Hal Task */Hal_Init( taskID+ );/* HCI Task */HCI_Init( taskID+ );#if defined ( OSAL_CBTIMER_NUM_TASKS )/* 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( taskID+ );/* SM Task */SM_Init( taskID+ );/* Profiles */GAPRole_Init( taskID+ );GAPBondMgr_Init( taskID+ );GATTServApp_Init( taskID+ );/* Application */SimpleBLEPeripheral_Init( taskID );應(yīng)用層的初始化

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論