一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

OSAL調度機制

 韋小楓 2012-11-30

摘要:

1、任務調度:osal采用一個鏈表結構來管理協(xié)議棧各層相應任務。相關操作函數有,添加任務到鏈表中;獲取下一個活動任務;根據taskID查找下一個任務。osal采用輪詢任務調度隊列(任務鏈表),通過兩個函數:調度程序主循環(huán)函數和設置事件發(fā)生標志函數。

2、時間管理:通過為事件設置超時等待時間,一旦等待時間結束,便為對應任務設置事件發(fā)生標志,從而達到對事件進行延時處理目的。

3、原語通信:請求響應原語操作:一旦調用了下層相關函數后,就立即返回。下層處理函數在操作結束后,將結果以消息的形式發(fā)送到上層并產生一個系統(tǒng)事件,調度程序發(fā)現(xiàn)這個事件后就會調用相應的事件處理函數對它進行處理。兩個相關函數:向目標任務發(fā)送消息的函數;消息提取函數。

 

一、操作系統(tǒng)介紹
       現(xiàn)有的嵌入式操作系統(tǒng)可以分為兩類,即通用的多任務操作系統(tǒng)(General—purpose Multi-tasking OS)和事件驅動的操作系統(tǒng)(Event-driven OS)。前者能夠很好地支持多任務或者多線程,但是會隨著內部任務切換頻率的增加而產生很大的開銷,這類操作系統(tǒng)有:uC/OS-II、嵌入式Linux、WinCE等。后者支持數據流的高效并發(fā),并且考慮了系統(tǒng)的低功耗要求,在功耗、運行開銷等方面具有優(yōu)勢。典型的代表如TinyOSl291。

    目前TinyOS操作系統(tǒng)支持的平臺有ATMEL公司的AVR系列、TI公司的MSP430系列。由于TinyOS操作系統(tǒng)還沒有對Chipcon公司(才知道TI把它收購了OSAL調度機制 - 小峰 - happy~)提供CC2430開發(fā)平臺提供支持,因此,要在CC2430開發(fā)平臺上使用TinyOS系統(tǒng)來開發(fā)Zigbee協(xié)議棧軟件,就必須首先對TinyOS進行移植?;页B闊?img doc360img-src='http://image57.360doc.com/DownloadImg/2012/11/3009/28576546_2.gif' alt="OSAL調度機制 - 小峰 - happy~" src="http://image57.360doc.com/DownloadImg/2012/11/3009/28576546_2.gif" __1354239570243__="ev_4380742244">……

   因此Chipcon公司為自己設計的ZStack協(xié)議棧中提供了一個名為操作系統(tǒng)抽象層OSAL的協(xié)議棧調度程序。

//-------------------------------------------------------------------------------------

二、下面分析下這個協(xié)議棧調度程序(OSAL)的調度機制。

        三部分:1、任務調度

                       2、時間管理

                       3、原語通信

(一)任務調度

                                               //每層任務=對應事件處理函數         

                                               //任務鏈表,任務按優(yōu)先級插入
        ZigBee協(xié)議棧中的每一層都有很多原語操作要執(zhí)行,因此對于整個協(xié)議棧來說,就會有很多并發(fā)操作要執(zhí)行。協(xié)議棧的每一層都設計了一個事件處理函數,用來處理與這一層操作相關的各種事件。這些事件處理函數可以看成是與協(xié)議棧每一層相對應的任務,由ZigBee協(xié)議棧中調度程序OSAL來進行管理。這樣,對于協(xié)議棧來說,無論何時發(fā)生了何種事件,我們都可以通過調度協(xié)議棧相應層的任務即事件處理函數來進行處理。這樣,整個協(xié)議棧便會按照時間順序有條不紊的運行。
        ZigBee協(xié)議棧的實時性要求并不高,因此在設計任務調度程序時,OSAL只采用了輪詢任務調度隊列的方法來進行任務調度管理。

        OSAL采用一個鏈表結構來管理協(xié)議棧各層相應的任務。鏈表中的每一項是一個結構體,用來記錄鏈表中相關任務的基本信息。鏈表的建立是按照任務優(yōu)先級從高到低的順序進行插入的。優(yōu)先級高的任務將被插入到優(yōu)先級低的任務前面。如果倆任務優(yōu)先級相同,則按照時間順序加入到鏈表中。那么這個任務鏈表在系統(tǒng)啟動的時候建立,一旦建立后便一直存在于事個系統(tǒng)運行的過程中,直到系統(tǒng)關閉或硬件復位才被銷毀。

        鏈表中的每一項數據結構聲明:

typedef void (*pTaskInitFn)(unsigned char task_id) ; //指向任務初始化函數
typedef void (*pTaskEventHandlerFn)(usigned char task_id unsigned short event_flag);
 
//指向事件處理函數

typedef struct osalTaskRec
{
  struct osalTaskRec          *next;                           //指向鏈表中下一個結構體
  pTaskInitFn                       pfnInit;                         //指向相關層任務初始化函數
  pTaskEventHandlerFn     pfnEventProcessor;  //指向相關層事件處理函數
  byte                                    taskID;                         //對應當前任務ID
  byte                                    taskPriority;                //當前任務優(yōu)先級
  uint16                                 events;                       //需要被處理的事件,0表示沒有要被處理事件
} osalTaskRec_t; 
//鏈表中的每一項數據結構

//-------------------------------------------------------------------------------------

        對于pfnInit,是指向相關層任務初始化函數的指針,比如:

        網絡層中,任務初始化函數為nwkInit(),用來對網絡層相關數據進行初始化操作。函數聲明為

        extern void nwkInit(byte task_id);

       //task_id表示為網絡層任務分配的唯一任務號

//-------------------------------------------------------------------------------------
       
對于 pfnEventProcessor是指向協(xié)議棧相關層的事件處理函數指針。比如:

        網絡層中,事件處理函數nwk_event_loop(),用來處理與網絡層相關的各種事件。函數聲明為

        extern void nwk_event_loop(byte task_id, uint16 event_flag);

        //event_flag標志需要在網絡層處理的事件

//-------------------------------------------------------------------------------------

       上面記錄的是鏈表中的每一項數據結構,與任務鏈表有關的主要操作有:添加任務到列表中;獲取下一個活動任務;根據taskID值查找相應的任務。

(1)在任務管理列表中添加任務

        這個函數遍歷整個任務隊列鏈表,并按照優(yōu)先級的高低將優(yōu)先級高的任務插入到優(yōu)先級低的任務前面;否則,就將任務插入到鏈表的尾部。在這個過程中,將為每個任務分配一個唯一的任務號。函數聲明為:

Extern osalTaskAdd(pTaskInitFn pfnInit,pTaskEventHandleFn pfnEventProcessor,byte taskPriorty);

 

(2)獲取下一個活動任務

       這個函數將根據osalTaskRec_t結構中的events標記來獲取任務隊列中下一個要執(zhí)行的任務。函數聲明:

  Extern osalTaskRec_t *osalNextActiveTask(void) ;

(3)根據taskID查找任務  

      這個函數將根據任務列表在建立過程中為協(xié)議棧中每個任務分配的任務號,來查找對應任務。函數聲明:

    Extern osalTaskRec_t  *osalFindTask(byte taskID); 

當任務鏈表建立成功后,系統(tǒng)便開始運行。如果在系統(tǒng)運行的過程中有事件發(fā)生,系統(tǒng)就會通過調用相應的任務,即事件處理函數,對所發(fā)生的事件進行相應處理。在整個運行過程中,調度程序(OSAL)始終不停地輪詢任務隊列鏈表,以發(fā)現(xiàn)需要處理的事件。這個過程涉及兩個函數操作:

1、調度程序主循環(huán)函數

2、設置事件發(fā)生標志函數

 

(1)系統(tǒng)主循環(huán)

        這個函數始終不停地輪詢隊列鏈表,來處理系統(tǒng)發(fā)生的各種事件。函數聲明和部分實現(xiàn)如下:

 extern void osal_start_system(void);

        //無限循環(huán)

 for(; ; )

{

    activeTask=osalNextActiveTask();

    if(activeTask)

    {

        StoreDisableInts;

        events=activeTask—>events;

        activeTask—>events=0;

        if(events!=0)

        {

            (activeTask—>pfnEventProcessor)(activeTask—>taskID,events);

            RestoreInts;

        }

    }

}

(2)設置事件發(fā)生標志

        當協(xié)議棧中有任何事件發(fā)生時,我們可以通過設置osalTaskRec_t結構中的events來標記有事件發(fā)生,以便主循環(huán)函數能夠及時加以處理。函數聲明如下:

 extern byte osal_set_event(byte task_id,uint16 event_flag);

 

 

 (二)時間管理

           協(xié)議棧中的每層都會有很多不同的事件發(fā)生,這些事件發(fā)生的時間順序各不相同。很多時候,事件并不要求立即得到處理,而是經過一定的時間后再進行處理。OSAL調度程序設計了與時間管理相關的函數,用來各種不同的要被處理的事件。

         對事件進行時間管理,OSAL也采用了鏈表的方式進行,有時發(fā)生一個要被處理的事件,就啟動一個邏輯上的定時器,并將此定時器添加到鏈表當中。利用硬件定時器作為時間操作的基本單元。設置時間操作的最小精度為1ms,每1ms硬件定時器便產生一個時間中斷,在時間中斷處理程序中去更新定時器鏈表。每次更新,就將鏈表中的每一項時間計數減1,如果發(fā)現(xiàn)定時器鏈表中有某一表項時間計數已減到0,則將這個定時器從鏈表中刪除,并設置相應的事件標志。這樣任務調度程序便可以根據事件標志進行相應的事件處理。具體參見關于“系統(tǒng)時鐘”的記錄。

       時間管理函數:

extern byte osal_start_timer(byte task_id, uint16 event_id, uint16 timeout_value);

這個函數為事件event_id設置超時等待時間timeout_value。一旦等待結束,便為task_id所對應的任務設置相應的事件發(fā)生標記,再對事件進行相應處理。

 

 

(三)原語通信

原語只是一個理論層面上的術語,描述了服務層次的關系,以及兩個通信的N用戶和它們相連的N層(子層)對待協(xié)議實體之間的關系。初學時總是想不通原語跟協(xié)議棧的代碼有什么關系,后來才了解了原語只是規(guī)范里面的一個術語,反映到協(xié)議棧代碼里就是一個個具體的函數了!例如我們可以看到很多原語是以request,confirm等為后綴的,到了程序里面就是相應的request請求函數,confirm確認函數了。)

        對請求(request)、響應(response)原語可以直接使用函數調用來實現(xiàn)

       對確認(confirm)、指示(indication)原語則需采用間接處理機制來完成

一個原語的操作往往需要逐層調用下層函數并根據下層返回的結果來進行進一步的操作。在這種情況下,一個原主的操作從發(fā)起到完成需要很長時間。因此,如果讓程序一直等待下層返回的結果再進一步處理,會使微處理器大部分時間處于循環(huán)等待之中,無法及時處理其它請求。

      因此,與請求、響應原語操作相對應的函數,一旦調用了下層相關函數后,就立即返回。下層處理函數在操作結束后,將結果以消息的形式發(fā)送到上層并產生一個系統(tǒng)事件,調度程序發(fā)現(xiàn)這個事件后就會調用相應的事件處理函數對它進行處理。(調用就返回,而不管函數有沒有處理完成。當函數處理完成后將結果以消息的形式發(fā)送到上層產生一個系統(tǒng)事件)。

      OSAL調度程序用兩個相關的函數來完成這個過程:

1、向目標任務發(fā)送消息的函數

      這個函數主要用來將原語操作結果以消息的形式往上層任務發(fā)送,并產生一個系統(tǒng)事件來通知調度程序。函數聲明如下:

extern byte osal_msg_send(byte destination_task,byte *msg_ptr,byte len);

參數destination_task是目標任務的任務號,參數指針msg_ptr指向要被發(fā)送的消息,參數len為消息長度

 

2、消息提取函數

      這個消息用來從內存空間中提取相應的消息。其中消息結構和函數聲明如下:

typedef struct

{

    byte task_id;

    byte dst_task_id;

    byte send_len;

}osal_msg_rec_header_t;

 

typedef struct

{

    osal_msg_rec_header_t  hdr;

    byte *msg_ptr;

}osal_msg_received_t;      //消息結構(上面結構體包含在里面)

 

extern osal_msg_received_t   osal_rcvd;  //全局變量

 

extern osal_msg_received_t    *osal_msg_receive(byte task_id); //接收任務

 

這個函數返回一個指向osal_msg_received結構的指針,通過msg_ptr這個指針就可以提取出所需要的信息。(有一個例子,是以MAC層返回原語MCPS_DATA.confirm所對應的函數為例,下次再說明)

 

說明:本文作者所記錄,錯誤處還請高手指點,本人隨時更新,轉載請注明出處。

           本文《OSAL調度機制》主要內容參考廈門大學閆沫的《zigbee協(xié)議棧分析與設計》

           參考資料:《zigbee技術基礎及案例分析》;《zigbee協(xié)議棧分析與設計》;

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    午夜精品成年人免费视频| 一二区不卡不卡在线观看| 欧美不雅视频午夜福利| 国产亚洲欧美另类久久久| 精品欧美日韩一区二区三区 | 中文字幕在线五月婷婷| 成年人免费看国产视频| 国产日韩欧美综合视频| 日本高清一区免费不卡| 在线免费国产一区二区三区| 四季精品人妻av一区二区三区 | 九九热最新视频免费观看| 国产午夜精品在线免费看| 成人精品一级特黄大片| 青草草在线视频免费视频| 亚洲伊人久久精品国产| 2019年国产最新视频| 国产免费无遮挡精品视频| 91欧美激情在线视频| 日韩国产欧美中文字幕| 黄片在线观看一区二区三区| 国产无摭挡又爽又色又刺激| 久久精品伊人一区二区| 白丝美女被插入视频在线观看| 亚洲中文字幕在线观看黑人| 蜜桃传媒视频麻豆第一区| 日本人妻中出在线观看| 国产一区欧美一区二区| 国产午夜精品亚洲精品国产| 国产精品激情对白一区二区| 91亚洲熟女少妇在线观看| 亚洲乱码av中文一区二区三区| 青草草在线视频免费视频| 国产精品免费不卡视频| 免费啪视频免费欧美亚洲| 欧美黑人精品一区二区在线 | 亚洲中文字幕视频在线观看| 午夜国产精品福利在线观看| 不卡视频免费一区二区三区| 女人高潮被爽到呻吟在线观看| 色一情一乱一区二区三区码|