日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux下怎样看设备的中断号,Linux设备驱动的中断处理

發(fā)布時(shí)間:2025/3/12 linux 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux下怎样看设备的中断号,Linux设备驱动的中断处理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Linux設(shè)備驅(qū)動(dòng)中,中斷處理非常重要,尤其是在嵌入式系統(tǒng)中,無時(shí)無刻不在與中斷打交道,因此,中斷處理必須要牢牢掌握。

設(shè)備在產(chǎn)生某個(gè)事件時(shí)通知處理器的方法就是中斷。中斷就是一個(gè)信號(hào),當(dāng)硬件需要通知CPU你該處理我的數(shù)據(jù)或狀態(tài)時(shí),就會(huì)發(fā)出這個(gè)信號(hào),而處理器如果發(fā)現(xiàn)驅(qū)動(dòng)注冊(cè)了該中斷信號(hào),就會(huì)保存現(xiàn)場(chǎng),執(zhí)行中斷處理程序,然后再恢復(fù)現(xiàn)場(chǎng)。中斷處理程序和其他代碼是并行的,因此必須考慮競(jìng)態(tài)問題。

1.注冊(cè)中斷

內(nèi)核維護(hù)了一個(gè)中斷信號(hào)線的注冊(cè)表,驅(qū)動(dòng)模塊在使用中斷前要先請(qǐng)求一個(gè)中斷通道(或者 IRQ中斷請(qǐng)求),并在使用后釋放它。

int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name, void *dev_id);

void free_irq(unsigned int irq, void *dev_id);

中斷處理例程可在驅(qū)動(dòng)初始化時(shí)或在設(shè)備第一次打開時(shí)安裝。推薦在設(shè)備第一次打開、硬件被告知產(chǎn)生中斷前時(shí)申請(qǐng)中斷,因?yàn)榭梢怨蚕碛邢薜闹袛噘Y源。這樣調(diào)用 free_irq 的位置是設(shè)備最后一次被關(guān)閉、硬件被告知不用再中斷處理器之后。但這種方式的缺點(diǎn)是必須為每個(gè)設(shè)備維護(hù)一個(gè)打開計(jì)數(shù)。

i386 和 x86_64 體系定義了一個(gè)函數(shù)來查詢一個(gè)中斷線是否可用:

int can_request_irq(unsigned int irq, unsigned long flags); /*當(dāng)能夠成功分配給定中斷,則返回非零值。但注意,在 can_request_irq 和 request_irq 的調(diào)用之間給定中斷可能被占用*/

快速中斷和慢中斷

在現(xiàn)代內(nèi)核中,快速和慢速中斷的區(qū)別已經(jīng)消失,剩下的只有一個(gè):快速中斷(使用 SA_INTERRUPT )執(zhí)行時(shí)禁止所有在當(dāng)前處理器上的其他中斷(其他處理器仍然可以響應(yīng)中斷)。除非你充足的理由在禁止其他中斷情況下來運(yùn)行中斷處理例程,否則不應(yīng)當(dāng)使用SA_INTERRUPT。這個(gè)在嵌入式系統(tǒng)中或許用的比較多。

/proc/interrupts:記錄了中斷信息統(tǒng)計(jì)

/proc/stat:記錄了系統(tǒng)活動(dòng)的底層統(tǒng)計(jì)信息

2.自動(dòng)檢測(cè) IRQ 號(hào)

驅(qū)動(dòng)初始化時(shí)最迫切的問題之一是決定設(shè)備要使用的IRQ 線,驅(qū)動(dòng)需要信息來正確安裝處理例程。自動(dòng)檢測(cè)中斷號(hào)對(duì)驅(qū)動(dòng)的可用性來說是一個(gè)基本需求。有時(shí)自動(dòng)探測(cè)依賴一些設(shè)備具有的默認(rèn)特性,以下是典型的并口中斷探測(cè)程序:

if (short_irq < 0) /* 依靠使并口的端口號(hào),確定中斷*/

switch(short_base) {

case 0x378: short_irq = 7; break;

case 0x278: short_irq = 2; break;

case 0x3bc: short_irq = 5; break;

}

有 2 種方法來進(jìn)行探測(cè)中斷: 調(diào)用內(nèi)核定義的輔助函數(shù)和DIY探測(cè)。

(1)調(diào)用內(nèi)核定義的輔助函數(shù)

unsigned long probe_irq_on(void); /*這個(gè)函數(shù)返回一個(gè)未分配中斷的位掩碼。驅(qū)動(dòng)必須保留返回的位掩碼, 并在后面?zhèn)鬟f給 probe_irq_off。在調(diào)用probe_irq_on之后, 驅(qū)動(dòng)應(yīng)當(dāng)安排它的設(shè)備產(chǎn)生至少一次中斷*/

int probe_irq_off(unsigned long); /*在請(qǐng)求設(shè)備產(chǎn)生一個(gè)中斷后, 驅(qū)動(dòng)調(diào)用這個(gè)函數(shù), 并將 probe_irq_on 返回的位掩碼作為參數(shù)傳遞給probe_irq_off。probe_irq_off 返回在"probe_on"之后發(fā)生的中斷號(hào)。如果沒有中斷發(fā)生, 返回 0 ;如果產(chǎn)生了多次中斷,probe_irq_off 返回一個(gè)負(fù)值*/

(2)DIY探測(cè)

DIY探測(cè)與前面原理相同: 使能所有未使用的中斷, 接著等待并觀察發(fā)生什么。

3.實(shí)現(xiàn)中斷處理例程

中斷處理例程唯一的特別之處在中斷時(shí)運(yùn)行,它能做的事情受到了一些限制:

(1)中斷處理例程不能與用戶空間傳遞數(shù)據(jù), 因?yàn)樗辉谶M(jìn)程上下文執(zhí)行;

(2)中斷處理例程也不能做任何可能休眠的事情, 例如調(diào)用 wait_event, 使用除 GFP_ATOMIC 之外任何東西來分配內(nèi)存, 或者鎖住一個(gè)信號(hào)量;

(3)處理者不能調(diào)用schedule()。

4.禁用中斷

(1)禁用單個(gè)中斷

void disable_irq(int irq);/*禁止給定的中斷, 并等待當(dāng)前的中斷處理例程結(jié)束。如果調(diào)用 disable_irq 的線程持有任何中斷處理例程需要的資源(例如自旋鎖), 系統(tǒng)可能死鎖*/

void disable_irq_nosync(int irq);/*禁止給定的中斷后立刻返回(可能引入競(jìng)態(tài))*/

void enable_irq(int irq);

(2)禁用全部中斷

void local_irq_save(unsigned long flags);/*在保存當(dāng)前中斷狀態(tài)到 flags 之后禁止中斷*/

void local_irq_disable(void);/* 關(guān)閉中斷而不保存狀態(tài)*/

如果調(diào)用鏈中有多個(gè)函數(shù)可能需要禁止中斷, 應(yīng)使用 local_irq_save

void local_irq_restore(unsigned long flags); /*打開中斷使用*/

void local_irq_enable(void);

在 2.6 內(nèi)核, 沒有方法全局禁用整個(gè)系統(tǒng)上的所有中斷

5.中斷頂半部和底半部

中斷處理需要很快完成,可通過將中斷處理分為兩部分來解決這個(gè)問題:

(1)頂半部,立即執(zhí)行,實(shí)際響應(yīng)中斷的例程(request_irq 注冊(cè)的那個(gè)例程)

(2)底版本,被頂半部調(diào)度,并在稍后更安全的時(shí)間內(nèi)執(zhí)行的函數(shù)

Linux 內(nèi)核有 2 個(gè)不同的機(jī)制可用來實(shí)現(xiàn)底半部處理:

(1)tasklet (首選機(jī)制),它非常快, 但是所有的 tasklet 代碼必須是原子的。

(2)工作隊(duì)列, 它可能有更高的延時(shí),但允許休眠,執(zhí)行在進(jìn)程上下文中,但不允許與用戶空間進(jìn)行數(shù)據(jù)拷貝。

6.中斷共享

Linux 內(nèi)核支持在所有總線上中斷共享,Linux大部分中斷都是可以共享的。

在通過request_irq 安裝處理例程時(shí)候,有些不同:

(1)當(dāng)request_irq 時(shí),flags 中必須指定SA_SHIRQ 位;

(2)dev_id 必須唯一。任何指向模塊地址空間的指針都行,但 dev_id 絕不能設(shè)置為NULL。

請(qǐng)求一個(gè)共享的中斷時(shí),如果滿足下列條件之一,則request_irq 成功:

(1)中斷線空閑;

(2)所有已經(jīng)注冊(cè)該中斷信號(hào)線的處理例程也標(biāo)識(shí)了IRQ是共享。

一個(gè)共享的處理例程必須能夠識(shí)別自己的中斷,并且在自己的設(shè)備沒有被中斷時(shí)快速退出(返回 IRQ_NONE )。共享處理例程沒有探測(cè)函數(shù)可用,但使用的中斷信號(hào)線是空閑時(shí)標(biāo)準(zhǔn)的探測(cè)機(jī)制才有效。一個(gè)使用共享處理例程的驅(qū)動(dòng)需要小心:不能使用 enable_irq 或 disable_irq,否則,對(duì)其他共享這條線的設(shè)備就無法正常工作了。即便短時(shí)間禁止中斷,另一設(shè)備也可能產(chǎn)生延時(shí)而為設(shè)備和其用戶帶來問題,因?yàn)檫@個(gè)中斷可能不是你一個(gè)驅(qū)動(dòng)模塊在關(guān)注。

7.中斷驅(qū)動(dòng)的 IO

當(dāng)與驅(qū)動(dòng)程序管理的硬件間的數(shù)據(jù)傳送可能因?yàn)槟撤N原因而延遲,驅(qū)動(dòng)編寫者應(yīng)當(dāng)實(shí)現(xiàn)緩存。

輸入:當(dāng)新數(shù)據(jù)到達(dá)時(shí)并且處理器準(zhǔn)備好接受時(shí),設(shè)備中斷處理器。

輸出:當(dāng)設(shè)備準(zhǔn)備好接受新數(shù)據(jù)或確認(rèn)一個(gè)成功的數(shù)據(jù)傳送時(shí),設(shè)備產(chǎn)生中斷。

總結(jié)

以上是生活随笔為你收集整理的linux下怎样看设备的中断号,Linux设备驱动的中断处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。