Ch4嵌入式實時操作系統_第1頁
Ch4嵌入式實時操作系統_第2頁
Ch4嵌入式實時操作系統_第3頁
Ch4嵌入式實時操作系統_第4頁
Ch4嵌入式實時操作系統_第5頁
已閱讀5頁,還剩71頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第四章

μC/OS-Ⅱ內核結構與運行流程本章要點μC/OS-Ⅱ內核結構及可裁剪性μC/OS-Ⅱ任務管理及表管理μC/OS-Ⅱ就緒表管理及算法分析μC/OS-Ⅱ任務調度及實現、任務調度的打開和關閉μC/OS-Ⅱ空閑任務及實現μC/OS-Ⅱ統計任務及實現μC/OS-Ⅱ任務的初始化μC/OS-Ⅱ中斷處理μC/OS-Ⅱ時鐘節拍μC/OS-Ⅱ內核的核心模塊core.c1.操作系統服務嵌入式實時操作系統基本性質RTOS是一種能夠響應時間約束控制以及事件控制過程的操作系統,這個控制過程具有預先設置的時限要求。RTOS是一種對任務、中斷服務子程序有實時限制和截止時間要求的操作系統。實時操作系統軟件提供的服務

任務管理、任務優先級、任務調度及算法、優先級繼承系統預計時間屬性:任務抖動即時限值最好情況和最壞情況的時間差。內存管理:應用程序任務能夠在內核空間運行,訪問內核代碼、堆棧、數據的內存空間,將導致內核代碼不可防護。采用定長內存塊分配的內存分配方法,分配速度快。時鐘管理:提供計時函數,完成時間分配和重置,以確保給定計時時限的有效性。任務同步機制:信號量、郵箱、消息隊列等。2.基于RTOS嵌入式系統基本設計基本機制RTOS提供在內核空間運行用戶線程的機制;RTOS提供中斷、驅動、IST、任務或線程的處理;RTOS提供內存分配和釋放函數;RTOS提供對零到多個任務的調度、運行和阻塞操作;RTOS提供簡單操作,如I/O、文件、管道第等;RTOS提供對于CPU的多個狀態、內部和外部設備的有效管理。RTOS支持下的嵌入式系統基本設計原則中斷處理子程序ISR和任務的設計原則中斷服務線程或任務的設計原則任務設計原則模塊化設計原則堅持數據封裝任務設計原則減少系統調用話費時間設計原則優先級設置策略和搶占式調度策略避免刪除任務設計原則利用空閑的CPU時間執行系統內部函數任務內完成內存分配和回收的設計原則謹慎使用任務間共享資源和數據層次和限定范圍優先級搶占調度任務的運行規律假設一個編碼消息流到達一個嵌入式系統端口A,對每個消息進行解碼,并傳送到端口B。應用程序功能設計為5個任務運行,優先級大到小:任務B1:檢測端口A是否有消息任務B2:讀出端口A的消息任務B3:消息解碼任務B4:消息編碼任務B5:傳送編碼消息到端口B任務B1等待來自端口A的中斷任務B2讀出來自端口A的消息任務B3解碼來自端口A的消息隊列消息任務B4對消息再次編碼任務B5向端口B寫入編碼消息運行上下文任務B1任務ISRB2任務B3任務B4任務B5保存上下文B3RunningB1RunningBlockedB3B2FinishRunningBlockedB3B3FinishFinishRunningB4FinishFinishFinishRunningB5FinishFinishFinishFinishRunningB1RunningBlockedB5B2FinishRunningBlockedB5B3FinishFinishRunningBlockedB5程序運行過程中各任務執行情況及上下文切換

操作系統μC/OS-II的內核模塊結構核心雜項功能管理:os_core.c標志功能管理:os_flag.c消息郵箱管理:os_mbox.c內存塊管理:os_mem.c互斥信號量管理:os_mutex消息隊列管理:os_q.c計數信號量管理:os_sem.c任務管理:os_task.c時鐘管理:os_time.c基于內核的應用軟件編程當用戶基于μC/OS-II內核,進行應用程序設計實現時,用戶應用代碼可以通過調用內核函數,并完成編譯、鏈接等操作,用以形成可執行程序代碼,實現具有實時特性的軟件。3.uC/OS-II基本模塊功能OSInit()OSIntEnter()OSIntExit()OSSchedLock()OSSchedUnlock()OSStart()OSStartInit()OSVersion()OSTimeTick()3.uC/OS-II基本模塊功能OS_Dummy()OS_EventTaskRdy()OS_EventTaskWait()OS_EventTO()OS_EventWaitListInit()OS_InitEventList()OS_InitMisc()OS_InitRdyList()OS_InitTaskIdle()OS_EventTO()3.uC/OS-II基本模塊功能OS_InitTaskStat()OS_InitTCBList()OS_Sched()OS_TaskIdle()OS_TaskStat()OS_TCBInit()OS_EventTO()核心雜項功能管理——os_core.c系統初始化函數:voidOSInit(void)OSinit()負責對μC/OS-Ⅱ操作系統進行初始化工作,完成雜項數據、任務就緒隊列、空閑任務控制塊、空閑事件控制塊等數據結構的初始化工作。該函數功能為初始化核心數據,調用這個函數必須在調用OSStart()函數之前,OSStart()函數用于開始多任務應用系統運行,必須在創建所有μC/OS-Ⅱ任務之后調用。中斷進入函數voidOSIntEnter(void)本函數告知μC/OS-Ⅱ內核,要開始執行一個中斷處理子程序段,在該段程序執行期間,不能響應任何中斷,程序員需要確保中斷處理子程序的正確性、穩定性,以免程序癱瘓。μC/OS-Ⅱ可據此記錄、跟蹤中斷嵌套的層數,確保只對最外層的中斷處理子程序做出響應。OSIntEnter()函數和OSIntExit()函數成對使用,調用OSIntEnter()函數表示封中斷開始,調用OSIntExit()函數表示封中斷結束。中斷退出函數voidOSIntExit(void)該函數告知μC/OS-Ⅱ內核,當前正在執行的中斷服務子程序已執行完畢,μC/OS-Ⅱ可據此記錄、跟蹤中斷嵌套的變化。當最后一層嵌套的中斷處理子程序執行完畢后,也就是本程序可以響應中斷的時候,由于實時內核采用可搶占式優先級調度進行任務調度。如果在執行中斷處理子程序期間,有更高優先級的任務進入就緒態,μC/OS-Ⅱ會通過任務調度函數的執行,令中斷返回到更高優先級的任務。而被中斷執行的任務,要等待在就緒任務中,直到成為優先級最高時才能得到執行。系統任務調度關閉函數voidOSSchedLock(void)調用該函數允許應用程序禁止任務間的上下文切換,以確保當前任務能夠執行,不被高優先級的就緒任務搶奪運行權。系統任務調度打開函數voidOSSchedUnlock(void)。調用該函數,表示應用程序此時解除了任務調度關閉狀態,即允許上下文切換的發生。啟動多任務函數voidOSStart(void)該函數用于啟動多任務運行過程,令uC/OS-II內核管理已經創建好的任務。請注意,調用該函數之前,必須調用OSInit()函數,完成系統數據結構的初始化工作,并且,必須至少創建一個應用任務。系統統計數據初始化函數voidOSStatInit(void)應用代碼調用該函數計算CPU利用率首先確定,在1秒鐘內,如果沒有其他任務執行的話,一個32位計數器能夠完成的最大計數是多少CPU利用率可以由此這樣確定:每秒鐘,令一個低優先級任務跟蹤這個32位計數器的計數值,該任務優先級高,可以執行。CPU利用率的計算公式如下:CPUUsage(%)=100*(1–OSIdleCtr/OSIdleCtrMax)

OSIdleCtr指在較低優先級任務執行過程中,計數器得到的計數值

OSIdleCtrMax指在沒被中斷情況下獲取的計數器的值。表明,實時內核在并發執行實時任務時,具有的實際執行率,與單任務執行是不同的。系統版本函數INT16UOSVersion(void)。該函數用于返回uC/OS-II的版本號,返回值等于uC/OS-II版本號乘以100,也就是說,版本號2.00的返回值為200。系統時鐘節拍函數voidOSTimeTick(void)該函數用于系統時鐘嘀嗒發生時,向uC/OS-II內核發送信號。該函數一般由時鐘嘀嗒中斷處理程序調用,也可由更高優先級任務調用。等待事件發生,任務就緒函數:INT8UOS_EventTaskRdy(OS_EVENT*pevent,void*msg,INT8Umsk)該函數由其他uC/OS-II服務函數調用,用于當等待事件發生,一個任務由等待變為就緒。掛起等待事件的任務voidOS_EventTaskWait(OS_EVENT*pevent)

事件到來,任務就緒voidOS_EventTO(OS_EVENT*pevent)該函數由其他uC/OS-II服務函數調用,表明時間到時,一個任務就緒,可以運行。初始化事件控制塊隊列voidOS_EventWaitListInit(OS_EVENT*pevent)該函數由OSInit()調用,用于初始化事件控制塊自由隊列。初始化事件控制塊自由隊列函數voidOS_EventWaitListInit(OS_EVENT*pevent)該函數由OSInit()調用,用于初始化事件控制塊自由隊列。staticvoidOS_InitEventList(void)初始化雜項變量函數:staticvoidOS_InitMisc(void)該函數由OSInit()調用,用于初始化雜項數據變量。初始化就緒隊列/初始化創建空閑任務staticvoidOS_InitRdyList(void)該函數由OSInit()調用,用于初始化就緒隊列。staticvoidOS_InitTaskIdle(void)該函數用于創建空閑任務。創建統計任務staticvoidOS_InitTaskStat(void)

調用參數:無。返回值:無。初始化函數:staticvoidOS_InitTCBList(void)該函數用于初始化任務控制塊自由隊列。由OSInit()函數調用,初始化由OS_TCB構成的自由隊列。調用參數:無。返回值:無。調度函數:voidOS_Sched(void)調用該函數,判定是否有一個新的更高優先級任務就緒,等待運行。該函數由任務級代碼喚醒,不能用于中斷處理子程序中重新調度任務。中斷服務子程序的重新調度,調用系統函數OSIntExit()完成。調用說明: 1)該函數屬于uC/OS-II的內部函數,應用代碼不會調用。 2)當調度程序被鎖定時,可以防止重新調度的發生。參見函數OS_SchedLock()的使用。閑逛任務函數voidOS_TaskIdle(void*pdata) 當沒有其它高優先級任務執行時執行該任務,也許其它任務都在等待事件的發生。說明:系統函數OSTaskIdleHook()在臨界區執行之后被調用。統計任務函數voidOS_TaskStat(void*pdata)用于計算多任務環境下的一些統計數據。OS_TaskStat()是專門用來計算CPU利用率。

OSCPUUsage=100*(1–OSIdleCtr/OSIdleCtrMax)調用說明:1)該任務的優先級高于閑逛任務的優先級。該任務運行的優先級為OS_IDLE_PRIO-1。2)可以通過設置配置參數不運行該任務,即定義#defineOS_TASK_STAT_EN為0。3)可以在初始狀態下,延遲5秒鐘,使系統到達一個穩定的狀態,所有需要的任務創建完畢,才執行統計任務。初始化任務控制塊函數創建任務時使用函數原型:INT8UOS_TCBInit(INT8Uprio,OS_STK*ptos,OS_STK*pbos,INT16Uid,INT32Ustk_size,void*pext,INT16Uopt)參考任務管理函數OSTaskCreate()和

OSTaskCreateExt()調用。4.μC/OS-II內核結構(1)μC/OS-II內核實現4層架構應用代碼層:面向用戶應用功能的程序設計代碼,一般是基于內核進行的應用程序設計源代碼。處理器無關代碼層&與應用代碼相關代碼層:與處理器無關的內核功能代碼,供應用代碼層的源程序調用,以及面向應用代碼的配置文件,對應用代碼的參數等進行設置,也與處理器無關。與處理器相關代碼層:內核功能只涉及三個文件與處理器相關,將移植的工作量降到最低。當嵌入式軟件需要移植到另一個硬件平臺時,需要按照目標機的機器指令修改該層文件中的功能實現。硬件層:嵌入式系統的硬件構成,包括系統時鐘。這是嵌入式軟件運行的平臺。μC/OS-II內核的核心功能(OS_CORE.C)可裁減的如果用戶應用程序不去調用該項內核功能,這部分功能代碼就不用包含在應用軟件中。不可裁減的分別實現了中斷的關閉和打開,內核初始化,任務調度,中斷ISR的入口函數和出口函數,任務調度的關閉和打開等。不可裁減的內核功能μC/OS-II內核功能函數OS_CFG.H中置1表示函數有效函數功能OS_ENTER_CRITICAL()必有關中斷OS_EXIT_CRITICAL()必有開中斷OSInit()必有內核初始化OSStart()必有任務調度OSIntEnter()必有中斷進入OSIntExit()必有中斷退出OSSchedLock()OS_SCHED_LOCK_EN置1任務調度加鎖OSSchedUnlock()OS_SCHED_LOCK_EN置0任務調度解鎖OSVersion()必有版本(2)任務任務函數的定義形式voidYourTask(void*pdata){for(;;){/*該任務應用代碼*/ 調用uC/OS-II的某種系統服務,例如:

OSMboxPend();

OSQPend();

OSSemPend();

OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);

OSTimeDly();

OSTimeDlyHMSM(); /*該任務用戶代碼*/}}任務的狀態(3)任務控制塊(TaskControlBlocks)typedef

struct

os_tcb{

OS_STK*OSTCBStkPtr;#ifOS_TASK_CREATE_EXT_EN/*如果使用擴展任務創建*/

Void*OSTCBExtPtr;

OS_STK*OSTCBStkBottom;

INT32UOSTCBStkSize;

INT16UOSTCBOpt;

INT16UOSTCBId;#endif

struct

os_tcb*OSTCBNext;

struct

os_tcb*OSTCBPrev;#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_EN/*如果使用事件*/

OS_EVENT*OSTCBEventPtr;#endif#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN/*如果使用消息*/

Void*OSTCBMsg;#endif

INT16UOSTCBDly;

INT8UOSTCBStat;

INT8UOSTCBPrio;

INT8UOSTCBX;

INT8UOSTCBY;

INT8UOSTCBBitX;

INT8UOSTCBBitY;#ifOS_TASK_DEL_EN/*如果允許刪除任務*/

BOOLEANOSTCBDelReq;#endif}OS_TCB;空閑任務表μC/OS-Ⅱ初始化時,所有任務控制塊OS_TCBs被鏈接成一個單向空閑任務表。任務建立時——空閑任務控制塊指針OSTCBFreeList指向的任務控制塊,便分配給該任務,OSTCBFreeList的值調整為指向下鏈表中下一個空閑的任務控制塊。任務刪除時——任務控制塊就鏈入空閑任務表尾。(4)任務就緒表及其操作實現根據就緒表確定最高優先級任務進入運行態新就緒任務存入就緒表算法基礎:就緒表的結構優先數分解為高三位和低三位,分別確定優先級高優先數小

根據優先級找到任務在就緒任務表中的位置就緒任務放入任務就緒表,就緒表用兩個變量表示:OSRdyGrp、OSRdyTbl[]OSRdyGrp1207654300XXXYYY任務優先級2017654310891514131211181617232221201926242531302928273432333938373635424041474645444350484955545352515856576362616059[0][1][2][3][4][5][6][7]OSRdyTbl[8]XY優先級最低任務(空閑任務)優先級最高任務任務優先級號00001100001010011221為了找到就緒態優先級最高的任務,不需要從OSRdyTbl[0]開始掃描整個就緒任務表的各個元素值,算法設計查表,即優先級判定表OSUnMapTbl[],見文件OS_CORE.C中關于該數組表定義:INT8UconstOSUnMapTbl[]={0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, /*0x00to0x0F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x10to0x1F*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x20to0x2F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x30to0x3F*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x40to0x4F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x50to0x5F*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x60to0x6F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x70to0x7F*/7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x80to0x8F*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0x90to0x9F*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0xA0to0xAF*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0xB0to0xBF*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0xC0to0xCF*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0xD0to0xDF*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,/*0xE0to0xEF*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0/*0xF0to0xFF*/};1)采用查表法確定高優先級任務查表法具有確定時間,增加系統可預測性,C/OS–II所有系統調用時間確定。High3=OSUnMapTbl[OSRdyGrp];Low3=OSUnMapTbl[OSRdyTbl[High3]];Prio=(High3<<3)+Low3;OSRdyGrp0110100000XXXYYY任務優先級0000010000000010100001000000000000000000000000001000000000011000[0][1][2][3][4][5][6][7]OSRdyTbl[8]XY就緒表(ReadyList)結構

處于就緒態的任務將就緒態標志置于就緒表中。就緒表由變量OSRdyGrp和OSRdyTbl[]構成。如對應組中有就緒態任務,OSRdyGrp對應位置1。就緒表OSRdyTbl[]對應(Y,X)元素置1。就緒表OSRdyTbl[]數組的大小取決于OS_LOWEST_PRIO的值,可在文件OS_CFG.H中定義。OS_LOWEST_PRIO值越小,占用RAM空間越少。為確定就緒任務優先級,內核調度程序總是先將OS_LOWEST_PRIO在就緒表相應位置1。Index(下標索引)BitMask(二進制位掩碼)0000000011000000102000001003000010004000100005001000006010000007100000002、使任務進入就緒態:該算法中用到的二進制位映射查找表OSMapTbl[],定義在OS_CORE.C文件中,可確保算法執行時間的確定。該表數組值如下。使任務進入就緒態程序清單OSRdyGrp|=OSMapTbl[prio>>3];OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07];使任務進入就緒態(修改OSRdyGrp)C語句OSRdyGrp|=OSMapTbl[prio>>3]:直接從TCB中取出OSTCBY的值(即priority>>3),該值表示該任務在就緒表中的邏輯行號,即Y值,以該值為下標索引,取得OSMapTbl[Y]的值,該值為對應就緒表中的邏輯行號的掩碼值,行號所對應的二進制bit位是1。使用該掩碼值與OSRdyGrp作按位或操作,將OSRdyGrp的對應就緒表中的邏輯行號的二進制位置1。使任務進入就緒態(修改OSRdyTbl[])C語句OSRdyTbl[prio>>3]|=OSMapTbl[prio&0x07]:直接從TCB中取出OSTCBY的值(即priority>>3),該值表示該任務在就緒表中的邏輯行號,即Y值,以該值為下標索引,取得OSRdyTbl[Y]變量,即該語句等號的右邊。等式左邊:直接從TCB中取出OSTCBX的值(即priority&0x07),該值表示該priority任務在就緒表中的某邏輯行號下的第幾個任務,即X值,以該值為下標索引,取得OSMapTbl[X]變量,該值為對應就緒表中某邏輯行號下的序號的掩碼值,該序號所對應的二進制bit位是1。使用該掩碼值與OSRdyTbl[Y]作按或操作,達到將對應就緒表OSRdyTbl[]中的邏輯行號下的任務序號對應的二進制位置1的目的。OSRdyTbl[]表示優先級priority對應的就緒表中的邏輯行號及該行下的任務序號的二進制位,已置1,表明第Y行的第X個任務已就緒。附加說明:TCB表中有四個變量用來記錄相關值。任務進入就緒態或進入等待事件發生狀態算法使用。使得任務進入就緒表或進入等待表的時間是個常數,便于控制性能。避免在運行中去計算這些值。這些值在任務建立時確定,或在改變任務優先級時更新。

OSTCBY=priority>>3;OSTCBBitY=OSMapTbl[priority>>3];OSTCBX=priority&0x07;OSTCBBitX=OSMapTbl[priority&0x07];運用TCB成員算法代碼:使任務進入就緒態程序清單OSRdyGrp|=OSMapTbl[priority>>3];OSRdyTbl[priority>>3]|=OSMapTbl[priority&0x07];使任務進入就緒態程序清單OSRdyGrp|=OSTCBBitY;OSRdyTbl[OSTCBY]|=OSTCBBitX;(5)任務調度(TaskScheduling)

μC/OS-Ⅱ內核總是運行就緒態任務中優先級最高的。前面算法已確定最高優先級任務。下面由調度程序(Scheduler)完成該任務運行。任務級調度由函數OSSched()完成中斷級調度由函數OSIntExt()完成根據實時內核的設計需求,μC/OS-Ⅱ任務調度程序運行所花費時間是個常數,與應用程序中建立的任務數無關。

程序清單任務調度程序(TaskScheduler)voidOSSched(void){

INT8Uy;

OS_ENTER_CRITICAL();

if((OSLockNesting|OSIntNesting)==0){ (1)

Y=OSUnMapTbl[OSRdyGrp]; (2)

OSPrioHighRdy=(INT8U)((y<<3)+OSUnMapTbl[OSRdyTbl[y]]); (2)

if(OSPrioHighRdy!=OSPrioCur){ (3)

OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy]; (4)

OSCtxSwCtr++;(5)

OS_TASK_SW();(6)

}}

OS_EXIT_CRITICAL();}任務調度的關閉和打開調用任務調度關閉函數、任務調度打開函數實現1、調用任務調度關閉函數OSSchedLock()以后,不得使用任何能將現行任務掛起的系統調用,因為這些調用會導致該任務睡眠,使得任務調度程序無法重新打開。2、用戶可以在低優先級任務在進行事件發送期間,調用任務調度關閉函數,禁止任務調度。確保事件發送過程不被中斷。

程序清單:任務調度程序關閉VoidOSSchedLock(void){

if(OSRunning==TRUE){

OS_ENTER_CRITICAL();

OSLockNesting++;

OS_EXIT_CRITICAL();

}}程序清單:任務調度程序打開voidOSSchedUnlock(void){

If(OSRunning==TRUE){

OS_ENTER_CRITICAL();

if(OSLockNesting>0){

OSLockNesting--;

if((OSLockNesting|OSIntNesting)==0){

OS_EXIT_CRITICAL();

OSSched();

}else{

OS_EXIT_CRITICAL();

}

}else{

OS_EXIT_CRITICAL();

}

}}(6)空閑任務(IdleTask)為了更好地控制多個實時任務運行,μC/OS-Ⅱ內核總是建立一個空閑任務,這個任務在沒有其它任務進入就緒態時運行。空閑任務對應的函數代碼為OSTaskIdle(),空閑任務永遠設為最低優先級,即OS_LOWEST_PRI0。空閑任務OSTaskIdle()的主要工作,只是在不斷地給一個32位的變量OSIdleCtr計數器加1

μC/OS-Ⅱ的空閑任務代碼VoidOSTaskIdle(void*pdata){

Pdata=pdata;

for(;;){

OS_ENTER_CRITICAL();

OSIdleCtr++;

OS_EXIT_CRITICAL();

}}在計數器OSIdleCtr加1時,中斷關閉,加1完成后中斷再打開。這是因為,完成8位和多數16位微處理器對一個32位變量加1操作,需要多條指令,要防止高優先級任務或中斷服務子程序ISR中斷這個加1的指令執行過程。統計任務

為了完成應用程序代碼完成各種時間統計,μC/OS-Ⅱ內核提供一個統計任務,任務函數為OSTaskStat()。只當在文件OS_CFG.H中,將符號常量OS_TASK_STAT_EN設為1,這個任務才會創建。一旦創建成功,統計任務OSTaskStat()每秒鐘運行一次,計算當前的CPU利用率。程序清單

4.12初始化統計任務Voidmain(void){

OSInit();/*1、初始化uC/OS-II*/

/*2、安裝uC/OS-II的任務切換向量(略)*/

/*3、創建用戶起始任務TaskStart()(略)*/

OSStart();/*4、開始多任務調度*/}VoidTaskStart(void*pdata){

/*5、安裝并啟動uC/OS-II的時鐘節拍(略)*/

OSStatInit();/*6、初始化統計任務*/

/*7、創建用戶應用程序任務(略)*/

for(;;){

/*8、任務函數TaskStart()的代碼!*/

}}程序清單4.14統計任務VoidOSTaskStat(void*pdata){

INT32Urun;

INT8Susage;

pdata=pdata;

while(OSStatRdy==FALSE){ (1)

OSTimeDly(2*OS_TICKS_PER_SEC);

}}

for(;;){

OS_ENTER_CRITICAL();

OSIdleCtrRun=OSIdleCtr;

run=OSIdleCtr;

OSIdleCtr=0L;

OS_EXIT_CRITICAL();

if(OSIdleCtrMax>0L){

usage=(INT8S)(100L-100L*run/OSIdleCtrMax); (2)

if(usage>100){OSCPUUsage=100;

}elseif(usage<0){

OSCPUUsage=0;

}else{OSCPUUsage=usage;

}

}else{OSCPUUsage=0;

}

OSTaskStatHook(); (3)

OSTimeDly(OS_TICKS_PER_SEC);

}系統初始化期間創建的任務應用程序必須先建立一個起始任務,如TaskStart(),當應用程序運行到main()中調用uC/OS-II內核啟動函數OSStart(),μC/OS-Ⅱ內核一般已創建3個任務:TaskStart()、OSTaskIdle()和OSTaskStat()。μC/OS-Ⅱ將空閑任務優先級設為最低,即OS_LOWEST_PRIO,統計任務優先級設為次低,即OS_LOWEST_PRIO-1。啟動任務TaskStart()總是優先級最高的任務,比如,優先級為0。(7)μC/OS中的中斷處理

中斷技術及其實現是任何一種實時內核必須提供的應用機制。實時內核應該能夠支持應用程序設計實現自身需要的中斷及中斷處理子程序。μC/OS內核中,中斷服務子程序要用匯編語言來寫。如果用戶使用的C語言編譯器支持內置匯編語言,用戶可以直接將中斷服務子程序代碼放在C語言的程序文件中。程序清單

μC/OS-II中的中斷服務子程序用戶中斷服務子程序:

保存全部CPU寄存器;(1)

調用OSIntEnter或OSIntNesting直接加1;

(2)

執行用戶代碼做中斷服務;(3)

調用OSIntExit();

(4)

恢復所有CPU寄存器;

(5)

執行中斷返回指令;

(6)程序清單4.16中斷進入函數:通知μC/OS-Ⅱ內核,中斷服務子程序開始執行voidOSIntEnter(void){OS_ENTER_CRITICAL();

OSIntNesting++;

OS_EXIT_CRITICAL();}程序清單

4.17中斷退出函數:通知μC/OS-Ⅱ內核,中斷服務子程序執行完畢voidOSIntExit(void)

{OS_ENTER_CRITICAL();(1)

If((--OSIntNesting|OSLockNesting)==0){(2)

OSIntExitY=OSUnMapTbl[OSRdyGrp];(3)

溫馨提示

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

最新文檔

評論

0/150

提交評論