上下文儲存 中斷 實時作業系統中斷和時間管理

2021-10-15 00:21:21 字數 3098 閱讀 7053

目錄

前言一、中斷

1:中斷的概念

2:中斷執行的過程

3:相關操作函式

二、時間管理

1:時鐘節拍

3:何時啟動時鐘節拍器

這篇文章我們主要講解一下ucos中的中斷和時間管理,中斷是計算機系統處理非同步事件的重要機制,當非同步事件發生時,硬體首先會向cpu發起中斷請求,cpu響應這個請求之後會立即執行中斷服務程式來處理該事件。

為了處理任務延時,任務排程等與時間相關的事件,任何乙個計算機系統都應該有個系統時鐘,與其他系統一樣,ucos的系統時鐘也是通過硬體定時器產生的定時中斷來實現的。

中斷:由於某種事件的發生而導致程式流程的改變。產生中斷的事件稱為中斷源。

cpu響應中斷的條件:至少有乙個中斷源向cpu發出中斷信 號;系統允許中斷,且對此中斷訊號未予遮蔽

任務在執行過程中,應內部或外部事件的請求中止當前任務而去處理非同步事件所要求的任務的過程叫做中斷。應中斷請求而執行的程式叫做中斷服務程式,中斷服務程式的入口叫做中斷向量

中斷一旦被識別,cpu會儲存部分(或全部)執行上下文(context,即暫存器的值),然後跳轉到專門的子程式去處理此次事件,稱為中斷服務子程式(isr)。

大概的執行過程如下所示

(1)儲存全部cpu暫存器的值;

(2)呼叫osintenter(),或直接把全域性變數 osintnesting(中斷巢狀層次)加1;

(3)執行使用者**做中斷服務;

(4)呼叫osintexit();

(5)恢復所有cpu暫存器;

(6)執行中斷返回指令。

在中斷服務程式中,有兩個重要的函式,分別是osintenter 和 osintexit。

其中osintenter 通常發生才中斷服務程式保護了斷點資料之後執行中斷服務程式之前,稱之為進入中斷服務函式,其作用就是把osintnesting變數加1,從而用它來記錄中斷巢狀的層數。原始碼如下

void osintenter (void)  } }
另乙個函式osintexit叫做退出中斷服務函式,這個函式呼叫發生在處理完中斷流程,退出中斷的時候,起作用就是在退出中斷處理的時候判斷要執行哪乙個任務(執行最高優先順序),該函式的作用可以用下面的圖來表示。

void osintexit (void)  }  os_exit_critical(); //開中斷返回}
從上面的**中我們可以看到在執行任務切換的時候我們是呼叫osintctxsw函式的,那麼為什麼不呼叫os_task_sw呢,原因有以下兩點

一半的任務切換工作,即cpu暫存器入棧,已經在前面做完了;

需要保證所有被掛起任務的棧結構是一樣的

下面的圖中描述了osintctxsw的堆疊情況

任何系統都需要乙個週期性的訊號源,以供系統處理延時超時等與時間相關的事件,這個週期性的訊號源就叫做時鐘。

多數系統中採用硬體定時器產生乙個週期性為ms級的週期性中斷來實現系統時鐘,這個系統時鐘的最小時間單位就是兩次中斷到來之間的相間隔的時間,這個最小的時間間隔就是時鐘節拍。

硬體定時器以時鐘節拍為週期定時產生中斷,該中斷的服務函式叫做ostickisr,系統通過呼叫該函式來實現在每個時鐘節拍中斷中需要執行的操作。

void ostickisr(void)
上面的**中我們可以看到在 ostickisr函式中呼叫了osintexit,這個函式的主要作用就是給每個使用者任務控制塊os_tcb 中的時間延時項ostcbdly 減 1(如果該項不為零的話)。ostimtick()從 ostcblist 開始,沿著 os_tcb 鍊錶 做,一直做到空閒任務。當某任務的任務控制塊中的時間延時項 ostcbdly 減到 了零,這個任務就進入了就緒態。而確切被任務掛起的函式 ostasksuspend()掛 起的任務則不會進入就緒態。ostimtick()的執行時間直接與應用程式中建立了 多少個任務成正比。

ostimedly():任務延時函式,申請該服 務的任務可以延時一段時間; 

呼叫ostimedly後,任務進入等待狀態;

使用方法void ostimedly (int16u ticks);  ticks表示需要延時的時間長度,用時鐘節拍的個數來表示。

void ostimedly (int16u ticks)    ostcbcur->ostcbdly = ticks;    os_exit_critical();    ossched();  }}
ostimedlyhmsm() :ostimedly()的另乙個 版本,即按時分秒延時函式;

使用方法 int8u ostimedlyhmsm(

int8u hours, // 小時

int8u minutes, // 分鐘

int8u seconds, // 秒

int16u milli // 毫秒

ostimedlyresume() :讓處在延時期的任 務提前結束延時,進入就緒狀態;

使用方法 int8u ostimedlyresume (int8u prio); prio表示需要提前結束延時的任務的優先順序 任務id

ostimeget() :獲得該計數器的當前值; int32u ostimeget (void);

ostimeset() :設定該計數器的值。 void ostimeset (int32u ticks);

每隔乙個時鐘節拍,發生乙個時鐘中斷,將一 個32位的計數器ostime加1;該計數器在使用者呼叫osstart()初始化多工和 4,294,967,295個節拍執行完一遍的時候從0開 始計數。若時鐘節拍的頻率等於100hz,該計數 器每隔497天就重新開始計數;

使用者必須在多工系統啟動以後再開啟時鐘節拍 器,也就是在呼叫osstart()之後;在呼叫osstart()之後做的第一件事是初始化定時器中斷

void main(void)

上下文儲存 中斷 深入理解CPU上下文切換

我們都知道cpu上下文切換,會增加系統負載。那什麼是cpu上下文,為什麼要切換?我們都知道,linux 是乙個多工作業系統,它支援遠大於 cpu 數量的任務同時執行。當然,這些任務實際上並不是真的在同時執行,而是因為系統在很短的時間內,將 cpu 輪流分配給它們,造成多工同時執行的錯覺。而在每個任務...

中斷上下文

一 中斷下半部 工作佇列 1 中斷 先看一下宋寶華先生的 linux裝置驅動開發詳解 裡面對中斷的描述吧。這本書個人感覺 寫的比較好,從開始學驅動到現在,還能從中得到不少知識。裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望...

linux中斷 程序上下文和中斷上下文

中斷發生以後,cpu跳到核心設定好的中斷處理 中去,由這部分核心 來處理中斷。這個處理過程中的上下文就是中斷上下文。為什麼可能導致睡眠的函式都不能在中斷上下文中使用呢?首先睡眠的含義是將程序置於 睡眠 狀態,在這個狀態的程序不能被排程執行。然後,在一定的時機,這個程序可能會被重新置為 執行 狀態,從...