目錄前言
關於中斷歷史與發展
linux中斷設計
linux中斷下半部實現
軟中斷:
tasklet:
工作佇列:
關於可重入和不可重入函式
在我們學習中斷的時候,先要了解幾個概念。何為中斷?為什麼要使用中斷?中斷如何運作?弄明白這些再去使用中斷會顯得得心應手。
何為中斷?cpu在執行的過程中,由於外部因素,終止執行當前的任務去執行另乙個任務。打個比方,你在做乙個任務,突然上司來乙個優先順序更高的任務讓你去完成,這時候你就要放下當前的任務而去執行優先順序比較高的緊急任務。
為什麼要使用中斷?這個問題我們想想如果沒有中斷會怎樣。當cpu按照指定的流程處理某乙個任務,如果沒有中斷,我們只好等它把當前的任務完成之後,才能給它新的任務。這會導致我們想要及時處理的任務cpu半天沒有響應,這種體驗會讓人痛苦得要死。
中斷如何運作?當cpu在執行的過程中,如果有外部中斷觸發時候,如定時器、序列匯流排中斷等,cpu停止執行當前的任務轉而去執行中斷內容。對於中斷函式的處理,原則是盡快處理完並退出中斷,這樣才能保證之前的任務能正常執行,這樣才保證它能繼續響應其他中斷,保證實時性和併發性。
簡單通俗理解實時性和併發性,實時性就是說當前任務被中斷了一下,但是並沒有太大的延時,cpu很快從中斷**來,整體來看對當前任務沒有太多延時;所謂併發性,就是說cpu可以隨時響應新的中斷任務請求,感覺是處理兩件事兩不誤。目前使用到跟硬體關聯的中斷有兩大類:一種是微控制器這種單程序作業系統,另一種linux/unix這樣的多程序作業系統。
不管是mcu還是linux都會有中斷「上下部分」的思維,舉乙個簡單的例子,串列埠uart進行資料通訊,對於rx接收資料,在採用中斷方式接收時,先將資料存到乙個快取buffer中,中斷函式只負責將資料存入快取,主函式負責處理快取中的資料。我們通常把存入快取這部分稱為「中斷上部分」,這裡包括暫存器訪問、狀態改變等操作;同理把從快取中獲取資料並處理的過程稱為「中斷下部分」。
微控制器執行實時作業系統rtos,是以任務為排程的,以rt-thread為例,實現乙個串列埠中斷接收函式。中斷上部分負責把資料放入快取,中斷下部分可以建立乙個處理執行緒,當獲得上半部分訊號量時則排程執行緒處理函式,否則掛起該執行緒,節省cpu資源。
不同於微控制器作業系統,linux是多程序、多執行緒的,能更好的處理併發。當外設有中斷時,核心會中斷響應,並遮蔽其外設中斷(為什麼這麼操作?如果不這樣會多次進入中斷響應),當中斷函式比較耗時時候,會降低系統的實時性和併發性。為此,linux在考慮實時性和併發性的時候,將中斷處理程式分為上半部(top half)和下半部(bottom half)。原則上,上半部分處理事情比較少,主要是暫存器、時間敏感的任務,以及登記中斷,通知核心處理中斷下半部分;下半部分處理比較耗時的操作,如上面講到串列埠buffer資料的處理部分。
此時我們總結linux中斷如下:
一般來說,在處理完上半部分中斷之後,下半部分會在核心的排程下被執行,當然如果有更高優先順序的任務需要處理時,會優先處理該任務再排程中斷下半部分,或者在空閒的時候處理。
對於linux系統裝置而言,乙個完整的中斷程式由上半部和下半部分共同構成,在編寫裝置驅動程式前,就需考慮好上半部和下半部的分配。很多時候上半部與下半部並沒有嚴格的區分界限,主要由程式設計師根據實際設計,如某些外設中斷可以沒有下半部。關於上下半部的劃分原則,就是主要事務、耗時事務劃分在下半部處理。
1)與硬體相關的操作,如操作暫存器,必須放在上半部。
2)對時間敏感、要求實時性的任務放在上半部。
3)該任務不能被其他中斷或者程序打斷的放在上半部。
4)實時性要求不高的任務、耗時任務放在下半部。
linux下半部實現,通過核心版本更新中實現下衍化,最原始的實現手段是bh(bottom half)後在2.5版本移除,在2.3版本引入軟中斷(softirq)和tasklet機制,在2.5版本引入工作佇列(workqueue)。因此,目前使用方式是三種,軟中斷、tasklet機制、工作佇列。上半部分執行時是允許中斷請求的,而上半部分執行時時關閉中斷的。
1、軟中斷是在編譯期間靜態分配的。
2、最多可以有32個軟中斷。
3、軟中斷不會搶占另外乙個軟中斷,唯一可以搶占軟中斷的是中斷處理程式。
4、可以併發執行在多個cpu上(即使同一型別的也可以)。所以軟中斷必須設計為可重入的函式(允許多個cpu同時操作),因此也需要使用自旋鎖來保護其資料結構。
5、目前只有兩個子系直接使用軟中斷:網路和scsi。
6、執行時間有:從硬體中斷**返回時、在ksoftirqd核心執行緒中和某些顯示檢查並執行軟中斷的**中。
1、tasklet是使用兩類軟中斷實現的:hi_softirq和tasklet_softirq。
2、可以動態增加減少,沒有數量限制。
3、同一類tasklet不能併發執行。
4、不同型別可以併發執行。
5、大部分情況使用tasklet。
1、由核心執行緒去執行,換句話說總在程序上下文執行。
2、可以睡眠,阻塞。
在多工系統下,中斷可能在任務執行的任何時間發生;如果乙個函式的執行期間被中斷後,到重新恢復到斷點進行執行的過程中,函式所依賴的環境沒有發生改變,那麼這個函式就是可重入的,否則就不可重入。
在中斷前後不都要儲存和恢復上下文嗎,怎麼會出現函式所依賴的環境發生改變了呢?我們知道中斷時確實儲存一些上下文,但是僅限於返回位址,cpu暫存器等之類的少量上下文,而函式內部使用的諸如全域性或靜態變數,buffer等並不在保護之列,所以如果這些值在函式被中斷期間發生了改變,那麼當函式回到斷點繼續執行時,其結果就不可預料了。
滿足下面條件之一的多數是不可重入函式:
(1)使用了靜態資料結構;
(2)呼叫了malloc或free;
(3)呼叫了標準i/o函式;
(4)進行了浮點運算.
malloc/free是不可重入的,它們使用了全域性變數來指向空閒區;
標準i/o庫的很多實現都使用了全域性資料結構;
許多的處理器/編譯器中,不可重入的 (浮點運算大多使用協處理器或者軟體模擬來實現)。
在訊號處理程式及多執行緒程式設計時,要特別注意。
關於計數中斷迴圈的一些錯誤思考
for int i 1 i n i 對於這個 我們要注意這個是先進行條件判斷,再進行計數判斷。如果存在剛開始就已經符合k了的話,這種就會少考慮了。同樣,如果是這樣 for int i 1 i n i 把中斷條件放到最後的話,也會少考慮一些情況如,最後一此迴圈 i n時達成count 此時符合coun...
關於中斷的一些整理
中斷裝置和中斷處理程式統稱為中斷系統。中斷系統是計算機的重要組成部分。實時控制 故障自動處理 計算機與外圍裝置間的資料傳送往往採用中斷系統。中斷系統的應用大大提高了計算機效率。不同的計算機其硬體結構和軟體指令是不完全相同的,因此,中斷系統也是不相同的。計算機的中斷系統能夠加強cpu對多工事件的處理能...
關於SpringIOC的一些思考
ioc是 依賴倒置原則 的乙個特例,說其是特例,就是說其具有 依賴倒置原則 的性質。依賴倒置原則強調的兩點是 上層模組和下次模組都依賴於抽象,二者之間通過這種抽象的東西聯絡在一起 具體可以依賴於抽象,而抽象不能依賴於具體。我認為spring提倡的 基於介面程式設計 就是為了遵循 依賴倒置原則 其中所...