嵌入式linux核心中斷的理解

2021-10-04 12:58:25 字數 4632 閱讀 8815

一,嵌入式linux核心中斷的理解

1, 計算機為什麼有中斷機制?

由於外設的處理速度遠遠慢於cpu的處理速度 為了保證cpu和外設的資料通訊正確,一般呢首先可能考慮使用輪詢機制(輪詢就是死等),如果輪詢的時間過程長,會大大降低cpu的利用率(cpu不能幹其他的事情,只能等待當前這個硬體)此時還可以考慮使用中斷機制,當cpu發現裝置沒有準備就緒, cpu幹其他的事情(比如做乙個演算法)一旦外設準備好了,外設會給cpu傳送乙個中斷電訊號 ,cpu一旦接收到了這個中斷電訊號,cpu停止當前的 任務,轉去處理外設,處理完畢以後,再去接著執行原先被打斷的任務,大大提高了cpu的利用率!以cpu讀取uart資料為例,可以闡述一下!

2,中斷的硬體連線和中斷的處理流程

(1)切記:外設產生的中斷電訊號,不會直接給cpu,而是這個中斷電訊號首先要經過中斷控制器,經過中斷控制器的一番判斷以後,

中斷控制器最終決定這個中斷訊號是否傳送cpu

中斷控制器的功能:

a.能夠使能或者禁止某個外設中斷

b.能夠設定外設中斷的優先順序

c.能夠設定外設中斷將來以什麼樣的方式(irq/fiq)傳送給cpu      

d.能夠設定外設中斷的有效觸發電訊號

高電平觸發中斷

低電平觸發中斷

上公升沿觸發中斷

下降沿觸發中斷

雙邊沿觸發中斷

(2).中斷的處理過程

明確:中斷本質就是一種異常以按鍵為例,談談中斷的整個處理過程:

a.當使用者按下按鍵,gpu管腳的硬體電訊號由高電平變成低電平,產生乙個下降沿電訊號

b.這個下降沿電訊號,輸送中斷控制器

c.中斷控制器首先判斷這次中斷訊號有沒有被禁止如果禁止了,直接丟棄,

如果沒有禁止,再判斷當前有沒有高優先順序的中斷;如果有,直接丟棄。

如果沒有,再判斷這個下降沿是否是有效的觸發訊號;如果不是,直接丟棄。

如果是,再判斷以何種方式傳送給cpu(irq/fiq) 最終選擇fiq或者irq形式傳送給cpu乙個電訊號。

這個過程都是硬體在做!

d.cpu一旦接收到了這個中斷控制器傳送來的電訊號這裡以irq為例,cpu核啟動硬體的處理流程:

<1>.備份cpsr到spsr_irq

<2>.設定cpsr的mode=irq模式

t=0  / i=1 / f=1       

<3>.儲存返回位址到lr_irq=pc-4

<4>.設定pc的位址為0x18,至此cpu跑到0x18位址去"執行",也就是cpu跑到異常向量表irq的處理入口位址0x18

至此開啟了軟體處理中斷的流程:

<5>.軟體處理中斷的流程:保護現場(壓棧),呼叫對應中斷處理函式,進一步對中斷,進行處理,裡面做何事,完全由使用者需求來決定,中斷處理函式執行完畢,恢復現場(彈棧)   

<6>.至此cpu繼續跑到原先被打斷的地方執行!

<7>.明確:這個過程中,發生了一次cpu資源的切換!

3.畫出乙個中斷的處理示意圖:

4.中斷的軟體程式設計(不管是裸板還是跑作業系統都一樣)

(1).編寫異常向量表的**

(2).編寫保護現場的**

(3).編寫中斷處理函式:具體做何事,根據使用者需求來定

(4).編寫恢復現場的**        

總結:不管是裸板還是跑作業系統,中斷軟體程式設計,只需關注第3步即可!

只要將編寫好的中斷處理函式,註冊,將來硬體產生的中斷,cpu最終去執行對應的中斷處理函式!

5,linux核心中斷程式設計

linux核心註冊/釋放中斷處理函式的方法:

int request_irq(中斷號,中斷處理函式,中斷標誌,中斷名稱, 給中斷處理函式傳遞的引數)

irqreturn_t 中斷處理函式名(當前觸發中斷的中斷號, 對應的引數)

free_irq(中斷號,給中斷處理函式傳遞的引數)

中斷註冊完畢,可以使用cat /proc/interrutps進行檢視!

明確:外設的中斷處理函式執行在核心空間!思路就是將外設的中斷處理函式註冊到核心中將來一旦硬體產生中斷,

核心最終呼叫註冊的中斷處理函式,至於1,2,4這三步都是由核心完成!

二,中斷處理之問

1,問:如何向核心註冊硬體外設的中斷處理函式呢?答:利用大名鼎鼎的request_irq/free_irq函式

int request_irq(unsigned int irq,  irq_handler_t handler,  unsigned long flags,  const char *name, void *dev)

request_irq(btn_info[i].irq, button_isr,  irqf_trigger_falling|irqf_trigger_rising, btn_info[i].name, &btn_info[i]);

函式功能:

(1).向核心申請硬體中斷資源(類似malloc,申請裝置號,申請gpio資源)

(2).還要向核心註冊這個硬體中斷對應的中斷處理函式一旦註冊完畢,將來硬體產生中斷,核心就會呼叫其註冊的中斷處理函式

引數: irq:就是硬體中斷對應的乙個軟體編號(類似硬體中斷的身份證號)此編號又稱中斷號,從32開始,0~31核心保留!

硬體中斷      中斷號

xeint0        irq_eint(0)

xeint1        irq_eint(1)

handler:傳遞要註冊的中斷處理函式

3, 例如:

static irqreturn_t ***_isr(int irq, void *dev)

return irq_none;//中斷處理函式執行失敗

或者return irq_handled; //中斷正常處理完畢

引數:irq:就是對應的硬體中斷的中斷號

dev:註冊中斷處理函式時傳遞的引數

flags:中斷標誌

對於外部中斷:指定有效的觸發方式,以下巨集來指定:

irqf_trigger_falling :下降沿觸發

irqf_trigger_rising :上公升沿觸發

irqf_trigger_high :高電平觸發

irqf_trigger_low : 低電平觸發   

irqf_trigger_falling|irqf_trigger_rising:雙邊沿觸發

對於內部中斷:給0即可!   

name:中斷名稱,用於除錯

執行:cat /proc/interrupts檢視如果有這個名,說明註冊ok否則失敗!

dev:給中斷處理函式傳遞的引數不傳參給null

執行緒:void *thread_func(void *dev)

int data = 0x55;

pthread_create(&tid, null, thread_func, &data);   

切記:中斷不再使用時,記得要釋放硬體中斷資源和刪除中斷處理函式

void free_irq(int irq, void *dev) [ free_irq( btn[i].irq, &btn_info[i] );  ]

irq:釋放的中斷號

dev:給中斷處理函式傳遞的引數,這個一定一定要和註冊時傳遞的引數要保持一致!

三,什麼是系統呼叫?明確:使用者空間和核心空間唯一的通訊方式只能通過系統呼叫

系統呼叫原理:以write系統呼叫函式為例向串列埠終端輸出字串:write(1, "hello,world\n", 12);

1.某個程序呼叫write系統呼叫函式

2.首先跑到c庫的write函式的定義(實現)

3.c庫write函式的定義將做兩件事

3.1:儲存write函式對應的系統呼叫號到r7暫存器

(1)系統呼叫號:linux核心給每乙個系統呼叫函式都分配乙個唯一的數字編號,這個編號稱之為系統呼叫號(系統呼叫函式的身份證號)

(2)定義在核心原始碼的:arch/arm/include/asm/unistd.h

(3)write函式的系統呼叫號(__nr_系統呼叫函式名): #define __nr_write 4

3.2.呼叫svc指令觸發軟中斷異常、老arm版本使用swi指令、 新arm版本使用svc指令

4.一旦c庫的write函式觸發軟中斷異常,接下來要做:

arm核硬體做:

(1).備份cpsr

(2).設定cpsr

(3).lr=pc-4

(4).pc=軟中斷的處理入口位址0x08

跳轉到核心事先準備好的異常向量表的軟中斷處理入口位址0x08,繼續執行,開啟了軟體處理異常的流程

至此:cpu由user模式切換svc管理模式

3.1,保護現場(壓棧)

3.2,處理做兩件事:

(1).從r7暫存器中取出之前儲存的系統呼叫號4

(2).再以系統呼叫號為下標,在核心實現準備好的系統呼叫表(陣列)中找到對應的函式sys_write,找到以後,呼叫此函式,此函式執行完畢,返回即可。

「系統呼叫表」:本質上就是乙個陣列,陣列的每乙個元素儲存的是乙個函式指標,函式名命名sys_系統呼叫函式名,這些**統統由核心已經實現好!

定義在核心原始碼的arch/arm/arch/arm/kernel/calls.s

恢復現場(出棧),也就代表著應用程式呼叫write函式的返回

嵌入式linux核心中下測試sata硬碟的讀寫速度

首先核心中要編譯進去sata驅動,make menuconfig中將sata驅動選上,編譯核心,在開發板上啟動,然後fdisk l檢視磁碟分割槽,掛載上sata硬碟。第一種方法,利用dd命令。測試硬碟的讀取速度 time dd if dev sda1 of dev null bs 1m count ...

嵌入式linux核心中下測試sata硬碟的讀寫速度

分類 tools 2012 08 15 15 31 2051人閱讀收藏 舉報 測試linux核心 嵌入式ide 磁碟工具 首先核心中要編譯進去sata驅動,make menuconfig中將sata驅動選上,編譯核心,在開發板上啟動,然後fdisk l檢視磁碟分割槽,掛載上sata硬碟。第一種方法,...

嵌入式中斷

interrupt double compute area double radius 這個函式有太多的錯誤了,以至讓人不知從何說起了 1 isr 不能返回乙個值。如果你不懂這個,那麼你不會被雇用的。2 isr 不能傳遞引數。如果你沒有看到這一點,你被雇用的機會等同第一項。3 在許多的處理器 編譯器...