




已閱讀5頁,還剩45頁未讀, 繼續免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
基于嵌入式操作系統VxWorks的多任務并發程序設計(1)基本概念02月 13th, 2006 by 宋寶華 作者:宋寶華 e-mail:21 出處:軟件報(轉載請務必注明作者與出處) 1引言 嵌入式系統定義為:嵌入到對象體系中的專用計算機系統。“嵌入性”、“專用性”與“計算機系統”是嵌入式系統的三個基本要素,對象系統則是指嵌入式系統所嵌入的宿主系統。目前,隨著高端消費類電子產品(如PDA、手機、智能家電)的普及,嵌入式計算機系統獲得了相當廣泛的應用。 操作系統在嵌入式軟件體系中占據著重要低位,學習和掌握相關的知識是一名嵌入式系統研發人員的必須。 1.1本文的讀者對象與寫作目的 本文針對的讀者對象為入門級的嵌入式系統軟件開發人員以及其他對嵌入式操作系統感興趣的朋友,順利閱讀本文需要讀者具備的基本知識能力為: (1)熟練的C語言程序設計能力; (2)操作系統的基本知識。 如果讀者具備在Windows平臺下進行多線程程序設計或者其他嵌入式操作系統本臺下進行多任務程序設計的經驗,將對閱讀本文有很大的幫助。 本文雖然以VxWorks為介紹的主體對象,但是其中所論述的概念和方法并不局限于VxWorks操作系統本身。它們也同樣適用于其它嵌入式操作系統,如WinCE、嵌入式Linux、ucos等,所謂“萬變不離其宗”。 筆者力求能以通俗和形象的語言進行論述,但是由于水平有限,文中難免存在錯誤和紕漏,誠盼讀者朋友指正。 1.2 為什么以VxWorks為寫作對象 之所以選擇VxWorks操作系統為本文的寫作對象,是因為: (1)VxWorks具備清晰的多任務并發控制及任務間通信的成熟機制; (2)VxWorks有廣泛的使用基礎,國內外分布著大量的VxWorks程序員; (3)VxWorks簡單易學,便于我們集中目標講解多任務控制程序本身。 1.3 什么是VxWorks VxWorks操作系統是美國WindRiver公司于1983年設計開發的一種嵌入式實時操作系統(RTOS),它憑借著良好的可持續發展能力、高性能的內核以及友好的用戶開發環境,在嵌入式實時操作系統領域占據了重要一席。VxWorks具備高可靠性和實時性,因而被廣泛地應用在通信、軍事、航空、航天等高精尖技術及實時性要求極高的領域中,如衛星通訊、軍事演習、彈道制導、飛機導航等。在美國的F-16、FA-18戰斗機、B-2隱形轟炸機和愛國者導彈上,甚至連1997年4月在火星表面登陸的火星探測器上也使用到了VxWorks。 VxWorks的 實時性體現在它能在限定時間內執行完規定的功能并對外部的異步事件作出響應。實時操作系統主要應用于過程控制、數據采集、通信、多媒體信息處理等對時間敏 感的場合;而分時操作系統按照相等的時間片調度進程輪流運行,無法實時響應外部異步事件,因而主要應用于科學計算和實時性要求不高的場合。 VxWorks由一個體積很小的內核及一些可以根據需要進行定制的系統模塊組成。VxWorks 內核最小為 8KB,即便加上其它必要模塊,所占用的空間也很小,且不失其實時、多任務的系統特征。VxWorks的內核主要包括: (1)多任務:為滿足真實世界事件的異步性,現代操作系統需提供多任務支持,由系統內核分配CPU給多個任務并發執行。如果是單CPU,則執行方式實質是宏觀并行、微觀串行; (2)任務調度:真實世界的事件具有繼承的優先級,當一個高優先級的任務變為可執行態,它會立即搶占當前正在運行的較低優先級的任務,VxWorks對這種優先級搶占調度(Preemptive Priority Scheduling)提供了支持。同時,VxWorks也支持同優先級任務間的時間片輪轉調度(Round-Robin Scheduling); (3)任務間的通訊與同步:在一個實時系統中,系統必須提供多個任務間快速且功能強大的通信機制,并提供為了有效地共享不可搶占的資源或臨界區所需的同步機制; (4)任務與中斷之間的通信:許多外設以中斷方式與CPU通信,我們不宜在中斷服務程序(ISR)中進行過多的處理,通常將相應處理交給特定任務去完成。 VxWorks前些年對我國一直采取禁運措施,自從對中國的銷售解禁以來,它在中國贏得了越來越多的用戶。 2 進程、線程與任務 既然我們是講解一種操作系統,那我們就有必要再老生長嘆一次進程與線程的概念及其區別。 進程(Process) 是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,是系統進行資源分配和調度的一個獨立單位。程序只是一組指令的有序集合,它本身沒有任何運行 的含義,只是一個靜態實體。而進程則不同,它是程序在某個數據集上的執行,是一個動態實體。它因創建而產生,因調度而運行,因等待資源或事件而被處于等待 狀態,因完成任務而被撤消,反映了一個程序在一定的數據集上運行的全部動態過程。 線程(Thread)是進程的一個實體,是CPU調度和分派的基本單位。線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。 線 程和進程的關系是:線程是屬于進程的,線程運行在進程空間內,同一進程所產生的線程共享同一內存空間,當進程退出時該進程所產生的線程都會被強制退出并清 除。線程可與屬于同一進程的其它線程共享進程所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在運行中必不可少的信息(如程序計數器、一組寄存器和棧)。 根據進程與線程的設置,操作系統大致分為如下類型: (1)單進程、單線程,MS-DOS大致是這種操作系統; (2)多進程、單線程,多數UNIX(及類UNIX的LINUX)是這種操作系統; (3)多進程、多線程,Windows NT(以及基于NT內核的Windows 2000、XP等)、Solaris 2.x和OS/2都是這種操作系統; (4)單進程、多線程,可以認為VxWorks是這種操作系統。VxWorks只有一個進程(內存空間和資源分配),其任務的概念與線程大致相當,所有任務之間共享內存和其它資源。 3 開發環境 嵌入式軟件開發不同于PC機Windows操作系統之上的應用軟件開發,它一般需要一個交叉編譯和調試環境。編譯和調試軟件運行在宿主機上(我們通常使用的PC機,Windows操作系統),它們按照目標平臺CPU指令集生成目標代碼,并將目標代碼下載到目標機上運行;此后,主機和目標機需建立通訊連接,并傳輸調試命令和數據。調試方式如下圖所示:VxWorks的開發環境為WindRiver公司提供的Tornado,它支持的目標平臺可以是X86、ARM、PowerPC等類型處理器。Tornado包含三個高度集成的部分: (1)運行在宿主機和目標機上的強有力的交叉開發工具和實用程序; (2)運行在目標機上的高性能、可裁剪的實時操作系統VxWorks; (3)連接宿主機和目標機的多種通訊方式,如:以太網,串口線,ICE或ROM仿真器等。 對于不同的目標機,Tornado給開發者提供一個一致的圖形接口和人機界面,如下圖所示:我們通常需要一塊目標電路板來進行嵌入式系統的開發調試工作,但是相信還有相當多的讀者朋友沒有目標開發電路板,為了實現本文中代碼的調試,我們可采用兩種方式: (1)使用Tornado提供的VxSim模擬器來模擬調試,在此模擬器平臺上,我們同樣可以實現和運行本文中將介紹的大部分程序。VxSim是一個原型仿真器,它能使開發者在沒有實際目標硬件的情況下,先進行原型機應用程序的開發。如果我們要調試BSP程序,不能依賴此平臺。其界面很簡潔,如下圖:(2)使用著名的VmWare虛擬機軟件虛擬一個X86目標機平臺,安裝對應于X86版本的Tornado,我們可以調試BSP和一般應用程序。VMWare是一個“虛擬機”軟件,它使用戶可以在一臺機器上同時運行多個WIN2000/WINNT/WIN9X /DOS/LINUX/VxWorks等系統。VmWare是較“多啟動”是一個更好的選擇:“多啟動”系統在一個時刻只能運行一個系統,在系統切換時需要重新啟動機器,而VmWare則使用運行于Windows之上,各種操作系統的切換直接在VmWare軟件中進行。VmWare的界面如下圖:Posted in 3.嵌入式系統 | No Comments 基于嵌入式操作系統VxWorks的多任務并發程序設計(2)任務控制03月 5th, 2006 by 宋寶華 基于嵌入式操作系統VxWorks的多任務并發程序設計(2) 任務控制 作者:宋寶華 e-mail:21 出處:軟件報 4 任務與任務狀態 VxWorks實時內核Wind提供了基本的多任務環境。對用戶而言,宏觀上看起來,多個任務同時在執行。而本質而言,在微觀上,系統內核中的任務調度器總是在根據特定的調度策略讓它們交替運行。系統調度器需要使用任務控制塊(TCB)數據結構來管理任務調度功能,TCB被用來描述一個任務。TCB中存放了任務的上下文(context)信息,主要包括程序計數器PC、CPU內部寄存器、浮點寄存器、堆棧指針SP、任務信息等。每一任務都與一個TCB關聯,當執行中的任務被停止時,任務的上下文信息需要被寫入TCB;而當任務被重新執行時,必須要恢復這些上下文信息。 VxWorks的一個任務可能處于如下幾種狀態: Ready:就緒狀態(不是運行狀態),其他資源已經就緒,僅等待CPU,當獲得CPU后,就進入Running狀態; Pended:阻塞狀態,由于等待某些資源(CPU除外)而阻塞; Suspended:掛起狀態,這種狀態需要用taskResume才能恢復,主要用于調試。不會約束狀態的轉換,僅僅約束任務的執行; Delayed:睡眠狀態,任務以taskDelay主動要求等待一段時間再執行; 這些狀態之間的轉換關系如下: 任務狀態轉換 完成方式 Ready-pended 通過semTake()/msgQReceive()調用 Ready-delayed 通過taskDelay() ready-suspended 通過taskSuspend() pended-ready 通過其它任務對semaGive()/msgQSend()的調用 pended-suspended 通過其它任務對taskSuspend()調用 delayed-ready 延遲期滿 delayed-suspended 通過taskSuspend()調用 suspended-ready 通過taskResume()/taskActivate()調用 suspended-pended 通過其它任務的taskResume()調用 suspended-delayed 通過其它任務的taskResume()調用 5 任務控制 5.1創建任務 VxWorks程序員創建任務需使用如下API:taskSpawn (char *name, int priority, int options, int stackSize, FUNCPTR entryPt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10); 該API的參數定義如下: name:任務名; priority:任務優先級; options:任務選項,下表給出了各種option及其含義: 選項 16進制值 含義 VX_FP_TASK 00008 執行浮點協處理 VX_NO_STACK_FILL 00100 不對任務堆棧填充0xee VX_PRIVATE_ENV 00080 執行一個環境私有的任務 VX_UNBREAKABLE 00002 使任務不能斷點 VX_DSP_TASK 00200 1 = DSP協處理支持 VX_ALTIVEC_TASK 00400 1 = ALTIVEC協處理支持 stacksize:任務堆棧大小; main:任務入口函數; arg1,arg10:任務入口函數參數 下面來看一個具體的例子: 例1:創建任務 /* includes */ #include vxWorks.h #include taskLib.h #include sysLib.h int tid; /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ for (i = 0; i 10; i+) printf(%d , i); taskDelay(sysClkRateGet ( ) / 2); /* user entry */ void user_start() printf(ready to begin a new taskn); tid = taskSpawn(myTask, 90, VX_NO_STACK_FILL, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 程序運行,在VxSim上輸出: Hello, I am task 0 1 2 3 4 5 6 7 8 9 taskDelay(sysClkRateGet ( ) / 2)語句的含義為將任務延遲0.5S,因此,0、19的數字輸出之間間隔0.5S。 要特別注意taskSpawn函數的options參數,在如下幾種情況下我們都要將其它options與 VX_FP_TASK做“按位或”操作使得任務支持浮點運算(如果僅包含此選項,則不需進行或操作): (1)執行浮點操作; (2)調用返回任何浮點數的函數; (3)調用參數為浮點數的函數。 例如下列程序啟動任務的方式就不正確: 例2:創建浮點支持任務 /* task including float calculate */ void floatTask(void) printf(%f, 100 / 30.0); /* user entry */ void user_start() taskSpawn(floatTask, 90, VX_NO_STACK_FILL, 2000, (FUNCPTR) floatTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 應該將對taskSpawn函數調用的代碼改為: taskSpawn(floatTask, 90, VX_NO_STACK_FILL | VX_FP_TASK, 2000, floatTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 5.2 終止任務 exit() :終止當前任務。這個函數是不安全的,任務終止后,其所占據的內存空間并未釋放,請看下面的程序: 例3:任務退出 /* includes */ #include vxWorks.h #include taskLib.h #include sysLib.h int tid; /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ for (i = 0; i 5; i+) printf(%d , i); taskDelay(sysClkRateGet() / 2); exit(0); for (i = 5; i 10; i+) printf(%d , i); taskDelay(sysClkRateGet() / 2); /* user entry */ void user_start() printf(ready to begin a new taskn); tid = taskSpawn(myTask, 90, 0100, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 這次程序僅僅輸出: Hello, I am task 0 1 2 3 4 這意味著exit(0)語句之后的循環for (i = 5; i 10; i+)沒有被執行。 taskDelete()函數:終止任務并釋放任務占用的內存(堆棧和任務控制塊空間),其原型為:extern STATUS taskDelete (int tid); 參數tid為任務的ID。請看下面的例子:例4:刪除任務 /* includes */ #include vxWorks.h #include taskLib.h #include sysLib.h int tid; /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ for (i = 0; i 10; i+) printf(%d , i); taskDelay(sysClkRateGet() / 2); /* another task function:delete my task */ void delMyTaskFunc(void) taskDelay(sysClkRateGet() *4); printf(ready to delete taskn); taskDelete(tid); /* user entry */ void user_start() printf(ready to begin new tasksn); tid = taskSpawn(myTask, 90, 0100, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); taskSpawn(delMyTask, 90, 0100, 2000, (FUNCPTR)delMyTaskFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 運行輸出: Hello, I am task 0 1 2 3 4 5 6 7 ready to begin a new task 程序為運行輸出8、9,這是因為在此之前,myTask已經被另一個任務delMyTask刪除。 任務可能被taskDelete()調用刪除掉,但這一行為也不一定是安全的。如果我們刪除一個獲得了某些資源(如二進制信號量等)的任務,則對應的資源將不被釋放,到站其它正在等待該資源的任務永遠不能獲得資源,系統會擋掉。我們可以用 taskSafe()和 taskUnsafe ()來保護這種區域,例如: taskSafe (); semTake (semId, WAIT_FOREVER); /* Block until semaphore available */ . . .critical region . semGive (semId);semGive (semId); /* Release semaphore */ taskUnsafe (); 5.3 延遲任務 taskdelay()提供了一個簡單的任務睡眠機制,常用于需要定時/延時機制的應用中。它的原型是: STATUS taskDelay(int ticks /* number of ticks to delay task */); 可以看出使用該函數實現延時的單位為節拍(tick)。在VxWorks下通常以如下方式調用taskDelay()函數: taskDelay(sysClkRateGet()*n); 其中的n是要延遲的時間,以秒為單位。其中的sysClkRateGet(int ticks /* number of ticks every second */)函數返回系統的時鐘速率,單位是tick數/每秒。操作系統每秒的tick數可以利用sysClkRateSet()函數設置。 5.4 掛起/恢復/重啟任務 我們可以使用taskSuspend()函數掛起一個任務的運行,這個任務只有獲得對應的taskResume()后才能再次運行,這兩個API的原型為: extern STATUS taskSuspend (int tid); extern STATUS taskResume (int tid); 例5:掛起/恢復任務 /* includes */ #include vxWorks.h #include taskLib.h #include sysLib.h int tid; /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ for (i = 0; i 10; i+) printf(%d , i); taskDelay(sysClkRateGet() / 2); /* suspend and resume task */ void suspendResumeMyTask(void) taskDelay(sysClkRateGet() *3); taskSuspend(tid); printf(my task is suspendedn); taskDelay(sysClkRateGet() *3); taskResume(tid); /* user entry */ void user_start() printf(ready to begin new tasksn); tid = taskSpawn(myTask, 90, 0100, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); taskSpawn(suspendResumeMyTask, 90, 0100, 2000, (FUNCPTR) suspendResumeMyTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 運行輸出: Hello, I am task 0 1 2 3 4 5 my task is suspended 6 7 8 9 這個程序運行3秒后,suspendResumeMyTask任務掛起了myTask,輸出“my task is suspended”。suspendResumeMyTask本身延遲3秒后恢復myTask,使得myTask再次輸出“6 7 8 9”。顯然,“6 7 8 9”與“0 1 2 3 4 5”的輸出之間間隔了3秒以上的時間。 如果我們將上述程序改為: 例6:重啟任務 /* includes */ #include vxWorks.h #include taskLib.h #include sysLib.h int tid; /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ for (i = 0; i 10; i+) printf(%d , i); taskDelay(sysClkRateGet() / 2); /* reset task */ void resetMyTask(void) taskDelay(sysClkRateGet() *3); printf(my task will be resetedn); taskRestart(tid); /* user entry */ void user_start() printf(ready to begin new tasksn); tid = taskSpawn(myTask, 90, 0100, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); taskSpawn(resetMyTask, 90, 0100, 2000, (FUNCPTR)resetMyTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 運行輸出: Hello, I am task 0 1 2 3 4 5 my task will be reseted Hello, I am task 0 1 2 3 4 5 6 7 8 9 我們可以使用taskRestart()函數重新啟動一個任務,不管任務當前處于什么狀態,它都會被重新開始。該API的原型是: extern STATUS taskRestart (int tid); 在例6中,程序運行3秒后resetMyTask啟動,它復位了myTask,因此myTask被重新執行,“Hello, I am task ”以及“0 1 2 3 4 5”被再次輸出。 5.5任務鉤子 有過Windows鉤子(Hook)編程經驗的讀者應該對其概念并不陌生,Hook作為回調函數,當被掛接后。操作系統發生特定的事情時,將觸發這個Hook回調函數的執行。VxWorks也有鉤子的概念,不過比Windows要簡單許多,主要有taskCreateHook、taskDeleteHook、taskSwitchHookAdd,可以通過如下6個API來添加和刪除這三種Hook: STATUS taskCreateHookAdd (FUNCPTR createHook /* routine to be called when a task is created */ ); STATUS taskCreateHookDelete (FUNCPTR createHook /* routine to be deleted from list */); STATUS taskSwitchHookAdd (FUNCPTR switchHook /* routine to be called at every task switch */); STATUS taskSwitchHookDelete (FUNCPTR switchHook /* routine to be deleted from list */); STATUS taskDeleteHookAdd (FUNCPTR deleteHook /* routine to be called when a task is deleted */); STATUS taskDeleteHookDelete (FUNCPTR deleteHook /* routine to be deleted from list */); 請看例程: 例7:任務鉤子Hook /* includes */ #include vxWorks.h #include taskLib.h #include taskHookLib.h /taskHook所對應的庫 /* task function */ void myFunc(void) int i; printf(Hello, I am task %dn, taskIdSelf(); /* Print task Id */ /* taskCreatHook */ void myTaskHook(void) printf(task hook function calledn); /* user entry */ void user_start() taskCreateHookAdd( (FUNCPTR) myTaskHook); taskSpawn(myTask, 90, 0100, 2000, (FUNCPTR) myFunc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 運行輸出: task hook function called Hello, I am task 5.6 其它重要API 與任務控制相關的其它重要API還有: /設置任務優先級extern STATUS taskOptionsSet (int tid, int mask, int newOptions); /獲得任務優先級extern STATUS taskOptionsGet (int tid, int *pOptions); /從任務ID獲得任務名extern char *taskName (int tid); /從任務名獲得任務IDextern int taskNameToId (char *name); /確認ID為tid的任務是否存在extern STATUS taskIdVerify (int tid); /獲得任務自身IDextern int taskIdSelf (void); /任務狀態是否為readyextern BOOL taskIsReady (int tid); /任務狀態是否為Suspendedextern BOOL taskIsSuspended (int tid); /獲得任務的TCB指針extern WIND_TCB *taskTcb (int tid); /獲得任務的優先級STATUS taskPrioritySet (int tid, /* task ID */ int newPriority /* new priority */ ); /任務鎖定與解鎖:一個任務調用taskLock()后,任務運行時將沒有基于優先級的搶占發生;而taskUnlock()則用于恢復鎖定。extern STATUS taskLock (void); extern STATUS taskUnlock (void); 基于嵌入式操作系統VxWorks的多任務并發程序設計(3)任務調度03月 7th, 2006 by 宋寶華 基于嵌入式操作系統VxWorks的多任務并發程序設計(3) 任務調度 作者:宋寶華 e-mail:21 出處:軟件報 VxWorks支持兩種方式的任務調度: (1)基于優先級的搶占調度(Preemptive Priority Based Scheduling) 搶占是指正在執行的任務可以被打斷,讓另一個任務運行,它可以提高應用程序對異步事件的響應能力。基于優先級的搶占調度是最常見的搶占機制,用戶任務被分配一個優先級,操作系統內核總是調度優先級最高的就緒任務運行于CPU。當系統正在執行低優先級任務時,一旦有更高優先級的任務準備就緒,OS內核會立即進行任務的上下文切換。 VxWorks的Wind內核劃分優先級為256 級(0255)。優先級0為最高優先級,優先級255為最低。當任務被創建時,系統根據用戶指定的值分配任務優先級。VxWorks的任務優先級也可以是動態的,它們能在系統運行時被用戶使用系統調用taskPrioritySet()來加以改變。 (2)時間片輪轉調度(Round-Robin Scheduling) 時間片輪轉調度指的是操作系統分配一定的時間間隔(時間片),使每個任務輪流運行于CPU。在VxWorks中,對于優先級相同的多個任務,如果狀態為ready,則其可以通過時間片輪轉方式公平享有CPU資源。 輪轉調度法給處于就緒態的每個同優先級的任務分配一個相同的執行時間片,時間片的大小可由系統調用KernelTimeSlice指定。為對輪轉調度進行支持,系統給每個任務提供一個運行時間計數器,任務運行時每一時間滴答計數器加1。一個任務用完時間片之后,OS停止執行該任務,將它放入就緒隊列尾部,并將其運行時間計數器置零。接著,OS執行就緒隊列中的下一個任務。 6. 任務調度 6.1時間片輪轉調度 我們來看一個具體的例子,在這個程序中,用戶啟動了三個優先級相同的任務,并通過對kernelTimeSlice(TIMESLICE)的調用啟動了時間片輪轉調度。 例1:時間片輪轉調度 /* includes */ #include vxWorks.h #include taskLib.h #include kernelLib.h #include sysLib.h /* function prototypes */ void taskOne(void); void taskTwo(void); void taskThree(void); /* globals */ #define ITER1 100 #define ITER2 10 #define PRIORITY 101 #define TIMESLICE sysClkRateGet() #define LONG_TIME 0xFFFFFFL void sched(void) /* function to create the three tasks */ int taskIdOne, taskIdTwo, taskIdThree; if (kernelTimeSlice(TIMESLICE) = OK) /* turn round-robin on */ printf(nnnntttTIMESLICE = %d secondsnnn, TIMESLICE / 60); /* spawn the three tasks */ if (taskIdOne = taskSpawn(task1, PRIORITY, 0100, 20000, (FUNCPTR)taskOne, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = ERROR) printf(taskSpawn taskOne failedn); if (taskIdTwo = taskSpawn(task2, PRIORITY, 0100, 20000, (FUNCPTR)taskTwo, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = ERROR) printf(taskSpawn taskTwo failedn); if (taskIdThree = taskSpawn(task3, PRIORITY, 0100, 20000, (FUNCPTR) taskThree, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = ERROR) printf(taskSpawn taskThree failedn); void taskOne(void) unsigned int i, j; for (i = 0; i ITER1; i+) for (j = 0; j ITER2; j+) printf(task1n); /* log messages */ for (j = 0; j LONG_TIME; j+) ; /* allow time for context switch */ void taskTwo(void) unsigned int i, j; for (i = 0; i ITER1; i+) for (j = 0; j ITER2; j+) printf(task2n); /* log messages */ for (j = 0; j LONG_TIME; j+) ; /* allow time for context switch */ void taskThree(void) unsigned int i, j; for (i = 0; i ITER1; i+) for (j = 0; j ITER2; j+) printf(task3n); /* log messages */ for (j = 0; j LONG_TIME; j+) ; /* allow time for context switch */ 程序運行輸出:一會兒輸出一些“task1”,一會兒輸出一些“task2”,再一會兒輸出一些“task3”。每次輸出了某任務的一部分內容后,就開始輸出另一任務的內容,這說明了task1、task2、task3再進行時間片輪轉切換。 對于任務的上下文切換,我們可以使用WindView進行觀察。WindView是一個圖形化的動態診斷和分析工具,它可以向開發者提供目標機硬件上所運行應用程序的許多詳細情況。下圖顯示了使用WindView獲取的上述程序的運行結果: kernelTimeSlice()的函數原型為: STATUS kernelTimeSlice (int ticks /* time-slice in ticks or 0 to disable round-robin */ ); 程序中的kernelTimeSlice(TIMESLICE)展開后為kernelTimeSlice(sysClkRateGet(),即每秒鐘進行一次輪轉。如果kernelTimeSlice函數中的輸入參數為0,時間片輪轉調度就不會發生,程序的輸出將是:先輸出ITER1* ITER2個“task1”,再輸出ITER1* ITER2個“task2”,最后輸出ITER1* ITER2個“task3”。 6.2優先級搶占調度 如果將例1中三個任務的優先級設置的不相同,即將程序改為: 例2:優先級搶占調度 /* includes */ #include vxWorks.h #include taskLib.h #include kernelLib.h #include sysLib.h /* function prototypes */ void taskOne(void); void taskTwo(void); void taskThree(void); /* globals */ #define ITER1 100 #define ITER2 10 #define HIGH 100 /* high priority */ #define MID 101 /* medium priority */ #define LOW 102 /* low priority */ #define LONG_TIME 0xFFFFFFL void sched(void) /* function to create the two tasks */ int taskIdOne, taskIdTwo, taskIdThree; printf(n
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 學校生物室管理制度
- 學生會設備管理制度
- 學生項目部管理制度
- 安保部綜合管理制度
- 安全管理與管理制度
- 定向井公司管理制度
- 實訓室水電管理制度
- 客戶保證金管理制度
- 客運包車牌管理制度
- 家裝業務員管理制度
- 《分子動力學模擬》課件
- 新生兒重癥監護病房捐贈人乳應用與管理專家共識(2025)解讀
- 皮膚科進修心得分享
- 2025年上半年廣東省廣州市白云區委宣傳部政府雇員招聘5人重點基礎提升(共500題)附帶答案詳解
- 項目經理講安全課件
- 《休閑農業》課件 項目二 休閑農業分類及模式分析
- 2025年安徽省省情試題及答案
- 2025年消控室考核試題及答案
- 江西省吉安市遂川縣2024-2025學年數學三下期末達標檢測試題含解析
- 衛健系統2025年上半年安全生產工作總結
- 第一章體育與健康基礎知識 第一節 科學發展體能 課件 2024-2025學年人教版初中體育與健康八年級全一冊
評論
0/150
提交評論