VxWorks基本OS介绍
每一個被切換的程序實體就是“任務”。每一個任務都有其自己的上下文——所謂上下文就是指任務在每一次被核心調度時所需要的CPU環境、系統資源。在上下文的切換過程中,每一個任務的上下文被存在該任務的任務控制塊中(TCB)。
◆?執行的線程,也就是任務程序計數器;
◆?CPU寄存器的內容和浮點寄存器中的內容;
◆?動態變量和程序調用所使用的堆棧;
◆?標準輸入輸出的I/O分配和錯誤;
◆?延時計時器;
◆?時間片計時器;
◆?核心控制結構;
◆?信號處理句柄;
◆?調試和性能監視值。
wind核心中使用了基于優先級搶占式的任務調度策略,但是用戶也可以選擇優先級輪轉調度策略。
1.優先級搶占策略
通過使用優先級搶占策略,每一個任務都會擁有一個優先級,這樣內核就會確信將CPU資源分給了優先級最高的就緒任務。這種方法之所以叫做搶占式的,是指任何運行的任務會被一個變成就緒狀態而且優先級更高的任務打斷,這時系統會保存當前任務的上下文并立即切換到高優先級的任務上下文,并且開始執行這個任務。在圖14.2所示的任務優先級搶占圖中給出了優先級搶占的例子,例子中任務t1被優先級較高的任務t2搶占,而更高優先級的任務t3則搶占了t2的執行,當t3執行完后,t2開始繼續執行,接下來t1在t2完成之后從被打斷處繼續執行。
VxWorks的wind內核支持256級優先級,由高到低分別是0到255。任務創建的同時也就同時被賦予了相應的優先級,但是在任務執行的過程中,同樣可以通過系統函數taskPrioritySet()設置某一個任務的優先級。
在VxWorks系統中,所有應用程序任務的優先級應該在100~250之間;至于驅動程序創建的任務的優先級可以位于51~99之間,系統網絡任務tNetTask的優先級默認值為50。
2.時間片輪轉的調度策略
如果沒有時間片輪轉任務調度策略,那么當同優先級的一個任務獲得了CPU資源之后,它就會一直占用CPU資源直到完成執行,相同優先級的任務就會因為得不到CPU資源而不得不阻塞。解決這個問題就需要循環調度策略。
對于具有相同優先級的任務,時間片輪轉調度策略會為每一個任務分配相同的CPU時間片。優先級相同的一組任務都會在相同的時間間隔內被執行,每一個時間片結束,內核就會通過調度算法執行就緒隊列中的另一個任務,任何一個任務都不會比其他的任務獲得更多的時間片。
當一個高優先級的任務出現時,正在執行的優先級的任務會被打斷,它的運行時間計數器會被保存在任務控制塊中,一旦高優先級的任務完成執行,被打斷的任務將恢復執行,而運行時間計數器會從被打斷的位置繼續計數,直到分配給這個任務的時間片被消耗掉,或者該任務執行完。圖14.3解釋了剛才所描述的情況:t1,t2,t3是具有相同優先級的任務,而t2在執行的過程中被優先級更高的任務t4搶占,當t4執行完之后,t2繼續使用完了系統分配的時間片。
3.搶占鎖
VxWorks同樣允許低優先級的任務禁止正在使用的CPU資源被高優先級的任務搶占。注意:taskLock()/taskUnlock()的操作比semGive()/semTake()操作速度要快。主要用于對臨界資源的保護,避免系統發生異常。
通常我們都會使用taskSpawn(),這個函數可以方便的創建并且激活任務,taskId = taskSpawn("tRead", 150, 0, 2048, (FUNCPTR)TaskRead, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9);
2.任務的名稱和ID
當用戶生成一個任務的時候,可以將任意長度的字符串作為任務的名稱。而對于每一個新生成的任務,VxWorks都會返回一個ID號來標志這個任務,這個ID號是一個四字節的指針,指向了任務的結構。但是VxWorks提供了一個方便的表示辦法,在一個任務中使用0代替任務自身的ID。
為了避免任務之間名稱的重復,VxWorks有一個名稱格式的規定,所有目標機創建的任務名稱都以字母t開頭,而主機生成的任務都以字母u開頭。
雖然任務名會在調試和任務控制中帶來極大的方便,但是生成任務的時候也可以不指定任務名,這個時候VxWorks系統會為用戶生成的任務自動命名。這個功能使循環生成多任務變得更為方便,用戶可以通過循環體生成相同處理的很多任務。
taskIdSelf()獲取當前任務的ID
一個任務可以通過使用exit()將自己結束。如果希望結束其他任務,可以通過調用taskDelete()實現。當一個任務結束的時候,任何其他的任務都不會得到通知。這時,就應該使用其它的方法來通知相關任務。同時,任務執行所申請的內存也不會在其終止時自動釋放。
為了避免任務在未釋放資源的時候就被意外的結束,VxWorks提供了一對函數來進行保護,這就是taskSafe()和taskUnsafe()。為了避免任務在未釋放資源的時候就被意外的結束,VxWorks提供了一對函數來進行保護,這就是taskSafe()和taskUnsafe()。
| 函數 | 描述 |
| taskSuspend() | 掛起任務 |
| taskResume() | 恢復任務 |
| taskRestart() | 重啟任務 |
| taskDelay() | 任務延時(參數為時間片) |
| nanosleep() | 任務延時(參數為納秒) |
?
| 函數 | 描述 |
| taskCreateHookAdd() | 增加任務創建時調用的函數 |
| taskCreateHookDelete() | 刪除任務調用時要執行的函數 |
| taskSwitchHookAdd() | 增加任務切換時調用的函數 |
| taskSwitchHookDelete() | 刪除任務切換時要執行的函數 |
| taskDeleteHookAdd() | 增加任務刪除時調用的函數 |
| taskDeleteHookDelete() | 刪除任務刪除時要執行的函數 |
任何代碼或者數據中的錯誤都有可能導致硬件的異常狀態,那些非法的指令、錯誤的總線或者地址訪問,被零除等等的錯誤都會產生異常。所有的異常都會被VxWorks的異常處理包所捕獲。默認情況下,異常處理會將引起異常的任務掛起,并且保存異常出現時任務的狀態,而VxWorks核心和其他的任務都會繼續運行。與此同時,關于異常的描述將會傳遞給Tornado的開發工具,以便用戶的調試。
有些被多任務所調用的函數會訪問全局或者靜態變量。這種情況就是,幾個任務都有自身的緩沖區,而他們同時會將這些緩沖區中的值賦給一個相同的全局變量。
為了解決這種情況,VxWorks提供了任務變量的工具,允許將四個字節的變量加入到任務上下文中,于是這些變量就會跟隨著任務的切換而切換。這樣會給任務切換時間增加幾個微秒的時間。
在VxWorks中可以使用同一個函數實現體生成多個任務。每個新生成的任務都會帶有自己的任務堆棧和上下文。同時每次生成新的任務,都可以為函數傳入不同的參數。
1.根任務:tUsrRoot
在VxWorks內核引導后第一個創建的任務就是根任務tUsrRoot。這個任務的入口點在安裝目錄下的target/config/all/usrConfig.c中,這個任務在創建后會初始化大多數的VxWorks工具。他會創建記錄任務、異常處理任務、網絡任務和一個叫做tRlogind的守護任務。通常的情況下根任務在做完這些初始化之后都會結束并且被系統刪除。在根任務中用戶可以任意添加必要的初始化代碼。
2.日志任務:tLogTask
日志任務(也稱記錄任務)為VxWorks系統中的其他模塊提供了記錄系統信息的功能,通過這個任務可以記錄系統信息而不需要執行I/O操作。下面的表14-13中列出了用戶可以使用的系統記錄函數。
| logMsg() | 輸出帶有格式的登記信息 |
3.異常處理任務:tExcTask
異常處理任務執行VxWorks異常處理,這些函數都是在中斷中不能執行但又非常重要的。所以這個任務必須在系統中具有最高的優先級,不能被掛起、不能被刪除、不能改變優先級。
4.網絡任務:tNetTask
網絡守護任務處理VxWorks系統中任務級的網絡的請求。
5.目標機代理任務:tWdbTask
如果目標機代理設置為運行在任務方式下,系統會生成tWdbTask任務。這個任務負責主機與目標機的通信,所有調試信息都會通過目標機服務器傳給這個任務。
6.可選的任務
(1)目標機shell任務:tShell。
(2)遠程用戶登陸響應任務:tRlogind。
(3)Telnet用戶登陸響應任務:tTelnetd。
(4)RPC服務任務:tPortmapd。
?
對于任務來說,任務間的通信交流是必不可少的。任務間的通信允許相互獨立的任務完成協作的工作。為了方便的完成任務的通信,VxWorks為用戶提供了相當多而且靈活的通信機制,通過使用這些手段任務可以輕松的完成復雜的通信任務。基本的VxWorks提供了五種通信機制:
◆?簡單的數據共享,共享內存;
◆?簡單的互斥和同步機制,信號量;
◆?任務間傳輸消息所使用的消息隊列和管道;
◆?為網絡間任務的通信而提供的網絡插口(Socket)和遠程進程調用;
◆?用于處理異常的標志。
在VxWorks的可選件VxMP中,系統還提供了多CPU之間共享內存、信號量、消息隊列、數據庫等機制,使多CPU之間協作變得簡單方便。
這是最簡單的共享內存方式,通過訪問相同的數據結構體,任務之間可以輕易的共享數據以及控制信息。由于VxWorks的所有任務都使用單一地址空間,共享數據并不會增加系統的負擔,從而使這種方式成為VxWorks中最為簡單的數據共享方式。不同的任務都可以直接訪問全局變量、隊列、環形隊列、鏈表、指針等,如圖14.7所示。
| 訪問共享數據 |
| 訪問共享數據 |
| 訪問共享數據 |
| 共享數據 |
| ? |
| ? |
| 任務1 |
| 任務2 |
| 任務3 |
| 任務 |
| 內存 |
?
?
?
?
?
?
1.中斷鎖以及中斷延遲
在所有的互斥的方法中,中斷鎖的作用域最小,功能卻最強。中斷鎖可以使中斷處理程序不被打斷,使用了中斷鎖之后任何中斷處理或者任務都不會打斷中斷鎖控制中的代碼。int lock=intLock();????./*禁止中斷的程序部分*/????intUnlock(lock);
2.優先級鎖及其延遲
一個任務使用了優先級鎖之后,除了中斷之外沒有任何任務可以打斷這個任務的執行。taskLock();????./*禁止搶占的程序部分*/????taskUnlock();
1.二進制信號量
2.互斥信號量
3.計數信號量
| semFlush() | 使所有等待指定信號量的任務獲得信號量 |
當一個信號量創建的時候,就已經為其指定了隊列的模式。用戶可以指定優先級模式或者先進先出模式。使用基于優先級的信號量,會使高優先級的任務優先獲得信號量;使用先進先出模式的信號量,系統將對所有任務一視同仁。
5.互斥
6.同步
7.優先級反轉
在互斥信號量中,有選項SEM_INVERSION_SAFE,通過這個選項可以開啟優先級繼承。
msgQCreat()函數用于創建并初始化一個消息隊列,通過這個函數的參數,可以指定消息隊列所容納的消息數目和長度以及消息隊列的類型。VxWorks為消息隊列提供了兩種優先級類別的消息,普通消息(MSG_PRI_NORMAL)和緊急消息(MSG_PRI_URGENT)。
從函數的定義上來看,msgQSend()和msgQReceive()都可以設置超時參數。對于發送消息,超時的含義是,在規定的時間里消息隊列沒有可用的空間接納新的消息。而對于接收消息,超時的含義是,在規定的時間里消息隊列沒有新的消息到達。雖然機理不同,兩者同樣會引發超時錯誤。
管道是消息隊列的替代品,與消息隊列不同的是,管道使用了VxWorks系統的I/O系統。作為一個I/O設備,管道提供了一個消息隊列所不能提供的支持,即是對select的支持(select將會在后面介紹到)。通過使用select函數,任務可以同時等待不同的I/O設備的數據。
1.套接字
2.遠程進程調用
信號可以異步的改變任務的控制流程。在實際操作中,中斷服務程序或者任務向指定的任務發送信號,接收到信號的任務立即掛起當前執行的線程,在下一次調度執行的時候執行指定的信號處理程序。
VxWorks為定時功能提供了看門狗定時器機制。這個機制允許在一定時間延遲之后執行一段特定的函數代碼。在系統內部,看門狗定時器是作為系統時鐘的一部分來維護的。也就是說相當于系統時鐘在給定的時間后會給出中斷,而看門狗定時器指定的程序則是掛在這個中斷上的中斷服務程序,由于掛在系統時鐘上可以保證了精確的定時。
void wdogRoutine()
{
???????semGive(semId_Task2);//釋放執行任務所需的信號量
???????semGive(semId_Task1);
???????wdStart(wdogID, sysClkRateGet(),(FUNCPTR)wdogRoutine,0);
}
VxWorks提供了intConnect()函數實現這個功能,通過這個函數可以將用戶函數與中斷相關聯。事實中的中斷處理程序并不是簡簡單單的C函數,在函數intConnect()中不僅保存當前寄存器狀態以及其中正在執行的代碼,而且為被調用函數的參數建立了一個堆棧入口,最后調用連接在中斷上的函數。中斷處理完成后,從被調用的函數返回時,intConnect()函數恢復寄存器和堆棧,并退出中斷。
所有中斷程序都使用相同的中斷堆棧。這個堆棧是由系統啟動時根據指定的配置參數來定位和初始化的。為了能在最糟糕的情況下處理中斷嵌套。必須分配足夠大的中斷堆棧空間。
在開發過程中,使用checkStack()函數可以觀察如何關閉中斷堆棧以及中斷服務程序如何逐漸地占用堆棧空間。
雖然中斷服務程序可以連接到普通的C函數,在編寫這個被調用的C函數時,還是有很多限制。在這個被調用的函數中,不能執行過多的I/O操作、不可以獲取信號量、不可以分配內存。像printf()、malloc()、semTake()函數都是不可以使用的,但是可以使用semGive()、logMsg()、msgQSend()以及bcopy()函數。
同時為了給中斷服務程序提供輸出功能,VxWorks中提供了logLib,這個庫中的函數允許系統任務打印文本信息,它是中斷服務程序中最常用的輸出手段。在上一節例子中的logMsg()函數就是這個庫中的。
對于中斷服務程序來說,掛起是不可能的,因為中斷服務程序是沒有可掛起的上下文,系統也就沒有安全可靠的資源來處理異常。基于這個理由,VxWorks使用了另一種方法替代任務的掛起,那就是在系統低端內存的特定區域存儲引發錯誤的異常的描述,同時執行系統重啟。
總結
以上是生活随笔為你收集整理的VxWorks基本OS介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行白金卡一年有几次机场贵宾室服务
- 下一篇: 招行合作机场贵宾室有哪些?怎么查询?