亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

10 OSAL分析補充

2019-11-08 03:25:03
字體:
來源:轉載
供稿:網友
I協議棧所用系統框架探討。51的系統往往不是太大,但是幾十K的程序,也足以讓一個初學者望而卻步。我們首先忽略C語言本身的難度,光是系統框架也讓生手讀起來很吃力,再加上這種到處是API跟"define"的程序,還沒有正式學習協議部分就已經讓人在叢林中“迷路”了。在接下來的一段時間內,我會以TI所用的系統框架為主線進行學習,希望大家共同探討。。。[注:本文源自www.feibit.com--“飛比”Zigbee論壇,為尊重勞動者成果,如需轉載請保留此行]在層層迷霧中摸索了兩天,終于撥云見日,那個心情啊,怎一個“爽”字了得~~~可是怎么能把這么復雜的一個問題講得清楚呢?嗯。。。還是先上圖吧 注:為了便于直觀,以下涉及到數據地址的地方都是由上而下,地址由高變低第1節、各個任務是如何被調用到的?我們還是先從main()函數開始,看看各個任務之間是如何協調工作的。插播一句廣告:在一切都看不清的時候,忽略次要,看主要因素 -- by outman from feibit.com我們直接進入主循環的核心部分,看一下系統中的幾個主要的任務是如何被調用,并開始自己的使命的?看一段程序的時候,往往要從它的數據結構入手。我們先看一下,主循環中的兩個關鍵數組,*tasksEvents與*tasksArr,從圖一中我們可以看出來,tasksEvents這個數組存放的是從序號為0到tasksCnt,每個任務在本次循環中是否要被運行,需要運行的任務其值非0(用橙色表示),否則為0。而tasksArr數組則存放了對應每個任務的入口地址,只有在tasksEvents中記錄的需要運行的任務,在本次循環中才會被調用到。--這節講完了。。。又有同學舉手?什么?還沒明白?恩。。。好像是不能講這么短的。。。那好吧,把main函數貼過來,我們一點一點看初始化過程“先不管”,我們先看主循環(dead loop)for(;;)  // Forever Loop{    uint8 idx = 0;    Hal_PRocessPoll();  // 先不管1    do {      if (tasksEvents[idx])  // 尋找最高優先級的任務來運行      {        break;      }    } while (++idx < tasksCnt);    if (idx < tasksCnt) //如果有任務需要運行    {      uint16 events;      halIntState_t intState;      HAL_ENTER_CRITICAL_SECTION(intState);      events = tasksEvents[idx];      tasksEvents[idx] = 0;  // 本任務運行完了,要對其清空,為后面要運行的任務讓路      HAL_EXIT_CRITICAL_SECTION(intState);      events = (tasksArr[idx])( idx, events );//最關鍵的一句話,如圖一中,運行對應的任務      HAL_ENTER_CRITICAL_SECTION(intState);      tasksEvents[idx] |= events;  // 本任務可能沒完全完成,如果是這樣,再次設置標志位,在下一次循環中繼續執行      HAL_EXIT_CRITICAL_SECTION(intState);      }    }第2節、系統時間我們知道,每個操作系統(雖然我不認為OSAL是一個標準的操作系統,但我們先這么叫著吧)都有一個“節拍”-tick,就像每一個“活人”都有心跳一樣。那么OSAL的心跳有多快呢?--1ms。當然這個速度是可以設置的,在osal_timer_activate函數中開啟了系統節拍,用TICK_TIME來定義其速度#define TICK_TIME   1000   // Timer per tick - in micro-sec注意:這個1000是micro-sec(微秒),而不是milli-sec(毫秒)!我剛開始的時候就是誤以為是1000ms而耽誤了不少時間。那這個心臟是怎么跳動起來的呢?這得從“定時器”說起,由于本文的重點不是講單片機基礎的,如果對這個名字還陌生的同學,那還是回去先看看基礎再來看這個吧。2430有4個定時/計數器,其中timer4用來做系統計時。如果認為是timer2的同學請看一下halTimerRemap這個函數。在上述osal_timer_activate函數中,開啟了系統計時,并將timer4的初始設為TICK_TIME(1000),這樣timer4就開始了從1000開始的減計數,減到0以后呢?寄存器TIMIF會產生一個溢出標志,那么它會立即產生中斷并進入中斷服務程序嗎?不會的。我們看一下第1節主函數里的“Hal_ProcessPoll();  // 先不管1”(不管的東西早晚要管的,只是時間的問題而已)  這個函數里調用了HalTimerTick,這個函數就是專門來檢查是否有硬件定時器溢出的,如果有的話會調用halTimerSendCallBack這個函數,對溢出事件做處理?;剡^頭來說系統節拍,那timer4在計數滿1000(即1ms)后做了些什么事呢,那我們看一下halTimerSendCallBack 這個函數void halTimerSendCallBack (uint8 timerId, uint8 channel, uint8 channelMode){  uint8 hwtimerid;  hwtimerid = halTimerRemap (timerId);  if (halTimerRecord[hwtimerid].callBackFunc)    (halTimerRecord[hwtimerid].callBackFunc) (timerId, channel, channelMode);}這里面調用了“callBackFunc”函數,也就是說每個定時器溢出后都有一個callBackFunc函數,它在哪里呢,我們再看一下HalTimerConfig這個函數,它可以對每個定時器進行定義。那什么時候定義的呢?--InitBoard,即板子上電初始化的時候就做了這個定義的。我說什么來?“先不管”的東西,“后要管”的。。。我們看到timer4的callBackFunc函數是Onboard_TimerCallBack,最終指向osalTimerUpdate,這個函數厲害了~從上面的分析中我們知道它是每1ms被調用一次的,這樣它就為應用程序提供了一個ms計時器,應用程序所用的定時往往以ms為單位足夠了,這樣的話就不用另外再占用硬件計時器了,畢竟只有4個嘛。。。同時這個函數還提供了一個系統時鐘-osal_systemClock,看看它能計時多久吧,它是“uint32”型的,也就是2^32ms=49.7天,怎么樣?你不會讓這個系統時鐘overflow吧:)第3節、系統的消息處理機制結合第1、2節中的內容,讓我們一起進入到系統最核心的部分-消息處理中來吧(這個句型怎么這么耳熟~~~)第1節中我們說了,tasksEvents數組存放了一個任務是否該被運行的序列,但是這個序列是如何產生的呢?如果了解了這個問題,那也就知道了OSAL系統的運作方式。再插句廣告:在浩如煙海的程序中搜索最重要的東西,就像大浪淘沙,其實也是蠻享受的一件事情--by outman from feibit.comsource insight "ctr+/",整個項目搜索,我們發現了一個“osal_set_event”的函數是專門來設置tasksEvents的,但是似乎并不能幫到我們。繼續搜!有兩個很重要的地方引起了我們的注意:osalTimerUpdate和osal_msg_send這兩個函數osalTimerUpdate,這個稱得上“厲害”的函數還記得吧?它會去設置tasksEvents?那不就是說,它可以讓任務在主循環中被運行到?答對了,這就是它“厲害”的地方。。。那看看它運行任務的條件吧?      // When timeout, execute the task      if ( srchTimer->timeout == 0 )      {        osal_set_event( srchTimer->task_id, srchTimer->event_flag );... ...也就是說,計時器溢出--恩。。。不多說了,我們埋個伏筆,先介紹另一個朋友-osal_start_timerEx,先看下它的自我介紹/********************************************************************** @fn      osal_start_timerEx** @brief**   This function is called to start a timer to expire in n mSecs.*   When the timer expires, the calling task will get the specified event.** @param   byte taskID - task id to set timer for* @param   UINT16 event_id - event to be notified with* @param   UNINT16 timeout_value - in milliseconds.** @return  ZSUCCESS, or NO_TIMER_AVAIL.*/byte osal_start_timerEx( byte taskID, UINT16 event_id, UINT16 timeout_value )也就是說,它會開始一個timeout_value(ms)的計時器,當這個計時器溢出時,則會對taskID這個task,設置一個event_id,讓這個任務在后面的主循環中運行到,但是是怎么實現的呢?還是要請osalTimerUpdate來幫忙。。。那位同學說啥?復雜了,聽不懂?唉,還是上圖吧 還是先從數據結構說起吧,不知道啥是“數據鏈表”的同學,把譚老師的書拿過來再讀幾遍。。。這個表就是osalTimerUpdate函數的“任務表”,上面不是說過這個函數給應用程序提供了“軟計時”了嗎?就是體現在這里,osal_start_timerEx通過osalAddTimer向鏈表里添加了“定時任務”,由osalTimerUpdate來以ms為單位對這些“軟定時器”減計數,溢出時,即調用osal_set_event,實現主循環里對任務的調用。好了,到此講了上面提到的"set event"函數中的一個osal_start_timerEx, 還有一個更厲害的還在外面呢,osal_msg_send,這就漸入佳境,進入最重要的消息處理機制了。。。-- by outman from feibit.com 2010-4-14 18:00  下班啦,老婆在家等著回去一起做飯哪~~~晚上見~~~為了更好地說明這個問題,還是拿一個具體的例子來講比較直觀。不過在這個筆記中,我盡量不涉及具體開發板,而講一些通用的知識,因為這樣會讓更多的人受益。在TI官方zstack 2006中有4個例子,其中一個叫GenericApp最基本的通信的例程,如果沒有安裝zstack的同學可以到“本站專用下載貼”中下載。當然由于講的是些比較通用的東西,所以手頭有開發板的同學可以用自己的開發板來試驗,效果更好。。。在這樣的通信例程中,一般會有一個按鍵觸發,然后會和相鄰的模塊進行通信,當然由于這部分是講OSAL的系統框架的,我們先不涉及通信的內容,只是看一下按鍵是如何產生的,及如何調用相應的接口程序。按OSAL的模塊定義,按鍵可能在哪層來?硬件服務相關的,恩。。。是不是在HAL層呢?到Hal_ProcessEvent看看?有個HalKeyPoll函數不是?恩,這就是檢測按鍵的地方~~不過,我可不是像上面這樣這么容易猜出來的,這幾句話足足用了我大半個鐘頭呢。。。過程我不細說了,有興趣的話我可以再補充一下。在HalKeyPoll函數中,無論按鍵是ADC方式,或者是掃描IO口的方式,最后都會生成一個鍵值keys, 然后通過下面的語句來調用按鍵服務程序  /* Invoke Callback if new keys were depressed */  if (keys && (pHalKeyProcessFunction))  {    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);  }這里調用的服務程序,在InitBoard中被初始化為OnBoard_KeyCallback,這個函數又通過OnBoard_SendKeys運行下面語句  {    // Send the address to the task    msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );    if ( msgPtr )    {      msgPtr->hdr.event = KEY_CHANGE;      msgPtr->state = state;      msgPtr->keys = keys;      osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );    }    return ( ZSuccess );  }下面我們就看下osal_msg_send是如何向上級應用程序發送消息的。終于要講消息量的數據結構了,好像繞得有點遠。。。。還是先上圖 在理解了消息量的數據鏈表后,再來理解osal_msg_send里的語句就不難了  OSAL_MSG_ID( msg_ptr ) = destination_task;//設置消息數據對應是屬于哪個任務的  // 將要發送的消息數據鏈接到以osal_qHead開頭的數據鏈表中  osal_msg_enqueue( &osal_qHead, msg_ptr );  // 通知主循環有任務等待處理  osal_set_event( destination_task, SYS_EVENT_MSG );這樣用戶任務GenericApp_ProcessEvent就收到一個按鍵的處理任務,并通過GenericApp_HandleKeys來執行相應的操作。好了,現在應該對OSAL的消息處理機制有個了解了吧?我們再來復習一下這個按鍵的處理過程:任務驅動層Hal_ProcessEvent負責對按鍵進行持續掃描,發現有按鍵事件后OnBoard_KeyCallback函數向應用層GenericApp_ProcessEvent發送一個有按鍵需要處理的消息,最終由GenericApp_HandleKeys來負責執行具體的操作。讓我們再回到最初的問題,任務處理表tasksEvents是怎么被改動的呢?初始化程序、其他任務或者本任務主要通過下面幾種方式對其操作:1、設置計時器,當其溢出時,觸發事件處理2、直接通過任務間的消息傳遞機制觸發3、...(等我想到了再補充)-- by outman from feibit.com 2010.4.15 00:18   該睡覺啦~~~
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
午夜精品一区二区三区在线播放| 亚洲自拍偷拍色片视频| 久久久久久久久久久久av| 国产精品久久久av久久久| 久久人人爽人人爽爽久久| www.欧美精品| 精品国产成人av| 国产欧美一区二区三区久久| 日韩av影视综合网| 欧美有码在线观看视频| 成人a级免费视频| 国产国语刺激对白av不卡| 97av在线影院| 91精品国产自产在线观看永久| 亚洲欧洲激情在线| 久久精品亚洲精品| 亚洲欧美精品suv| 日韩在线激情视频| 欧美亚洲国产视频小说| 亚洲人成电影在线观看天堂色| 亚洲免费伊人电影在线观看av| 日韩视频在线免费| 久久久久久国产精品三级玉女聊斋| 91精品国产沙发| 91av在线国产| 欧美www视频在线观看| 国产视频自拍一区| 亚洲成人精品av| 中文字幕精品网| 国产国产精品人在线视| 日韩中文字幕网站| 亚洲综合社区网| 蜜臀久久99精品久久久无需会员| 精品福利一区二区| 亚洲国产精品小视频| 深夜福利国产精品| www.日本久久久久com.| 中文字幕v亚洲ⅴv天堂| 久久久久久久久久亚洲| 亚洲欧美制服中文字幕| 国内伊人久久久久久网站视频| 日韩av网址在线观看| 精品亚洲va在线va天堂资源站| 亚洲国产日韩欧美综合久久| 91色视频在线导航| 大桥未久av一区二区三区| 久热99视频在线观看| 国产精品日韩在线播放| 97精品国产97久久久久久春色| 亚洲少妇激情视频| 欧美日韩福利视频| 日韩色av导航| 亚洲自拍小视频免费观看| 91精品国产91久久久久久| 精品人伦一区二区三区蜜桃免费| 日韩性xxxx爱| 日韩精品视频在线观看网址| 91免费的视频在线播放| www.99久久热国产日韩欧美.com| 国产精品福利在线观看| 成人h猎奇视频网站| 欧美专区日韩视频| 青青草原成人在线视频| 理论片在线不卡免费观看| 亚洲欧美www| 欧美亚洲国产成人精品| 精品国产欧美一区二区五十路| 久久伊人91精品综合网站| 色婷婷久久一区二区| 久久国产精彩视频| 欧美午夜片在线免费观看| 永久免费精品影视网站| 另类图片亚洲另类| 欧美成人午夜免费视在线看片| 亚洲开心激情网| 日韩经典一区二区三区| 在线观看亚洲视频| 亚洲精品中文字幕女同| 欧美亚洲一级片| 91成人免费观看网站| 97超级碰碰碰| 91久久国产精品91久久性色| 一区二区欧美日韩视频| 日韩**中文字幕毛片| 精品视频久久久久久| 韩国精品久久久999| 色偷偷av一区二区三区| 国产精品成人一区二区| 91精品国产91久久久久久最新| 日韩精品高清视频| 国产亚洲综合久久| 欧美美女15p| 日本最新高清不卡中文字幕| 久久99国产综合精品女同| 在线亚洲国产精品网| 亚洲第一精品福利| 久久韩剧网电视剧| 中文字幕在线看视频国产欧美在线看完整| 亚洲欧美日韩一区二区三区在线| 黑丝美女久久久| 国产精品18久久久久久首页狼| 少妇高潮久久久久久潘金莲| 38少妇精品导航| 久久精品国产亚洲一区二区| 国产91精品青草社区| 亚洲精品视频在线观看视频| 国产成人精品久久二区二区| 国产视频久久久| 国产精品久久久久久av福利| 国产裸体写真av一区二区| 色婷婷综合成人av| 亚洲国产精品电影在线观看| y97精品国产97久久久久久| 日韩欧美综合在线视频| 久久国产精品影视| 日韩视频第一页| 欧美日在线观看| 亚洲精品98久久久久久中文字幕| 97在线观看免费高清| 成人a视频在线观看| 国产日韩中文在线| 亚洲va久久久噜噜噜| 中文字幕欧美精品在线| 国产欧美精品一区二区三区介绍| 国产日本欧美一区二区三区在线| 91精品国产91久久久久久吃药| 亚洲全黄一级网站| 最新91在线视频| 亚洲午夜精品久久久久久久久久久久| 亚洲欧美日韩区| 欧美日本在线视频中文字字幕| 成人欧美一区二区三区在线湿哒哒| 色综合久久88色综合天天看泰| 亚洲自拍另类欧美丝袜| 亚洲欧美日韩国产精品| 69国产精品成人在线播放| 粉嫩av一区二区三区免费野| 国产精品精品视频一区二区三区| 九九热在线精品视频| 日韩亚洲综合在线| 最新69国产成人精品视频免费| 亚洲小视频在线| 福利精品视频在线| 中文字幕日韩欧美在线视频| 亚洲精品久久在线| 亚洲一区二区久久| 欧美电影免费观看大全| 综合欧美国产视频二区| 亚洲第一区第一页| 亚洲精品色婷婷福利天堂| 91精品国产高清久久久久久| 国产精品久久久久国产a级| 91最新在线免费观看| 亚洲欧美制服中文字幕| 亚洲性生活视频| 美女啪啪无遮挡免费久久网站| 国产99久久精品一区二区 夜夜躁日日躁| 成人av资源在线播放| 91免费视频国产| 日韩av电影院| 欧美性生交xxxxx久久久| 最近中文字幕mv在线一区二区三区四区| 欧美日韩国产一区中文午夜| 久久久之久亚州精品露出|