1、 中斷的理解
中斷你可以理解為就是一種電信號,是由硬件設備產生的然后發送給處理器,處理器接收到中斷后,就會馬上向操作系統反映此信號,之后就是系統的工作了。
這里有兩個注意的地方,第一中斷是隨時都可以產生,意味着中斷的處理程序隨時都可以執行,所以得保證中斷處理程序能夠快速執行,才可能盡快的恢復中斷代碼執行,所以中斷代碼盡量簡短。第二每一個中斷都有自己唯一的數字標記,這樣操作系統才能對症下葯
2、 注冊中斷中斷處理程序
中斷處理程序是管理硬件的驅動程序的組成部分,每一設備都有相關的驅動程序,驅動程序可以通過request_irq()函數注冊一個中斷處理程序,並且激活給定的中斷線,來處理指定的中斷,原型如下:
int request_irq(unsigned int irq,
irq_handler_t handler,
unsigned long flags, const char *devname, void *dev_id)
第一個參數irq表示要分配的中斷號,就我目前所接觸的都是預先已經預定好的,還沒試着通過探測或者動態來確定中斷號
第二個參數handler是一個指針,指向處理這個中斷的實際中斷處理程序,只要操作系統一接收到中斷,該函數就被調用,這個函數稍后討論
第三個參數flags中斷處理程序的標志,這個標志可以是一個也可以是多個,列舉幾個最重要的標志:
IRQF_DISABLED: 該標志被設置后,意味內核在處理中斷處理程序本身的時候,禁止了其他所有的中斷。如果不設置,中斷處理程序可 以與除本身之外的其他任何中斷同時運行。顯而易見我們一般不去這么野蠻的設置這個標志
IRQF_TIMER:為系統定時器的中斷處理而准備的
IRQF_SHARED:這個中斷標志經常能遇見,這個標志意思就是多個中斷處理程序之間可以共享中斷線,概括起來就是沒有這個標志就只能獨自一個人占用,標志了,就是很多人可以占用這個中斷號來
第四個才參數就是自定義與中斷設備相關的文本了
第五個參數dev,看到第三個參數中IRQF_SHARED時候,你會不會有這樣的疑問,假如現在我要釋放當前共享的指定這個中斷程序時候,我如何釋放?會不會把其他占用也會刪除掉,這就是第五個參數的意義,如果中斷線是共享的,那么就必須傳遞能夠代表當前設備的唯一信息
request_irq()成功返回0,如果返回非0,就表示有錯誤發生,這個時候你可以考慮當前中斷是否被占用了,所以可以加上IRQF_SHARED標志
3、 中斷處理程序
這里延續上面的handler指針,原型如下:
Static irqreturn_t intr_handler(int irq, void *dev)
這里嘮叨一下,不知道大家面試時候有沒有遇到像這樣的題目
__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf(" Area = %f", area);
return area;
},指出上面中斷函數出現的錯誤,不知道的就認真看下面的 O(∩_∩)O
第一個參數irq就是這個處理程序要響應的中斷號,這個我認為現在沒有多大意義了,因為上面有講述到第五個參數的意義
第二個參數dev是一個通用的指針,同樣的,還是將上面講述到的第五個參數拿過來理解。
返回值irqreturn_t,先看下面的定義
enum irqreturn {
//中斷處理程序檢測到一個中斷,但該中斷對應的設備並不是在注冊處理函數期間指定的產生源時,返回這個值
IRQ_NONE,
//中斷處理程序被正確調用且確實是它多對應的設備產生了中斷,返回這個值
IRQ_HANDLED,
IRQ_WAKE_THREAD,
};
typedef enum irqreturn irqreturn_t;
關於描述到這里,我想對中斷有一個大概的了解,說白了就是硬件向處理器發送一個電信號,系統收到信號之后根據初始化的標志去處理相應的中斷處理程序。
如果熟悉中斷的應該知道,我這里所有描述的其實都是中斷處理程序的上半部,而下半部是什么,為啥要將中斷分為上下部兩部分?現在腦子里先有一個概念就是中斷是隨時產生的,也就意味着可能會打斷了一些當前重要的工作而去處理你的中斷處理程序,那當然我的中斷程序是越快越好。同時中斷他是不能被阻塞的,即不能在進程的上下文運行。基於上述原因 就是引入下半部的原因了。
(轉載自:http://blog.chinaunix.net/uid-24666775-id-3787938.html)
