當前位置:編程學習大全網 - 編程語言 - Linux中斷編程

Linux中斷編程

中斷和定時器:

中斷的概念:是指在CPU執行過程中,遇到壹些突發事件需要緊急處理,CPU暫停當前程序的執行,轉而處理突發事件。

處理完成後,CPU返回原程序中斷的位置繼續執行。

中斷的分類:內部中斷和外部中斷。

內部中斷:中斷源來自CPU(軟件中斷指令、溢出、觸發錯誤等。)

外部中斷:中斷源來自CPU外部,由外設請求。

屏蔽中斷和非屏蔽中斷:

可屏蔽中斷:它可以被屏蔽字屏蔽。屏蔽後,中斷將不再接收響應。

非平布中斷:無法屏蔽。

向量中斷和非向量中斷:

向量中斷:CPU通常給不同的中斷分配不同的中斷號,當檢測到壹個中斷號到來時,自動跳轉到該中斷號對應的地址執行。

非向量中斷:多個中斷* * *共享壹個入口地址。輸入入口地址後,軟件判斷中斷標誌以識別哪個是中斷。

也就是說,軟件為向量中斷提供中斷服務程序的入口地址,軟件為非向量中斷提供入口地址。

/*典型的非向量中斷首先判斷中斷源,然後調用不同中斷源的中斷處理程序*/

irq_handler()

{

...

int int _ src = read _ int _ status();/*讀取硬件的中斷相關寄存器*/

Switch(int_src){//判斷中斷標誌

案例開發_A:

dev _ a _ handler();

打破;

案例開發_B:

dev _ b _ handler();

打破;

...

默認值:

打破;

}

...

}

定時器中斷原理:

定時器也在硬件中中斷,PIT(可編程間隔定時器)接收時鐘輸入。

當時鐘脈沖到達時,將當前計數值增加1,並與設定計數值進行比較。如果相等,則證明計數周期已滿,並產生壹個定時器中斷。

重置計數值。

如下圖所示:

Linux中斷處理程序架構:

Linux把中斷分為:上半部分和下半部分。

頂板:完成盡可能少的緊急功能,通常只是讀取寄存器中的中斷狀態並清除中斷標誌。

“註冊中斷”的工作(即將下半部分執行隊列中的下半部分處理程序掛在設備上)

特點:反應快。

下半部分:中斷處理的大部分工作都在下半部分,它幾乎完成了中斷處理程序的所有工作。

特點:處理相對不太緊急的事件。

提示:查看Linux中的/proc/interrupts文件,獲取系統中斷的統計信息。

如下圖所示:

第壹列是中斷號,第二列是CPU產生中斷的次數。

介紹完相關的基本概念,我們壹起來討論壹下Linux中斷編程。

Linux中斷編程:

1.請求和釋放中斷

中斷請求:

int request_irq(無符號int irq,irq_handler_t handler,

無符號長整型irqflags,const char *devname,void *dev_id)

參數描述:irq是要應用的硬件中斷號。

Handler是壹個向系統註冊的中斷處理程序(上半部分),它是壹個回調函數。當中斷發生時,系統調用它並將

Dev_id參數傳遞給它。

Irqflags:它是中斷處理的壹個屬性,可以指定如何觸發和處理中斷:

觸發模式:IRQF_TRIGGER_RISING、IRQF_TRIGGER_FALLING、IRQF_TRIGGER_HIGH、IRQF_TRIGGER_LOW。

處理模式:IRQF_DISABLE表示中斷處理程序是壹個快速處理程序,當快速處理程序被調用時,所有中斷都被屏蔽。

IRQF_SHARED表示多個設備* * *享受中斷,dev_id在中斷* * *享受時使用,壹般設置為NULL。

返回值:0表示成功,-EINVAL表示中斷號無效,-EBUSY表示中斷已被占用,無法享用。

上半部分處理程序的類型irq_handler_t定義為

typedef IRQ return _ t(* IRQ _ handler _ t)(int,void *);

typedef int IRQ return _ t;

釋放IRQ

當然,有求必有放。

void free_irq(無符號int irq,void * dev _ id);

參數定義類似於request_irq。

3.啟用和屏蔽中斷

void disable _ IRQ(int IRQ);//等待當前中斷處理完成(最好不要用在頂板上,妳懂的)

void disable _ IRQ _ no sync(int IRQ);//立即返回

void enable _ IRQ(int IRQ);//

4.屏蔽該CPU中的所有中斷:

#定義local _ IRQ _ save(標誌)...//中斷禁用並保存狀態。

void local _ IRQ _ disable(void);//中斷禁用,不保存狀態。

下面分別介紹壹下上半部分和下半部分的實現機制。

下半部分機制:

簡介:下半部分機制主要包括小任務、工作隊列和軟中斷。

1.下半部分是思考的方式之壹。

(1)我們需要定義微線程機器處理器並關聯它們。

例如:

void my_tasklet_func(無符號長整型);/*定義處理程序*/

DECLARE_TASKLET(my_tasklet,my_tasklet_func,data);

/*上面的代碼定義了壹個名為my_tasklet的小任務,並設置了其余的。

My_tasklet_func()函數綁定,傳入的參數是data*/

(2)時間安排

tasklet_schedule。my _ tasklet);

//使用此函數調度操作。

Tasklet使用模板:

/*定義小任務和下半部分函數,並將它們關聯*/

void xxx_do_tasklet(無符號長整型);

DECLARE_TASKLET(xxx_tasklet,xxx_do_tasklet,0);

/*中斷處理的下半部分*/

void xxx_do_tasklet(無符號長整型)

{

...

}

/*中斷處理上半部分*/

IRQ return _ t XXX _ interrupt(int IRQ,void *dev_id)

{

...

tasklet_schedule。XXX _ tasklet);//調度樓層部門

...

}

/*設備驅動模塊加載函數*/

int __init xxx_init(void)

{

...

/*請求中斷*/

結果=請求_irq(xxx_irq,XXX _中斷,

IRQF_DISABLED,“xxx”,NULL);

...

返回IRQ _ HANDLED

}

/*設備驅動模塊卸載功能*/

void __exit xxx_exit(void)

{

...

/*釋放中斷*/

free_irq(xxx_irq,XXX _ interrupt);

...

}

2.底部半工作隊列的第二種實現方法

使用方法類似於tasklet。

相關操作:

結構work _ struct my _ wq/*定義工作隊列*/

void my_wq_func(無符號長整型);/*定義處理程序*/

INIT_WORK()可用於初始化工作隊列,並將工作隊列綁定到處理程序。

初始化工作(& ampmy_wq,(void (*)(void *))my_wq_func,NULL);

/*初始化工作隊列並將其綁定到處理程序*/

schedule _ work(& amp;my _ wq);/*調度工作隊列執行*/

/*工作隊列使用模板*/

/*定義工作隊列和相關功能*/

struct work_struct(無符號長整型);

void xxx_do_work(無符號長整型);

/*中斷處理的下半部分*/

void xxx_do_work(無符號長整型)

{

...

}

/*中斷處理上半部分*/

/*中斷處理上半部分*/

IRQ return _ t XXX _ interrupt(int IRQ,void *dev_id)

{

...

schedule _ work(& amp;my _ wq);//調度下半部分

...

返回IRQ _ HANDLED

}

/*設備驅動模塊加載函數*/

int xxx_init(void)

{

...

/*請求中斷*/

結果=請求_irq(xxx_irq,XXX _中斷,

IRQF_DISABLED,“xxx”,NULL);

...

/*初始化工作隊列*/

初始化工作(& ampmy_wq,(void (*)(void *))xxx_do_work,NULL);

}

/*設備驅動模塊卸載功能*/

void xxx_exit(void)

{

...

/*釋放中斷*/

free_irq(xxx_irq,XXX _ interrupt);

...

}

  • 上一篇:小學生冬奧會項目介紹內容是什麽?
  • 下一篇:在線購物網站建設-如何建設商城網站?
  • copyright 2024編程學習大全網