嵌入式系統(tǒng)中斷課件_第1頁(yè)
嵌入式系統(tǒng)中斷課件_第2頁(yè)
嵌入式系統(tǒng)中斷課件_第3頁(yè)
嵌入式系統(tǒng)中斷課件_第4頁(yè)
嵌入式系統(tǒng)中斷課件_第5頁(yè)
已閱讀5頁(yè),還剩46頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

中斷與異常主要內(nèi)容

中斷的基本知識(shí)

中斷描述符表的初始化

中斷處理

中斷的下半部處理機(jī)制

中斷的應(yīng)用-時(shí)鐘中斷中斷的基本概念

硬中斷的概念硬中斷即和硬件相關(guān)的中斷也就是通常意義上的“中斷處理程序”,它是直接處理由硬件發(fā)過來(lái)的中斷信號(hào)的。

中斷執(zhí)行的過程當(dāng)某個(gè)設(shè)備發(fā)出中斷請(qǐng)求時(shí),CPU停止正在執(zhí)行的指令,

轉(zhuǎn)而跳到包括中斷處理代碼或者包括指

向中斷處理代碼的轉(zhuǎn)移指令所在的內(nèi)存區(qū)域。這些代碼一般在CP

U的中斷方式下運(yùn)

行。就回去自己驅(qū)動(dòng)的設(shè)備上去看看設(shè)備的狀態(tài)寄存器以了

解發(fā)生了什么事情,并進(jìn)行相應(yīng)的操作。當(dāng)中斷處理完畢以后,CPU將恢復(fù)到以前的狀態(tài),繼續(xù)執(zhí)行中斷處理前正在執(zhí)行的指令。Linux中斷處理特色分

為上半部和下半部執(zhí)行上

半部屏蔽所有中斷下

半部允許中斷,執(zhí)行幾乎所有中斷中斷控

制的主要優(yōu)點(diǎn):

CPU只

有在I/O需要服務(wù)時(shí)才響應(yīng)外部中斷:

外部

設(shè)備所發(fā)出的I/O請(qǐng)求內(nèi)部

中斷:

也稱之為“異?!?,是為解決機(jī)器運(yùn)行時(shí)所出現(xiàn)的某些隨機(jī)事件及編程方便而出現(xiàn)的中斷常識(shí)中斷

向量:每個(gè)中

斷源都被分配一個(gè)8位無(wú)符號(hào)整數(shù)作為類型碼,即中斷向量中斷的種類:中斷:外部

可屏蔽中斷外部非

屏蔽中斷異常:不

使用中斷控制器,不能被屏蔽故

障陷

阱中斷向量-中斷源的類型Intelx86通過兩片中斷控制器8259A來(lái)響應(yīng)15個(gè)外中斷源,每個(gè)8259A可管理8個(gè)中斷源。外部設(shè)備擁有相應(yīng)權(quán)限時(shí),可以向特定的中斷線發(fā)送中斷請(qǐng)求信號(hào)外部I/O請(qǐng)求的屏蔽:從CPU的角度,清除eflag的中斷標(biāo)志位從中斷控制器的角度,將中斷屏蔽寄存器的相應(yīng)位置位外設(shè)可屏蔽中斷

異常就是CPU內(nèi)部出現(xiàn)的中斷,即在CPU執(zhí)行特定指令時(shí)出現(xiàn)的非法情況。非屏蔽

中斷就是

計(jì)算機(jī)內(nèi)部硬件出錯(cuò)時(shí)引起的異常情況

Intel把非屏蔽中斷作為一種異常來(lái)處理在CPU執(zhí)行一個(gè)

異常處理程序時(shí),就不再為其他異

?;蚩善帘沃袛嗾?qǐng)求服務(wù)

異常及非屏蔽中斷

中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)圖3.4Linux的中斷處理數(shù)據(jù)結(jié)構(gòu)中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)在i386系統(tǒng)中,Linux啟動(dòng)時(shí)要設(shè)置系統(tǒng)的中斷描述符表IDT。IDT中包含各個(gè)中斷(以及異常,諸如浮點(diǎn)運(yùn)算溢出)的服務(wù)程序地址,中斷服務(wù)程序地址由Linux提供。每個(gè)設(shè)備驅(qū)動(dòng)程序可以在圖3.4所示的結(jié)構(gòu)(irq_action)中注冊(cè)自己的中斷及中斷處理程序地址。Linux的中斷服務(wù)程序根據(jù)irq_action

中的注冊(cè)信息調(diào)用相應(yīng)的設(shè)備驅(qū)動(dòng)程序的中斷處理程序。和硬件相關(guān)的中斷處理代碼隱藏在中斷服務(wù)程序中,這樣,設(shè)備驅(qū)動(dòng)程序的中斷處理程序可在不同平臺(tái)之間

方便移植。一般來(lái)說,CPU在處理中斷時(shí),首先要在堆棧中保存與CPU指令執(zhí)行相關(guān)的寄存器(例如指令計(jì)數(shù)

寄存器),然后調(diào)用中斷服務(wù)程序,中斷服務(wù)程序結(jié)束時(shí)

再恢復(fù)這些寄存器。中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)irq_action實(shí)際是一個(gè)數(shù)組,其中包含指向irqaction的指針,每個(gè)數(shù)組元素分別定義一個(gè)IRQ。Linux內(nèi)核提供相應(yīng)的操作函數(shù),設(shè)備驅(qū)動(dòng)程序可調(diào)用這些操作函數(shù)設(shè)置相應(yīng)的中斷處理函數(shù)。一般在系統(tǒng)啟動(dòng)時(shí),由各個(gè)設(shè)備驅(qū)動(dòng)程序通過如下途徑獲取相關(guān)的設(shè)備IRQ并設(shè)置對(duì)應(yīng)的irq_action數(shù)組元素所指向的irqaction結(jié)構(gòu)。由于0-31號(hào)中斷向量已被Intel保留,就剩下32-255共224個(gè)中斷向量可用。在Linux中,這224個(gè)中斷向量除了0x80(SYSCALL_VECTOR)用作系統(tǒng)調(diào)用總?cè)肟谥?,其它都用在外部硬件中斷源(包括可編程中斷控制?259A的15個(gè)irq)上。實(shí)際上,當(dāng)沒有定義CONFIG_X86_IO_APIC時(shí),其它223(除0x80外)個(gè)中斷向量,只利用了從32號(hào)開始的15個(gè),其它208個(gè)空著未用。這些中斷服務(wù)程序入口的設(shè)置將在下面詳細(xì)說明。與硬中斷相關(guān)數(shù)據(jù)結(jié)構(gòu)主要有三個(gè),三者關(guān)系如圖3.5所示。中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)(1)定義在/arch/i386/Kernel/irq.h中的structhw_interrupt_type數(shù)據(jù)結(jié)構(gòu),它是一個(gè)抽象的中

斷控制器。這包含一系列的指向函數(shù)的指針,這些函數(shù)處理控制器

特有的操作:typename:控制器的名字。startup:允許從給定

的控制器的IRQ所產(chǎn)生的事件。shutdown:禁止從給

定的控制器的IRQ所產(chǎn)生的事件。handle:根據(jù)提供

給該函數(shù)的IRQ,處理唯一的中斷。enable和disable:這兩個(gè)函數(shù)基本上和startup和shutdown相同;structhw_interrupt_type{constchar*typename;void(*startup)(unsignedintirq);void(*shutdown)(unsignedintirq);void(*handle)(unsignedintirq,structpt_regs*regs);void(*enable)(unsignedintirq);void(*disable)(unsignedintirq);};中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)(2)定義在/arch/i386/Kernel/irq.h中的另外一個(gè)數(shù)據(jù)結(jié)構(gòu)是irq_desc_t,它具有如下成員:status:一個(gè)整數(shù)。代表IRQ的狀態(tài):IRQ是否被禁止了,有關(guān)IRQ的設(shè)備當(dāng)前是否正被自動(dòng)檢測(cè),等等。handler:指向hw_interrupt_type的指針。action:指向irqaction結(jié)構(gòu)組成的隊(duì)列的頭。正常情況下每個(gè)IRQ只有一個(gè)操作,因此鏈接列表的正常長(zhǎng)度是1(或者0)。但是,如果IRQ被兩個(gè)或者多個(gè)設(shè)備所共享,那么這個(gè)隊(duì)列中就有多個(gè)操作。depth:irq_desc_t的當(dāng)前用戶的個(gè)數(shù)。主要是用來(lái)保證在中斷處理過程中IRQ不會(huì)被禁止。中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)irq_desc是irq_desc_t類型

的數(shù)組。對(duì)于每一個(gè)IRQ都有一個(gè)數(shù)組入口,即數(shù)組把每一個(gè)IRQ映射

到和它相關(guān)的處理程序和irq_desc_t中的其它信息。typedefstruct{unsignedintstatus;//IRQstatus-IRQ_INPROGRESS,IRQ_DISABLEDstructhw_interrupt_type*handler;//handle/enable/disablefunctionsstructirqaction*action;//IRQactionlistunsignedintdepth;//Disabledepthfornestedirqdisables}irq_desc_t;中斷的相關(guān)數(shù)據(jù)結(jié)構(gòu)structirqaction{void(*handler)(int,void*,structpt_regs*);unsignedlongflags;unsignedlongmask;constchar*name;void*dev_id;structirqaction*next;};中斷和異常的

硬件處理:從硬件的角

度看CPU如何處理中斷和異常中斷請(qǐng)求隊(duì)列

的建立:方便外設(shè)共

享中斷線

中斷處理程序的執(zhí)行

從中斷返回:調(diào)用恢復(fù)中斷現(xiàn)場(chǎng)的宏RESTORE_ALL,徹底從中斷返回

中斷處理

當(dāng)CPU執(zhí)行了當(dāng)前指令之后,CS和EIP這對(duì)寄存器中所包含的內(nèi)容就是下一條將要執(zhí)行指令的虛地址。在對(duì)下一條指令執(zhí)行前,CPU先要判斷在執(zhí)行當(dāng)前指令的過程中是否發(fā)生了中斷或異常。如果發(fā)生了一個(gè)中斷或異常,那么CPU將做以下事情:中斷和異常的硬件處理由于硬件

條件的限制,很多硬件設(shè)備共享一條中斷線為方便處理,Linux為每條中斷線設(shè)置了一個(gè)

中斷請(qǐng)求隊(duì)列中斷服務(wù)例程

與中斷處理程序中斷線共享的數(shù)據(jù)結(jié)構(gòu)注冊(cè)中斷服務(wù)例程中斷請(qǐng)求隊(duì)列的建立中斷服務(wù)例程(InterruptServiceRoutine):每個(gè)中斷請(qǐng)求都有自己?jiǎn)为?dú)的中斷服務(wù)例程中斷處理程序:共享同一條中斷線的所有中斷請(qǐng)求有一個(gè)總的中斷處理程序在Linux中,15條中斷線對(duì)應(yīng)15個(gè)中斷處理程序中斷服務(wù)例程與中斷處理程序

初始化IDT表之后,必須通過request_irq()函數(shù)將相應(yīng)的中斷服務(wù)例程掛入中斷請(qǐng)求隊(duì)列,即對(duì)其進(jìn)行注冊(cè)

在關(guān)閉設(shè)備時(shí),必須通過調(diào)用free_irq()函數(shù)釋放所申請(qǐng)的中斷請(qǐng)求號(hào)

注冊(cè)中斷服務(wù)例程

int

request_irq(unsigned

int

irq,void(*handler)(int,void*,struct

pt_regs*),unsignedlongirqflags,constchar*devname,void*dev_id)CPU從中斷

控制器的一個(gè)端口取得中斷向量I

根據(jù)I從中斷

描述符表IDT中找到相應(yīng)的中斷門從中斷門獲

得中斷處理程序的入口地址判斷是否要

進(jìn)行堆棧切換調(diào)用do_IRQ

()對(duì)所接收的中斷進(jìn)行應(yīng)答,并禁止這條中斷線調(diào)用handle_IRQ_event()來(lái)運(yùn)行對(duì)應(yīng)的中斷服務(wù)例程

中斷處理程序的執(zhí)行

當(dāng)處理所有外設(shè)中斷請(qǐng)求的函數(shù)do_IRQ()執(zhí)行時(shí),內(nèi)核棧頂包含的就是do_IRQ()的返回地址,這個(gè)地址指向ret_from_intr從中斷返回時(shí),

CPU要調(diào)用恢復(fù)中斷現(xiàn)場(chǎng)的宏

RESTORE_ALL,徹底從中斷返回。

從中斷返回

中斷服務(wù)例程在中斷請(qǐng)求關(guān)閉的條件下執(zhí)行,避免嵌套使中斷控制復(fù)雜化

系統(tǒng)不能長(zhǎng)時(shí)間關(guān)中斷運(yùn)行,因此內(nèi)核應(yīng)盡可能快的處理完中斷請(qǐng)求,盡其所能把更多的處理向后推遲內(nèi)核把中斷處理分為兩部分:上半部(tophalf)和下半部(bottomhalf),上半部?jī)?nèi)核立即執(zhí)行,而下半部留著稍后處理

中斷的下半部處理機(jī)制

中斷描述符表(IDT):即中斷向量表,每個(gè)中斷占據(jù)一個(gè)表項(xiàng)中斷描述符表調(diào)用過程指令CALL:CALL過程名調(diào)用中斷過程的指令I(lǐng)NT

INT中斷向量中斷返回指

令I(lǐng)RETIRET

加載中斷描述符表的指令LIDT

LIDT48位的偽描述符相關(guān)匯編指令

Linux內(nèi)核在系統(tǒng)的初始化階段要初始化可編程控制器8259A;將中斷描述符表的起始地址裝入IDTR寄存器,并初始化表中的每一項(xiàng)

當(dāng)計(jì)算機(jī)運(yùn)行在實(shí)模式時(shí),中斷描述符表被初始化,

并由BIOS使用。真正進(jìn)入了Linux內(nèi)核,中斷描述符表就被移到內(nèi)存的另一個(gè)區(qū)域,

并為進(jìn)入保護(hù)模式進(jìn)行預(yù)初始化

初始化中斷描述符表IDT表項(xiàng)的設(shè)置通過_set_gaet()函數(shù)實(shí)現(xiàn)

調(diào)用該函數(shù)在IDT表中插入一個(gè)中斷門:set_intr_gate(unsignedintn,void*addr)

調(diào)用該函數(shù)在IDT表中插入一個(gè)陷阱門:set_trap_gate(unsignedintn,void*addr)調(diào)用該函數(shù)在IDT表中插入一個(gè)系統(tǒng)門:set_system_gate(unsignedintn,void*addr)

IDT表項(xiàng)的設(shè)置trap_init()函數(shù)用

于設(shè)置中斷描述符表開頭的19個(gè)陷阱

門和系統(tǒng)門這些中斷向量都

是CPU保留用于異常處理的,例:set_trap_gate(0,÷_error);set_trap_gate(1,&debug);set_trap_gate(19,&simd_coprocessor_error);set_system_gate(SYSCALL_VECTOR,&system_call);

初始化陷阱門和系統(tǒng)門中斷門的設(shè)置是由init_IRQ()函數(shù)中的一段代碼完成的:設(shè)置時(shí)必須跳過用于系統(tǒng)調(diào)用的向量0x80

中斷處理程序的入口地址是一個(gè)數(shù)組interrupt[],數(shù)組中的每個(gè)元素是指向中斷處理函數(shù)的指針。

中斷門的設(shè)置

for(i=0;i<NR_IRQS;i++){intvector=FIRST_EXTERNAL_VECTOR+i;if(vector!=SYSCALL_VECTOR)set_intr_gate(vector,interrupt[i]);}小任務(wù)是指待處理的下半部,其數(shù)據(jù)結(jié)構(gòu)為tasklet_struct,每個(gè)結(jié)構(gòu)代表一個(gè)獨(dú)立的小任務(wù)小任務(wù)既可以靜態(tài)地創(chuàng)建,也可以動(dòng)態(tài)地創(chuàng)建

小任務(wù)機(jī)制

structtasklet_struct{Structtasklet_struct*next;unsignedlongstate;atomic_tcount; void(*func)(unsignedlong);unsignedlongdata; };

voidtasklet_handler(unsignedlongdata)小任務(wù)不能睡眠,不能在小任務(wù)中使用信號(hào)量或者其它產(chǎn)生阻塞的函數(shù)。但它運(yùn)行時(shí)可以響應(yīng)中斷

通過調(diào)用tasklet_schedule()函數(shù)并傳遞給它相應(yīng)的tasklet_struct指針,該小任務(wù)就會(huì)被調(diào)度以便適當(dāng)?shù)臅r(shí)候執(zhí)行: tasklet_schedule(&my_tasklet)

在小任務(wù)被調(diào)度以后,只要有機(jī)會(huì)它就會(huì)盡可能早的運(yùn)行

編寫并調(diào)度自己的小任務(wù)下半部是一個(gè)不能與其他下半部并發(fā)執(zhí)行的高優(yōu)先級(jí)小任務(wù)

bh_base是一個(gè)指向下半部的指針數(shù)組,用于組織

所有下半部

bh_base數(shù)組共有32項(xiàng),每一項(xiàng)都是一種下半部下半部

下半部外部設(shè)備TIMER_BH定時(shí)器TQUEUE_BH

周期性任務(wù)隊(duì)列SERIAL_BH

串行端口IMMEDIATE_BH

立即任務(wù)隊(duì)列Linux常用的下半部任務(wù)隊(duì)列就是指以雙向隊(duì)列形式連接起來(lái)的任務(wù)鏈表,每一個(gè)鏈表元素都描述了一個(gè)可執(zhí)行的內(nèi)核任務(wù)

三個(gè)特殊的任務(wù)隊(duì)列:tq_immediate任務(wù)隊(duì)列,由IMMEDIATE_BH下半部運(yùn)行,該隊(duì)列中包括要執(zhí)行的內(nèi)核函數(shù)和標(biāo)準(zhǔn)的下半部。

tq_timer任務(wù)隊(duì)列,由TQUEUE_BH下半部運(yùn)行,每次時(shí)鐘中斷都激活這個(gè)下半部。tq_disk任務(wù)隊(duì)列,用于塊設(shè)備任務(wù)。任務(wù)隊(duì)列

大部分PC機(jī)中有兩個(gè)時(shí)鐘源,分別是實(shí)時(shí)時(shí)鐘(RTC)和操作系統(tǒng)(OS)時(shí)鐘實(shí)時(shí)時(shí)鐘也叫硬件時(shí)鐘,它靠電池供電,即使系統(tǒng)斷電,也可以維持日期和時(shí)間。RTC和OS時(shí)鐘之間的關(guān)系通常也被稱作操作系統(tǒng)的時(shí)鐘運(yùn)作機(jī)制不同的操作系統(tǒng),其時(shí)鐘運(yùn)作機(jī)制也不同

中斷的應(yīng)用-時(shí)鐘中斷

時(shí)鐘運(yùn)作機(jī)制OS時(shí)鐘是由可編程定時(shí)/計(jì)數(shù)器產(chǎn)生的輸出脈沖觸發(fā)中斷而產(chǎn)生的操作系統(tǒng)的“時(shí)間基準(zhǔn)”由設(shè)計(jì)者決定,Linux的時(shí)間基準(zhǔn)是1970年1月1日凌晨0點(diǎn)

OS時(shí)鐘記錄的時(shí)間就是系統(tǒng)時(shí)間。系統(tǒng)

時(shí)間以“時(shí)鐘節(jié)拍”為單位Linux中用全局變量jiffies表示系統(tǒng)自啟動(dòng)以來(lái)的時(shí)鐘節(jié)拍數(shù)目

Linux時(shí)間系統(tǒng)

每一次時(shí)鐘中斷的產(chǎn)生都觸發(fā)下列幾個(gè)主要的操作:自系統(tǒng)啟動(dòng)以來(lái)所花費(fèi)的時(shí)間更新時(shí)間和日期

確定當(dāng)前進(jìn)程在CPU上已運(yùn)行了多長(zhǎng)時(shí)

間,如果已經(jīng)超過了分配給它的時(shí)間,則搶占它

更新資源使用統(tǒng)計(jì)數(shù)

檢查定時(shí)器時(shí)間間隔是否已到,如果是,

則調(diào)用適當(dāng)?shù)暮瘮?shù)

時(shí)鐘中斷處理程序

timer_bh()函數(shù)與TIMER_BH下半部相關(guān)聯(lián),它在每個(gè)時(shí)鐘節(jié)拍都被激活

TIMER_BH下半部以關(guān)中斷調(diào)用update_times()函數(shù),該函數(shù)會(huì)以關(guān)中斷來(lái)更新xtime

更新了系統(tǒng)時(shí)鐘xtime之后,update_times()再次打開中斷時(shí)鐘中斷的下半部處理

定時(shí)器是管理內(nèi)核所花時(shí)間的基礎(chǔ),也被稱為動(dòng)態(tài)定時(shí)器或內(nèi)核定時(shí)器

定時(shí)器的使用:執(zhí)行一些初始化工作,設(shè)置一個(gè)到期時(shí)間,指定到時(shí)后執(zhí)行的函數(shù),然后激活定時(shí)器就可以了定時(shí)器由timer_list結(jié)構(gòu)表示

定時(shí)器及應(yīng)用

structtimer_list{structlist_headentry;unsignedlongexpires;unsignedlongdata;void(*function)(unsignedlong);};定義定時(shí)器:structtimer_listmy_timer;

初始化定時(shí)器:init_timer(&m

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論