Linux驅動中斷下半部的三種方法
什麼是中斷下半部
當產生中斷時,會進入中斷處理程序。
但中斷處理程序必須快速、非同步、簡單的對硬體做出迅速回應並完成那些時間要求很嚴格的操作。
因此,對於那些其他的、對時間要求相對寬鬆的任務,就應該推後到中斷被激活以後再去運行。
這樣,整個中斷處理流程就被分成了兩個部分:
第一個部分是中斷處理程序(上半部),核心透過對它的非同步執行完成對硬體中斷的即時回應。 中斷處理流程中的另外一部分,下半部(bottom half)
下半部的任務主要是執行與中斷相關的工作,這些工作並沒有被中斷服務程序本身完成。

下半部並不需要指明一個確切時間,只要把這些任務推遲一點,讓它們在系統不太繁忙並且中斷恢復後執行就可以了。
上半部與下半部的主要差異:
上半部指的是中斷處理程序,下半部則指的是一些雖然與中斷有相關性但是可以延後執行的任務。
上半部中斷不能被相同類型的中斷打斷,而下半部依然可以被中斷打斷。
通常下半部在中斷處理程序一回就會馬上運作。
上半部簡單快速,執行的時候禁止一些或全部中斷。
下半部稍後執行,而且執行期間可以回應所有的中斷。
在
Linux
中,中斷下半部的實作主要有三種:
軟體中斷 tasklet #工作佇列
##softirq
#softirq即軟體中斷,程式碼位於
kernel/softirq.c檔案中;
softirq_action結構表示:

softirq.c中定義了一個軟中斷向量陣列
softirq_vec:
static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp; enum { HI_SOFTIRQ=0, /*用于高优先级的tasklet*/ TIMER_SOFTIRQ, /*用于定时器的下半部*/ NET_TX_SOFTIRQ, /*用于网络层发包*/ NET_RX_SOFTIRQ, /*用于网络层收报*/ BLOCK_SOFTIRQ, BLOCK_IOPOLL_SOFTIRQ, TASKLET_SOFTIRQ, /*用于低优先级的tasklet*/ SCHED_SOFTIRQ, HRTIMER_SOFTIRQ, RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };
NR_SOFTIRQS決定,是一個列舉常數。
include/linux/interrupt.h 中加入一個列舉常數。
軟體中斷使用的幾個要點:
一个软中断不会抢占另外一个软中断。 惟一可以抢占软中断的是中断处理程序。 其他的软中断可以在其他处理器上同时执行。
相关接口
注册软中断
void open_softirq(int nr, void (*action)(struct softirq_action *))
即注册对应类型的处理函数到全局数组softirq_vec
中。
触发软中断
void raise_softirq(unsigned int nr)
实际上即以软中断类型nr
作为偏移量会置位irq_stat[cpu_id]
的成员变量__softirq_pending
.
__softirq_pending
字段中的每一个bit
,对应着某一个软中断,某个bit
被置位,说明有相应的软中断等待处理。
这也是同一类型软中断可以在多个cpu
上并行运行的根本原因。
软中断实例
以一个按键驱动的中断处理为例,将按键驱动的中断处理分成上下两部分:
上半部:讀取鍵值,觸發軟中斷 下半部:喚醒程序

軟中斷的註冊,在驅動的入口函數,註冊軟中斷:

新增的列舉常數:

可以看到,使用軟中斷是需要修改內核,增加一個列舉的,有些繁瑣。
所以,通常我們不建議擅自增加軟中斷的數量,如果需要新的軟中斷,盡可能把它們實現為基於軟中斷的tasklet
形式。
tasklet
#tasklet是利用軟體中斷實作的一種下半部機制。
那是用軟中斷還是tasklet
好呢?
選擇到底是用軟體中斷還是tasklet
其實很簡單:
通常你应该用 tasklet
。就像我们在前面看到的,软中断资源有限,也麻烦,而且软中断的使用者屈指可数。它只在那些执行频率很高和连续性要求很高的情况下才需要。而tasklet却有更广泛的用途。大多数情况下用 tasklet
效果都不错,而且它们还非常容易使用。因为tasklet是通过软中断实现的,所以它们本身也是软中断。
tasklet使用
tasklet
的使用步骤如下:
1、编写tasklet
处理函数(下半部)
void my_tasklet_fun (unsigned long data)
2、声明tasklet
//静态 DECLARE_TASKLET(my_tasklet,my_tasklet_fun,data); //动态 Struct tasklet_struct xxx; tasklet_init(&xxx,tasklet_handler,dev)
3、调度 tasklet
tasklet_schedule(&my_tasklet);
登记my_tasklet
, 然后允许系统在合适的时间调度它。
tasklet实例
以按键中断驱动为例:

先使用DECLARE_TASKLET
靜態宣告一個tasklet
,指定其下半部函數為btn_tasklet_func
,在中斷服務函數(上半部)取得按鍵值後,呼叫tasklet_schedule
調度。
work queue
#work queue
即工作佇列,也是中斷下半部的一種。
Work queue
將下半部工作延後給一個核心執行緒去執行-work
總是運行於進程上下文.
兩個要點:
如果延遲的工作需要睡眠,則使用 work queues
。否則使用softirq
或tasklets
.#Work queues
適用於需要分配大量的內存,以獲得一個信號量,或執行阻塞的I/O
的情況.
工作佇列的相關介面函數:

在使用上,工作佇列與tasklet
是類似的:

以上是Linux驅動中斷下半部的三種方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)
