第三章 中斷與時鐘_第1頁
第三章 中斷與時鐘_第2頁
第三章 中斷與時鐘_第3頁
第三章 中斷與時鐘_第4頁
第三章 中斷與時鐘_第5頁
已閱讀5頁,還剩23頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

嵌入式系統

EmbeddedSystem教師:白華郵箱:baihua2000@電話公室:4A-4092.2.4任務的其他管理函數堆棧檢驗:OSTaskStkChk()確定任務實際需要的堆棧空間大小刪除任務:OSTaskDel()任務休眠,任務代碼并未刪除,只是不再被調用請求刪除任務:OSTaskDelReq()改變任務的優先級:OSTaskChangePrio()掛起任務:OSTaskSuspend()空閑任務不能被掛起恢復任務:OSTaskResume()被掛起的任務只能通過該函數恢復獲得任務信息:OSTaskQuery()獲得指定任務的OS_TCB中內容的拷貝2.3例程解析共有10個任務在屏幕隨機的位置上顯示一個0~9的數字。每個任務只顯示同一個數字,也就是其中一個任務在隨機位置顯示0,另一個顯示1,等等。該例程目的在于演示mC/OS-II的多任務處理能力。#include"includes.h"includes.h是主控頭文件,包含所有相關的頭文件,從此可使用系統提供的數據類型、系統函數和全局變量等。#defineTASK_STK_SIZE512#defineN_TASKS10定義兩個常數:TASK_STK_SIZE表示堆棧可容納的指針元數目;N_TASKS表示需要建立的任務數。OS_STKTaskStk[N_TASKS][TASK_STK_SIZE];OS_STKTaskStartStk[TASK_STK_SIZE];charTaskData[N_TASKS];OS_EVENT*RandomSem;定義不同類型的變量(或數組)voidTask(void*data);voidTaskStart(void*data);staticvoidTaskStartCreateTasks(void);staticvoidTaskStartDispInit(void);staticvoidTaskStartDisp(void);自定義函數聲明前往第17頁voidmain(void){

PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);

OSInit();PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}PC_DispClrScr()為系統函數,具有清屏功能。()中的參數表示前景色為白色,背景色為黑色。voidmain(void){PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);

OSInit();

PC_DOSSaveReturn();PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}非常重要的系統函數,執行μC/OS-II的初始化。在使用μC/OS-II的所有服務之前,必須要調用μC/OS-II的初始化函數OSInit()對μC/OS-II自身的運行環境進行初始化。函數OSInit()將對μC/OS-II的所有的全局變量和數據結構進行初始化,同時創建空閑任務OSTaskIdle,并賦之以最低的優先級別和永遠的就緒狀態。如果用戶應用程序還要使用統計任務的話(常數OS_TASK_STAT_EN=1),則OSInit()還要以優先級別為OS_LOWEST_PRIO-1來創建統計任務。初始化函數OSInit()對數據結構進行初始化時,主要要創建5個空數據緩沖區(任務控制塊、事件控制塊、消息隊列控制塊、標志控制塊、存儲控制塊)。為了可以快速地查詢任務控制塊鏈表中的各個元素,初始化函數OSInit()還要創建一個數組OSTCBPrioTbl[OS_LOWEST_PRIO+1],在這個數組中,按任務的優先級別的順序把任務控制塊的指針存放在了對應的元素中。2.3.1μC/OS-II的初始化(OSInit()函數)voidmain(void){PC_DispClrScr(DISP_FGND_WHITE+DISP_BGND_BLACK);OSInit();PC_DOSSaveReturn();

PC_VectSet(uCOS,OSCtxSw);RandomSem=OSSemCreate(1);OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);OSStart();}PC_DOSSaveReturn();/*返回到沒有運行mCOS-II之前的DOS環境*/PC_VectSet(uCOS,OSCtxSw);/*指定任務切換處理函數*/RandomSem=OSSemCreate(1);/*建立一個信號量*/信號量是由mC/OS-II提供的一種機制,用于防止多個任務同時訪問同一資源(如產生隨機數的函數)。這里信號量初值設置為1,通知mC/OS-II在某一時刻只有一個任務可以調用隨機數產生函數。該信號量建立函數返回一個指向信號量的指針。OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0);/*在開始多任務之前,必須建立至少一個任務。這里建立了一個叫做TaskStart()的任務*/OSStart();/*將控制權交給mC/OS-II內核,開始運行多任務*/2.3.2μC/OS-II的啟動(OSStart()函數)多任務的啟動是通過OSStart()實現的。在啟動mC/OS-II之前,至少須建立一個應用任務。OSStart()函數完成以下兩個工作:從任務就緒表中找出用戶建立的優先級最高的任務的任務控制塊,將該任務設為當前任務。將上述任務的堆棧中保存的值彈回到CPU寄存器中,然后執行一條中斷返回指令,強制執行該任務代碼。當OSStart()執行后,即多任務啟動以后,系統將在用戶任務之間,或用戶任務與系統任務之間切換,不再返回到主函數main()。voidTaskStart(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifchars[100];INT16Skey;pdata=pdata;TaskStartDispInit();OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);PC_SetTickRate(OS_TICKS_PER_SEC);OS_EXIT_CRITICAL();OSStatInit();TaskStartCreateTasks();與進入臨界段代碼的方式有關定義16位變量key,用于按鍵輸入本任務無參數傳遞,未使用pdata,但為了避免編譯器警告,故執行該語句初始化屏幕顯示,作者自定義的函數,詳見光盤中的源程序代碼處理臨界段代碼1)處理臨界段代碼——關中斷處理完成后——開中斷

注:開/關中斷的方法與編譯器相關。2)μC/OS-II定義了兩個宏(macros)來開中斷和關中斷:OS_ENTER_CRITICAL()OS_EXIT_CRITICAL()這兩個宏的定義取決于微處理器,在文件OS_CPU.H中可以找到相應的宏定義,而每種微處理器都有自己的OS_CPU.H2.3.3臨界段代碼(criticalsections)代碼的臨界段也稱為臨界區,指處理時不可分割的代碼。一旦這部分代碼開始執行,則不允許任何中斷打入,因此在進入臨界段之前必須關中斷,而臨界段代碼執行完后,要立即開中斷。OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL()具體實現方法有3種1)OS_CRITICAL_MATHOD=1用處理器的關中斷指令完成OS_ENTER_CRITICAL()用處理器的開中斷指令完成OS_EXIT_CRITICAL()2)OS_CRITICAL_MATHOD=2在堆棧中保存中斷的開/關狀態,然后再關中斷,實現OS_ENTER_CRITICAL()從堆棧中彈出原來的中斷開/關狀態,實現OS_EXIT_CRITICAL()#defineOS_ENTER_CRITICAL()\asm(“pushpsw”)asm(“DI”)#defineOS_EXIT_CRITICAL()\asm(“poppsw”)

3)OS_CRITICAL_MATHOD=3一些編譯器提供了擴展功能,用戶可以得到當前處理器狀態字的值,并保存在C函數的局部變量中,這個變量可以恢復PSW。#defineOS_ENTER_CRITICAL()\cpu_sr=get_processor_psw();\disable_interrupts();#defineOS_EXIT_CRITICAL()\set_processor_psw(cpu_sr);如果使用這種方式保護臨界段代碼,則須在應用程序的相關函數中多定義一個局部變量cpu_sr。voidTaskStart(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifchars[100];INT16Skey;pdata=pdata;TaskStartDispInit();OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);PC_SetTickRate(OS_TICKS_PER_SEC);OS_EXIT_CRITICAL();OSStatInit();TaskStartCreateTasks();把計算機本來為時鐘節拍提供的中斷服務程序替換成mC/OS-II需要用到的時鐘節拍中斷服務程序設置時鐘節拍的頻率為200HzOS_TICKS_PER_SEC=200通過該函數得知處理器在運行所有應用任務時實際的CPU使用率這是作者自定義的一個函數,其作用是建立更多的任務接上頁程序……for(;;){TaskStartDisp();if(PC_GetKey(&key)==TRUE){if(key==0x1B){PC_DOSReturn();}}OSCtxSwCtr=0;OSTimeDlyHMSM(0,0,1,0);}}無限循環作者自定義的顯示函數,在DOS窗口底部顯示任務數、CPU利用率等相關信息判斷是否有按鍵輸入如果按下鍵為Esc返回DOS環境如果沒有按下Esc鍵,記錄任務切換次數的全局變量OSCtxSwCtr清零,以便記錄下一秒內發生的任務切換次數延時函數,()中從左到右分別表示時、分、秒、毫秒。任務調用該函數將自身掛起1秒,交出CPU使用權,內核開始調度,找到下一個最高優先級的就緒任務staticvoidTaskStartCreateTasks(void){INT8Ui;for(i=0;i<N_TASKS;i++){TaskData[i]='0'+i;OSTaskCreate(Task,(void*)&TaskData[i],&TaskStk[i][TASK_STK_SIZE-1],i+1);}}定義一個局部變量i返回第4頁給數組TaskData[]賦值,包含0~9的ASCII字符創建10個任務,任務代碼完全相同,每個任務接受一個指向字符數組中不同元素的指針,即每個任務接受了一個不同的字符(0~9)。每個任務需分配自己的堆棧空間,且擁有一個獨一無二的優先級voidTask(void*pdata){INT8Ux,y,err;

for(;;){OSSemPend(RandomSem,0,&err);x=random(80);y=random(16);OSSemPost(RandomSem);PC_DispChar(x,y+5,*(char*)pdata,DISP_FGND_BLACK+DISP_BGND_LIGHT_GRAY);OSTimeDly(1);}}無限循環定義三個局部變量查詢信號量RandomSem,若該信號量正被其他任務占用,該任務被掛起,內核開始調度。括號中第二個參數表示超時時限,這個值為0表示無限等待調用隨機數產生函數,返回一個0~79的數值調用隨機數產生函數,返回一個0~15的數值釋放信號量RandomSem在坐標為(x,y+5)的位置顯示字符,前景色黑色,背景色淺灰色延遲一個時鐘節拍,延時期間該任務被掛起,內核開始調度第三章μC/OS-II中斷和時鐘主要內容μC/OS-II的中斷管理和中斷服務程序μC/OS-II的系統時鐘μC/OS-II的時間管理3.1μC/OS-II的中斷3.1.1、基本概念

中斷任務在運行過程中,應內部或外部異步事件的請求中止當前任務,而去處理異步事件所要求的任務的過程

中斷服務子程序(InterruptServiceRoutines,ISR)應中斷請求而運行的程序

中斷向量中斷服務子程序的入口地址3.1.2

mC/OS-II的中斷

中斷的優先級高于任務;中斷嵌套可以多達255層;當系統處于開中斷時,中斷才會響應;只有所有中斷都完成后,才能返回到任務;進入中斷時,中斷服務子程序必須調用OSIntEnter();退出中斷時,中斷服務子程序必須調用OSIntExit()。用戶中斷服務子程序流程保存全部CPU寄存器;調用OSIntEnter()或OSIntNesting直接加1;If(OSIntNesting==1){OSTCBCur->OSTCBStkPtr=SP;}清中斷源;重新開中斷;執行用戶代碼做中斷服務;調用OSIntExit();恢復所有CPU寄存器;執行中斷返回指令;進入中斷函數OSIntEnter()voidOSIntEnter(void){if(OSRunning==TRUE{if(OSIntNesting<255){OSIntNesting++;

}}}voidOSIntExit(void){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifOS_ENTER_CRITICAL();if(OSRunning==TRUE){if(OSIntNesting>0){OSIntNesting--;}if((OSIntNesting||OSLockNesting)==0){OSIntExitY=OSUnMapTbl[OSRdyGrp];OSPrioHighRdy=(INT8U)((OSIntExitY<<3)+OSUnMapTbl[OSRdyTbl[OSIntExitY]]);if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];OSCtxSwCtr++;

OSIntCtxSw();/*調用中斷切換函數,而非任務切換函數*/}}}OS_EXIT_CRITICAL();}退出中斷函數OSIntExit()時鐘:任何操作系統都要提供一個周期性的信號源,以提供系統處理諸如延時、超時等與時間有關的事

溫馨提示

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

評論

0/150

提交評論