黄色一级毛片网站_日韩在线国产_国产一级a在线观看_亚洲综合一区在线_99av视频_久久久7

當(dāng)前位置:首頁 > 學(xué)習(xí)資源 > 講師博文 > TI藍(lán)牙4.0協(xié)議棧main函數(shù)分析

TI藍(lán)牙4.0協(xié)議棧main函數(shù)分析 時間:2018-09-25      來源:華清遠(yuǎn)見

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

我們都知道在C代碼中,程序的入口都是main()函數(shù),這個函數(shù)在KeyFob_Main.c中

打開文件,可以看到這個文件包含了一些必要的頭文件和一個函數(shù)的申明,我們暫時不理會那個申明的函數(shù),先看main都做了些什么工作:

通過代碼我們可以看到,系統(tǒng)啟動的過程,主要是做了一些初始化,如果開啟了低功耗,則還需要開啟低功耗管理。我們先不去理會初始化做了什么,但是我們知道m(xù)ain函數(shù)終啟動了OSAL,所以我們只分析相關(guān)的兩個函數(shù)osal_init_system()和osal_start_system().

我們進(jìn)入osal_init_system()

我們從TI官方的注釋就能大致知道每個函數(shù)的作用.我再簡單介紹一下:

1044:初始化內(nèi)存分配系統(tǒng)

1047:初始化消息隊列

1050:初始化定時器

1053:初始化電源管理系統(tǒng)

1056:初始化系統(tǒng)任務(wù),這個函數(shù)添加了所有的任務(wù),我們在以后詳細(xì)分析它.

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

我們進(jìn)入osal_start_system(),發(fā)現(xiàn)這里會循環(huán)調(diào)用osal_run_system()

osal_run_system()才是整個協(xié)議棧的核心,進(jìn)入到osal_run_system()后發(fā)現(xiàn)他只有1102-1147這些行代碼.這些代碼就是整個協(xié)議棧運轉(zhuǎn)的大腦,我們務(wù)必要把這里搞清楚.

我們發(fā)現(xiàn)代碼里邊有好多預(yù)編譯宏,而這些宏我們都沒有定義,所以對應(yīng)的函數(shù)代碼也沒有執(zhí)行,我們再次精簡一下代碼,

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

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

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

追到以后發(fā)現(xiàn)是個指針,那它何時被賦值呢 ,被賦值成什么呢??我們要用到高級搜索這個功能了,把它找出來.

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

我們發(fā)現(xiàn)有以下地方用到了這個指針

用到的地方不少,別害怕,照著我的步驟你你就會看見前方一片光明.

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

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

127行將這片空間的數(shù)據(jù)全部清零,也就是將數(shù)組的全部元素清零.

這里我們先不去管這片內(nèi)存空間中要存儲什么數(shù)據(jù),我們知道這里邊全部是0;

再回到

do {

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

{

break;

}

} while (++idx < tasksCnt);

剛開始idx得值是0, tasksEvents[idx]也就是0;那if (tasksEvents[idx])就不成立.隨后會執(zhí)行while()中得語句++idx < tasksCnt, 這里我們需要再去跟蹤下tasksCnt這個變量,發(fā)現(xiàn)他原來是個常量:

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

我們發(fā)現(xiàn)這是個數(shù)組,那數(shù)組中又存的是什么類型呢>?我們跟下pTaskEventHandlerFn,原來這是函數(shù)指針啊,那我們就清楚了tasksArr這個數(shù)組中全部存的是函數(shù)指針啊.至于這些函數(shù)指針是干什么得,又指向誰我們待會來分析.但我相信你已經(jīng)知道了tasksCnt的值.

有點亂,我們現(xiàn)在先回憶下,剛才有幾個重要的變量.

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

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

還有一個指針變量tasksEvents.我們知道這個函數(shù)指針指向了一片堆空間,并且空間中全是0;我們就把它當(dāng)成一個數(shù)組,數(shù)組中有tasksCnt個成員,每個成員的大小是兩個字節(jié).再看do{}while()這個組合.

do {

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

{

break;

}

} while (++idx < tasksCnt);

根據(jù)上邊所說的,你應(yīng)該能想到這個循環(huán)結(jié)束的時候idx的數(shù)值了吧.對的,他后是等于tasksCnt的,結(jié)束循環(huán)后就進(jìn)入1136行得分支,這里就是系統(tǒng)在檢測到?jīng)]有事件發(fā)生的時候進(jìn)入低功耗模式.

那什么時候才會進(jìn)入1119行這個分支來處理發(fā)生的事件呢.我們再來認(rèn)識一個新的函數(shù)osal_set_event();這個函數(shù)得功能就是標(biāo)識有事件發(fā)生,我們來分析下代碼.

904行判斷傳參task_id是否小于tasksCnt(你好還記得這個常量).907行關(guān)閉中斷,進(jìn)入臨界區(qū).908行有用到剛才那個函數(shù)指針tasksEvents了(其實也是數(shù)組首地址),那這個數(shù)組存這些變量有什么意義呢?

一句話告訴你,這個數(shù)組的每一個成員都代表一個任務(wù),每個成員是兩個字節(jié)就是16位,每一位都代表這個任務(wù)中得一個事件,那一個任務(wù)能有幾個事件呢?怎么能表示事件發(fā)生還是沒發(fā)生呢?聰明的你應(yīng)該能想到是16個了.事件發(fā)生就將對應(yīng)的位置一就好了.

我們只需要知道協(xié)議棧里會通過中斷,函數(shù)調(diào)用等方式調(diào)osal_set_event()將系統(tǒng)事件置一.好了我們再回到下面的代碼:

do {

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

{

break;

}

} while (++idx < tasksCnt);

這時候tasksEvents[idx]隨著idx得增加if (tasksEvents[idx])會成立了吧,這時候break出來idx的值剛好對應(yīng)的是任務(wù)的編號.

終于能執(zhí)行這段分支了,我們來分析下;

1122:進(jìn)入臨界區(qū),關(guān)中斷;

1123:將待處理的任務(wù)中所有的事件賦值給變量events

1124:將tasksEvents數(shù)組中該任務(wù)的事件全部清空

1125:退出臨界區(qū),開中斷;

1127:將當(dāng)前任務(wù)的標(biāo)號復(fù)制給全局變量,它代表當(dāng)前正在處理的任務(wù)的標(biāo)號

1128:還記得tasksArr()存的是什么嗎?是函數(shù)指針,他其實就是對應(yīng)任務(wù)的處理函數(shù),至于這個處理函數(shù)都做了什么?我們下次分析,現(xiàn)在大家只用知道你把 事件傳進(jìn)去,他會幫你處理,但每次只能處理一個事件,然后將處理完的事件對應(yīng)的位清零隨后將新的事件變量返回.再賦值給events

1129:將activeTaskID賦值為TASK_NO_TASK代表當(dāng)前沒有任務(wù)處理

1131: 進(jìn)入臨界區(qū),關(guān)中斷;

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

1133: 退出臨界區(qū),開中斷;

好了,到這里該停了,我們先來總結(jié)下:

一個任務(wù)中如何表示不同的事件呢?

用一個unsigned short類型的變量來記錄不同的事件,unsigned short占兩個字節(jié),總共16位,每一位二進(jìn)制表示一個事件.

任務(wù)對應(yīng)的處理函數(shù)放在哪呢?

放在const pTaskEventHandlerFn tasksArr[];

如果知道某個任務(wù)發(fā)生了某個事件,怎么記錄?

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

下次我們會分析osalInitTasks()這個函數(shù),還有任務(wù)和處理任務(wù)事件的函數(shù)是怎么聯(lián)系起來的? 如何在協(xié)議棧添加一個自己的任務(wù),處理任務(wù)里的事件?

上一篇:Freemodbus啟動流程分析

下一篇:Linux內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)的一點認(rèn)識

戳我查看嵌入式每月就業(yè)風(fēng)云榜

點我了解華清遠(yuǎn)見高校學(xué)霸學(xué)習(xí)秘籍

猜你關(guān)心企業(yè)是如何評價華清學(xué)員的

干貨分享
相關(guān)新聞
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2024 北京華清遠(yuǎn)見科技發(fā)展有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: 久久久久久免费视频 | 免费国产裸体美女视频全黄 | 国产精品v欧美精品v日韩精品 | 91精品综合久久久久3d动漫 | 久久99精品一区二区三区三区 | 亚洲 久久| 少妇的肉体AA片免费 | 曰本一级毛片 | 黄色软件香蕉视频 | 国产成人av三级在线观看 | 91亚洲精品一区 | 国产a级黄色片 | 久久97| 一本色综合亚洲精品蜜桃冫 | 一级片免费网站 | 久亚洲一线产区二线产区三线区 | 欧美高清第一页 | 国产伦码精品一区二区三区 | 欧美一级日韩一级无毒不卡 | 亚洲精品视频观看 | 天堂精品 | 精品一区二区三区免费看 | 国产精品一区二区不卡 | 福利成人| 国产午夜亚洲精品理论片色戒 | 色毛片| 一级国产20岁美女毛片 | 精品综合久久久久久88 | 91久热欧美极品第一页 | 美国毛片基地 | 国产激情久久久久影院老熟女免费 | 久久久久久99精品 | 一级生性活片免费视频片 | 奇米777四色影视在线看 | 成人影片免费 | 欧美猛交免费 | 2020久久精品亚洲热综合 | 亚洲最大色网站 | 久久精品国产国产精品四凭 | 国产免费一区二区三区在线播放 | 国产精品澳门 |