嵌入式作業系統分析(三) 任務排程與上下文切換

2021-04-15 04:50:57 字數 3510 閱讀 9266

gogofly  

[email protected]

任務排程與上下文切換

1. 任務排程概述

任務排程(schedulers)是核心的主要職責,實際上它就是乙個法官,決定當前由哪個任務占用cpu,多數實時核心都是基於優先順序排程演算法的,每個任務根據其重要程度的不同被賦予一定的優先順序。基於此演算法,cpu總是讓處於就緒而且優先順序最高的任務優先執行,然而何時高優先順序任務能夠得到cpu使用權,由核心的型別而定。基於優先順序的核心有兩種:

不可搶占型和搶占型。

1) 不可搶占型核心:

不可搶占型核心要求每個任務主動放棄cpu的使用權,其間不能被高優先順序任務搶占。它的有點是:

a. 由於不需要在中斷返回是進行任務切換,所以中斷響應快。

b. 在任務級中可以呼叫不可重入函式而不必擔心造成資料破壞。

c. 幾乎不需要訊號量來保護共享資料,也就是說,在任務執行過程中,資料是獨享的。

但它的最大缺點是:響應時間不確定,當有更高優先順序任務就緒後,不知道什麼時候才能得到執行,這在實時系統中是致命的缺陷。所以不可搶占型核心最要用於前後臺系統中。

2) 搶占型核心:

在嵌入式系統中,程序(任務)都是搶占型的,通過給每個程序(任務)設定乙個優先順序,當系統中有優先順序比當前執行的程序(任務)的優先順序更高的程序(任務)時,當前的程序(任務)執行被中斷,並呼叫排程程式選擇優先順序高的程序(任務)執行。利用搶占式核心,可以保證高優先順序的程序(任務)被優先執行,從而保證系統的實時響應。

在多工系統中,程序(任務)的排程主要包括以下一些方面:

2. 任務排程:

在多工系統中,都會提供乙個系統函式來進行程序(任務)間切換,綜合來說,他們有兩種程序(任務)切換方式:

1) 由程序(任務)本身直接呼叫任務切換函式進行程序(任務)切換:

在當前程序(任務)因為不能獲得必須的資源而立即被堵塞時,就由程序(任務)本生直接呼叫程序(任務)切換函式進行程序(任務)間排程。

在linux中可以直接呼叫schedule()函式來實現。

在ucos中,通過呼叫ossched()來完成。

2) 延遲呼叫任務切換函式進行程序(任務)切換:

此方式是把當前程序(任務)設定一排程標誌而以延遲方式呼叫任務切換函式進行程序(任務)切換。

在linux系統中,總是在恢復使用者態程序執行之前,檢查這一排程標誌,在這裡標誌是:tif_need_resched,如果有這一標誌,就呼叫排程函式進行程序切換。此種情況主要包括以下幾種:

a. 當前程序用完了它的cpu時間片,有scheduler_tick()函式完成 schedule()的延遲呼叫。

b.當乙個被喚醒程序的優先順序比當前程序優先順序高時,由try_to_wake_up()函式完成schedule()的延遲呼叫。

c.當發出系統呼叫sched_setscheduler()時。

在這些情況中,主要由於系統呼叫或中斷而進入核心態,或者當前程序本來在核心態時,返回使用者態時發生的。

在ucos中,所有的任務有不同的優先順序,不會出現同一優先順序上有多個任務的情況,而且也沒有系統呼叫的概念,所以任務排程的延遲呼叫只能出現在中斷處理完成返回時,在osintext()函式中,檢查是否有高優先順序的任務就緒,如果有高優先順序的任務就緒,進行任務切換。

3. 排程演算法:

在linux系統中,選用了比較複雜的排程演算法,按照排程型別可以分為以下幾種:

sched_fifo:此演算法主要應用於實時程序,當排程程式把cpu分配給當前程序後,如果沒有更高優先順序的程序可以執行時,此程序會一直占用cpu直到此程序退出或者自願放棄cpu,即使此時有其他相同優先順序的程序存在。

sched_rr:時間片輪詢的實時程序,對於不同優先順序的程序會排程優先順序高的程序執行,對具有相同優先順序的程序,會根據時間片來排程,當當前程序的時間片用完後,會排程相同優先順序的其他程序執行,從而保證相同優先順序程序的cpu排程公平性。

sched_normal:此演算法主要用於普通程序,利用分時進行排程。

在ucos系統中,所有的任務都是實時任務,所以沒有普通任務排程機制,而且為了簡化排程演算法,不同的任務有不同的優先順序,不可能出現同一優先順序有多個任務的情況,實際上它的排程演算法就只有linux中sched_fifo這一種,即優先順序高的任務搶占優先順序低任務。

4. 上下文切換:

上下文切換是多任務排程的核心內容,也是我們感覺在乙個cpu上並行執行多個程式的基礎。

任務上下文(task context): 任務上下文是指任務執行的環境。例如,針對x86的cpu,任務上下文可包括程式計數器、堆疊指標、通用暫存器的內容。

上下文切換(context switching):在多工系統中,上下文切換是指cpu的控制權由執行任務轉移到另外乙個就緒任務時所發生的事件,當前執行任務轉為就緒(或者掛起、刪除)狀態,另乙個被選定的就緒任務成為當前任務。上下文切換包括儲存當前任務的執行環境,恢復將要執行任務的執行環境。上下文的內容依賴於具體的cpu。

對於不同的硬體體系結構,上下文切換的內容不一樣,本質上有下面兩步:

a. 如果有虛擬記憶體,則切換頁全域性目錄以安裝乙個新的位址空間。

b. 切換核心堆疊和硬體上下文,因為硬體上下文提供了核心執行新程序所需要的所有資訊,包括cpu資訊。

在搶占式核心中,利用中斷來實現上下文切換是乙個非常理想的機制。中斷發生時,中斷會強制cpu把控制權交給作業系統,也就相當於一次上下文切換。這樣不僅可以減少程式出錯的後果,而且提高切換的效率。ucos就是利用中斷機制進行上下文切換的典型例子。

在ucos中,如果排程程式決定任務需要切換,就會呼叫上下文切換os_task_sw()進行實際的上下文切換。os_task_sw()是巨集呼叫,含有微處理器的軟中斷指令,利用此中斷來實現任務之間的上下文切換。所以os_task_sw()是乙個體繫結構相關的巨集,對於不同的硬體體系機構,有不同的實現方式,這也是ucos在不同硬體體系結構中移植的乙個要點。

由於ucos不支援虛擬記憶體,所以不需要進行頁目錄切換,其他許多實時多工嵌入式系統的乙個特徵,也是區別linux系統的乙個重要方面。

在2.6 linux kernel中,引入了乙個全新的排程機制o(1)排程器,它能在固定的時間內完成程序切換。如果排程程式決定任務需要切換,就會呼叫上下文切換函式context_switch()函式進行上下文切換,此函式會呼叫switch_mm()切換頁全域性目錄以安裝乙個新的位址空間,然後呼叫switch_to()切換具體硬體上下文。

總結:

這裡主要介紹了多工系統中的任務排程及其演算法,比較了linux系統和ucos系統中的上下文切換,具體實現可以參考linux核心源**和ucos源**。

參考:

1. linux kernel primer

2. understanding the linux kernel

3. 嵌入式實時作業系統uc/os-ii

4. 嵌入式計算機系統設計原理

嵌入式作業系統分類

嵌入式作業系統是一種支援嵌入式系統應用的作業系統軟體,它是嵌入式系統的重要組成部分。嵌入時作業系統具有通用作業系統的基本特點,能夠有效管理複雜的系統資源,並且把硬體虛擬化。從應用角度可分為通用型嵌入式作業系統和專用型嵌入式作業系統 常見的通用型嵌入式作業系統有linux vxworks window...

嵌入式作業系統分類

按對外部事件的響應能力來分類,嵌入式作業系統有分時作業系統和實時作業系統。如果作業系統能 使計算機系統及時的響應外部事件請求,並能控制所有實時裝置和實時任務協調執行,且能在乙個規定的 時間內完成對事件的處理,那麼這種系統就稱為實時作業系統 rtos 按時間的正確程度來分,實時作業系統又分為硬體的實時...

(軟考 系統分析師 嵌入式系統

外部裝置是嵌入式系統同外界互動的通道 儲存器用於存放系統的 資料和執行結果 分類 時間輪轉排程 為每個任務提供確定份額的cpu執行時間,純粹的時間輪轉無法滿足實時系統要求,取而代之的是,基於優先順序搶占式擴充時間輪轉排程對於優先順序相同的任務分配相同份額的cpu使用時間 核心物件 特殊的核心構件,幫...