久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > TI藍牙4.0協議棧main函數分析

TI藍牙4.0協(xie)議棧main函數分析(xi) 時間:2018-09-25      來源:未知

我們采用BLE-CC254x-1.3.2中的KeyFob工(gong)程展開分析.

我們都(dou)知(zhi)道在C代(dai)碼中,程序的入口(kou)都(dou)是main()函(han)數,這(zhe)個函(han)數在KeyFob_Main.c中

打開文件,可以看(kan)到這個文件包含了(le)一(yi)些(xie)必要的(de)(de)頭(tou)文件和一(yi)個函數的(de)(de)申(shen)明(ming),我們暫時不理會(hui)那個申(shen)明(ming)的(de)(de)函數,先看(kan)main都做了(le)些(xie)什么工作(zuo):

通(tong)過代碼我(wo)們(men)可以看到,系統啟(qi)動的(de)過程,主(zhu)要是做了(le)一些初始化,如果開(kai)啟(qi)了(le)低功耗,則還需要開(kai)啟(qi)低功耗管(guan)理(li)。我(wo)們(men)先不去(qu)理(li)會初始化做了(le)什么,但(dan)是我(wo)們(men)知道main函數終(zhong)啟(qi)動了(le)OSAL,所以我(wo)們(men)只分析相關的(de)兩個函數osal_init_system()和(he)osal_start_system().

我(wo)們進入osal_init_system()

我(wo)們(men)從TI官方的(de)注(zhu)釋就能大致(zhi)知道每(mei)個(ge)函數的(de)作用.我(wo)再(zai)簡單介紹一下:

1044:初始(shi)化內(nei)存分(fen)配系統(tong)

1047:初始化消息隊列

1050:初始化定時器

1053:初(chu)始化電(dian)源管理系統(tong)

1056:初始化系(xi)統任務,這個函數(shu)添(tian)加了(le)所有的(de)任務,我們在以后詳細分(fen)析它.

1059: 設置有效(xiao)的查找堆(dui)上的第一個空閑塊

我們進入(ru)osal_start_system(),發現這里(li)會循環調用(yong)osal_run_system()

osal_run_system()才是(shi)整(zheng)個(ge)協議棧(zhan)(zhan)的(de)核心,進入到osal_run_system()后(hou)發(fa)現他(ta)只(zhi)有1102-1147這些(xie)行代碼(ma).這些(xie)代碼(ma)就(jiu)是(shi)整(zheng)個(ge)協議棧(zhan)(zhan)運轉的(de)大腦,我們務必要(yao)把這里(li)搞(gao)清楚.

我(wo)們發現代碼里邊有(you)好多預編譯宏(hong),而這(zhe)些宏(hong)我(wo)們都沒有(you)定義,所以對應的函數代碼也(ye)沒有(you)執行,我(wo)們再次精簡一下代碼,

好了,我們就詳細得分(fen)析下這段代碼吧(ba).

首先是一個do{}while()的組合,我們上來就執行(xing)do{}中得語句

我們先來解析(xi)下tasksEvents[idx],idx在1102行被賦(fu)值為(wei)0,那tasksEvents又是(shi)什么呢?我們右(you)鍵點(dian)擊變量(liang)然后go to definition或者按快捷鍵F12查看變量(liang)定(ding)義的(de)位置

追(zhui)到以后發(fa)現是個指針,那它(ta)何時被賦(fu)(fu)值(zhi)呢 ,被賦(fu)(fu)值(zhi)成什么呢??我們要用到高級(ji)搜索這個功(gong)能了,把它(ta)找(zhao)出來.

我們選(xuan)中以后,按下組合鍵ctrl+shift+f,然后點擊find即可

我(wo)們發現有以下地方用到了這(zhe)個指(zhi)針(zhen)

用到(dao)的地(di)方(fang)不少(shao),別(bie)害怕,照(zhao)著我的步(bu)驟你(ni)你(ni)就會看見前(qian)方(fang)一片光明.

首(shou)先我們(men)來看osalInitTasks()函數,在126行用malloc()分配(pei)了一(yi)片堆(dui)空間,后將這(zhe)片空間的首(shou)地址賦值給(gei)tasksEvents.這(zhe)里呢我們(men)就可以(yi)將

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);這句話等價于你定(ding)義了一個數組(zu)uint16 tasksEvents[tasksCnt],tasksCnt是幾呢(ni)?我一會告訴你.

127行(xing)將(jiang)這(zhe)片空間的數據全部清零(ling),也(ye)就(jiu)是(shi)將(jiang)數組的全部元(yuan)素清零(ling).

這(zhe)里我(wo)們(men)先不去(qu)管這(zhe)片內存空間中要存儲什么(me)數(shu)據(ju),我(wo)們(men)知道這(zhe)里邊全部(bu)是(shi)0;

再回到

do {

if (tasksEvents[idx]) // Task is highest priority that is ready.

{

break;

}

} while (++idx < tasksCnt);

剛開始(shi)idx得(de)(de)值(zhi)是0, tasksEvents[idx]也就是0;那if (tasksEvents[idx])就不成立(li).隨后會(hui)執行while()中得(de)(de)語句++idx < tasksCnt, 這里我們需要再去跟蹤下tasksCnt這個(ge)變量,發現(xian)他(ta)原來是個(ge)常量:

問題(ti)又來了, tasksArr又是啥呢?我們繼(ji)續跟蹤

我們(men)(men)發現這是個(ge)數組(zu),那數組(zu)中(zhong)又存的是什么類型呢>?我們(men)(men)跟(gen)下pTaskEventHandlerFn,原來這是函數指(zhi)針啊,那我們(men)(men)就清楚(chu)了(le)tasksArr這個(ge)數組(zu)中(zhong)全部(bu)存的是函數指(zhi)針啊.至(zhi)于(yu)這些函數指(zhi)針是干(gan)什么得,又指(zhi)向誰我們(men)(men)待會來分析.但我相信(xin)你已經知道了(le)tasksCnt的值.

有點亂,我(wo)們現在先回(hui)憶下(xia),剛才有幾個(ge)重(zhong)要的變量.

其(qi)中一個是存函數指針得數組tasksArr,這些函數指針具體(ti)干(gan)嘛我們一會(hui)分(fen)析.

還有一(yi)個是這個數組中(zhong)函數指針的個數tasksCnt.

還有一個(ge)(ge)(ge)指(zhi)針變量tasksEvents.我們知道這(zhe)(zhe)個(ge)(ge)(ge)函數(shu)指(zhi)針指(zhi)向了一片堆(dui)空間,并且空間中全是(shi)0;我們就把它當(dang)成(cheng)一個(ge)(ge)(ge)數(shu)組(zu),數(shu)組(zu)中有tasksCnt個(ge)(ge)(ge)成(cheng)員(yuan),每個(ge)(ge)(ge)成(cheng)員(yuan)的大小是(shi)兩個(ge)(ge)(ge)字節.再看do{}while()這(zhe)(zhe)個(ge)(ge)(ge)組(zu)合.

do {

if (tasksEvents[idx]) // Task is highest priority that is ready.

{

break;

}

} while (++idx < tasksCnt);

根據上邊(bian)所說的,你(ni)應(ying)該能想(xiang)到這(zhe)個循(xun)環結(jie)束的時候idx的數值了(le)吧.對的,他后是(shi)等于tasksCnt的,結(jie)束循(xun)環后就進入1136行得(de)分(fen)支,這(zhe)里就是(shi)系統(tong)在檢(jian)測(ce)到沒有事件發(fa)生的時候進入低功耗(hao)模式.

那什么時候(hou)才會進入1119行這個(ge)分(fen)支來處理發(fa)生(sheng)的事件(jian)呢(ni).我們(men)再來認識(shi)一個(ge)新的函數osal_set_event();這個(ge)函數得功(gong)能就(jiu)是標(biao)識(shi)有事件(jian)發(fa)生(sheng),我們(men)來分(fen)析下代碼.

904行(xing)判斷傳參task_id是(shi)否小于tasksCnt(你(ni)好還記得這(zhe)個(ge)常(chang)量).907行(xing)關閉中斷,進入臨界區.908行(xing)有用到剛才那(nei)個(ge)函(han)數指針tasksEvents了(其實(shi)也(ye)是(shi)數組首(shou)地址),那(nei)這(zhe)個(ge)數組存這(zhe)些變量有什么意義呢?

一句話告訴你,這個(ge)(ge)數組的每一個(ge)(ge)成員都代(dai)表(biao)一個(ge)(ge)任(ren)務(wu),每個(ge)(ge)成員是兩個(ge)(ge)字(zi)節(jie)就是16位,每一位都代(dai)表(biao)這個(ge)(ge)任(ren)務(wu)中得一個(ge)(ge)事件,那一個(ge)(ge)任(ren)務(wu)能有幾個(ge)(ge)事件呢?怎么(me)能表(biao)示(shi)事件發(fa)生還是沒發(fa)生呢?聰明的你應該(gai)能想到(dao)是16個(ge)(ge)了.事件發(fa)生就將(jiang)對應的位置一就好了.

我們(men)只需要知道協議(yi)棧里會(hui)通(tong)過中斷,函數調用等方(fang)式調osal_set_event()將系統事件置一.好了(le)我們(men)再回到下面的代碼:

do {

if (tasksEvents[idx]) // Task is highest priority that is ready.

{

break;

}

} while (++idx < tasksCnt);

這(zhe)時(shi)(shi)候(hou)(hou)tasksEvents[idx]隨著idx得增加(jia)if (tasksEvents[idx])會成(cheng)立了吧,這(zhe)時(shi)(shi)候(hou)(hou)break出來idx的值剛好對應的是任務的編號.

終(zhong)于能(neng)執行這(zhe)段分支了,我(wo)們來(lai)分析下(xia);

1122:進入臨界區,關中斷(duan);

1123:將待處理(li)的(de)任務(wu)中(zhong)所有(you)的(de)事件賦值給變量(liang)events

1124:將tasksEvents數組中該任務的事件全部(bu)清(qing)空(kong)

1125:退出臨界區,開中斷;

1127:將當(dang)前任務(wu)的(de)標號復制(zhi)給全(quan)局變量,它代表當(dang)前正(zheng)在處理(li)的(de)任務(wu)的(de)標號

1128:還記得tasksArr()存(cun)的是(shi)什么嗎?是(shi)函(han)數指(zhi)針,他(ta)其(qi)實就(jiu)是(shi)對應(ying)任(ren)務的處理函(han)數,至于這個(ge)處理函(han)數都(dou)做了什么?我們下次分(fen)析,現在(zai)大家(jia)只用知道(dao)你(ni)把 事(shi)件傳進去(qu),他(ta)會(hui)幫你(ni)處理,但每(mei)次只能處理一個(ge)事(shi)件,然(ran)后將處理完的事(shi)件對應(ying)的位清零隨后將新(xin)的事(shi)件變(bian)量返回.再賦值(zhi)給events

1129:將activeTaskID賦值為TASK_NO_TASK代(dai)表(biao)當前(qian)沒有任務處(chu)理

1131: 進(jin)入臨(lin)界區,關中斷;

1132: 由于你剛才將事件變(bian)量清空了,你每次又只(zhi)能處理一個事件,你總要把(ba)剩(sheng)下沒(mei)處理的變(bian)量告訴我吧.

1133: 退出臨界區(qu),開(kai)中(zhong)斷;

好(hao)了(le),到這(zhe)里(li)該停了(le),我(wo)們先來(lai)總結下:

一個任務中如何表(biao)示(shi)不(bu)同的事件呢?

用一個unsigned short類(lei)型的變(bian)量來記錄不同的事件(jian),unsigned short占兩個字節,總共16位,每一位二進制表示(shi)一個事件(jian).

任務(wu)對應的(de)處理(li)函數放(fang)在(zai)哪呢?

放在const pTaskEventHandlerFn tasksArr[];

如果知道某(mou)個任(ren)務發生了(le)某(mou)個事件,怎(zen)么記錄?

用這個函數 uint8 osal_set_event( uint8 task_id, uint16 event_flag )

 下(xia)次我們會分析osalInitTasks()這(zhe)個函(han)數,還有任務(wu)(wu)(wu)和(he)處理(li)(li)任務(wu)(wu)(wu)事(shi)件的(de)函(han)數是怎(zen)么聯系起(qi)來(lai)的(de)? 如何在協議棧添加(jia)一個自(zi)己的(de)任務(wu)(wu)(wu),處理(li)(li)任務(wu)(wu)(wu)里的(de)事(shi)件?

上一篇:Freemodbus啟動流程分析

下一篇:Linux內核中的數據結構的一點認識

熱點文(wen)章推薦
華清學員就業榜單
高薪(xin)學(xue)員經(jing)驗分享
熱點新聞推薦
前臺專線:010-82525158 企(qi)業培訓洽(qia)談專(zhuan)線:010-82525379 院校合作洽(qia)談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部