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

歡迎訪問 生活随笔!

生活随笔

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

windows

s5pv210——中断系统相关介绍

發(fā)布時(shí)間:2023/12/20 windows 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 s5pv210——中断系统相关介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

以下內(nèi)容源于朱有鵬課程的學(xué)習(xí),如有侵權(quán),請告知?jiǎng)h除。

參考資料:http://www.cnblogs.com/biaohc/p/6354068.html





一、S5PV210的中斷體系介紹

1、什么是中斷?

  • 中斷用來解決宏觀上的并行需求
  • 微觀上的并行,指的真正的并行,就是精確到每一秒甚至每一刻,多個(gè)事情都是在同時(shí)進(jìn)行的。
  • 宏觀上的并行,并不等于微觀上的并行,有時(shí)候宏觀上是并行的,微觀上是串行的。
  • 單核CPU無法并行,但是通過中斷機(jī)制,可以實(shí)現(xiàn)假并行(宏觀上的并行,微觀上實(shí)際還是串行的)。

2、中斷的實(shí)現(xiàn)機(jī)制——異常向量表

(1)異常向量表是CPU中某些特定地址的特定定義。當(dāng)中斷發(fā)生的時(shí)候,中斷要想辦法通知CPU去處理中斷,怎么做到?依靠異常向量表。

(2)在CPU設(shè)計(jì)時(shí),事先定義了CPU中一些特定地址作為特定異常的入口地址

  • 譬如定義0x00000000地址為復(fù)位異常向量地址,則發(fā)生復(fù)位異常時(shí)CPU會(huì)自動(dòng)跳轉(zhuǎn)到0x00000000地址去執(zhí)行指令。
  • 譬如外部中斷對應(yīng)的異常向量地址為0x30000008,則發(fā)生外部中斷后,CPU會(huì)硬件自動(dòng)跳轉(zhuǎn)到0x30000008地址去執(zhí)行指令。
(3)以上講的是CPU硬件設(shè)計(jì)時(shí)對異常向量表的支持,下來就需要軟件支持了。

  • 硬件決定發(fā)生什么異常時(shí),CPU自動(dòng)跳轉(zhuǎn)PC到哪個(gè)地址去執(zhí)行;
  • 軟件把處理這個(gè)異常的代碼的首地址填入這個(gè)異常向量地址。

3、S5PV210的異常向量表

  • 異常向量表中各個(gè)向量的相對位置是固定的,但是起始地址是不固定的,各種SoC可以不一樣。
  • 復(fù)雜ARM中還可以讓用戶來軟件設(shè)置異常向量表的基地址。
  • 所有架構(gòu)(譬如51單片機(jī)、PIC單片機(jī))的CPU的中斷,都是通過異常向量表實(shí)現(xiàn)的,但是不同CPU異常向量表的構(gòu)造和位置是不同的。

4、異常和中斷的區(qū)別和聯(lián)系

(1)對SoC來說,發(fā)生復(fù)位、軟中斷、中斷、快速中斷、取指令異常、數(shù)據(jù)異常等,我們都統(tǒng)一叫異常。因此,中斷其實(shí)是異常的一種。

(2)異常的定義就是突發(fā)事件,打斷了CPU的正常常規(guī)業(yè)務(wù),CPU不得不跳轉(zhuǎn)到異常向量表中去執(zhí)行異常處理程序。

  • 中斷是異常的一種,一般特指SoC內(nèi)的內(nèi)部外設(shè)產(chǎn)生的打斷SoC常規(guī)業(yè)務(wù),或者外部中斷(SoC的GPIO引腳傳回來的中斷)。

二、異常向量表的編程處理

1、像內(nèi)存一樣去訪問異常向量表




  • S5PV210的異常向量表可以改變(在CP15協(xié)處理器中),以適應(yīng)操作系統(tǒng)的需求。
  • 但是系統(tǒng)剛啟動(dòng)時(shí),DRAM尚未初始化,程序都在SRAM中運(yùn)行。210在iRAM中設(shè)置了異常向量表,供暫時(shí)性使用。
  • 查閱iRAM的地址分配,可知,iRAM中的異常向量表起始地址為0xD0037400。

2、函數(shù)名的實(shí)質(zhì)就是函數(shù)的首地址

(1)編譯器把函數(shù)體對應(yīng)的代碼段和這個(gè)函數(shù)的函數(shù)名(實(shí)質(zhì)是符號(hào))對應(yīng)起來

  • 當(dāng)使用這個(gè)函數(shù)名符號(hào)時(shí),編譯器會(huì)將函數(shù)的函數(shù)體實(shí)際上做替換。因?yàn)楹瘮?shù)體都不止4字節(jié),而函數(shù)名這個(gè)符號(hào)只能對應(yīng)1個(gè)地址,所以實(shí)際對應(yīng)的是函數(shù)體那一個(gè)代碼段的首地址。
  • 拿C語言中的語法來講,函數(shù)名就是這個(gè)函數(shù)的函數(shù)指針。

(2)將異常處理程序的首地址和異常向量表綁定后,異常處理初步階段就完成了。

到目前可以保證相應(yīng)異常發(fā)生后,硬件自動(dòng)跳轉(zhuǎn)到對應(yīng)異常向量表入口去執(zhí)行時(shí),可以執(zhí)行到我們事先綁定的函數(shù)。


3、為什么中斷處理要先在匯編中進(jìn)行

(1)中斷處理,需要保護(hù)現(xiàn)場和恢復(fù)現(xiàn)場

  • 比如中斷從SVC模式來,則保存SVC模式下的必要寄存器的值;
  • 中斷處理完成后,準(zhǔn)備返回SVC模式前,要將相關(guān)寄存器的值恢復(fù)回去,否則到了SVC模式后寄存器的值亂了,SVC模式下原來正在進(jìn)行的常規(guī)任務(wù)將會(huì)被破壞。

(2)保存現(xiàn)場

  • 第一,設(shè)置IRQ棧;
  • 第二,保存LR;
  • 第三,保存R0~R12;

(3)為什么要保存LR寄存器?

  • 要考慮中斷返回的問題,即中斷ISR執(zhí)行完后如何返回SVC模式下去接著執(zhí)行原來的代碼。
  • 中斷返回其實(shí)取決于我們進(jìn)入中斷時(shí)如何保存現(xiàn)場。
  • 中斷返回時(shí)關(guān)鍵的2個(gè)寄存器就是PC和CPSR。
  • 在進(jìn)入IRQ模式時(shí),應(yīng)該將SVC模式下的下一句指令的地址(中斷返回地址)和CPSR保存起來,將來恢復(fù)時(shí)才可以將中斷返回地址給PC,將保存的CPSR給CPSR。
  • 中斷返回地址保存在LR中,而CPSR(自動(dòng))保存在(IRQ模式下的)SPSR中。
  • 見博客http://blog.csdn.net/oqqhutu12345678/article/details/71215628

(3)保護(hù)現(xiàn)場關(guān)鍵是保存:中斷處理程序的返回地址,r0-r12(cpsr是自動(dòng)保存的);

(4)恢復(fù)現(xiàn)場主要是恢復(fù):r0-r12,pc,cpsr

三、S5PV210的向量中斷控制器

1、異常處理的2個(gè)階段

  • 第一個(gè)階段是異常向量表跳轉(zhuǎn);
  • 第二個(gè)階段是進(jìn)入真正的異常處理程序。

2、中斷處理的第一階段(異常向量表階段)處理。

  • 第一個(gè)階段主要依賴CPU設(shè)計(jì)時(shí)提供的異常向量表機(jī)制,主要任務(wù)是從異常發(fā)生到響應(yīng)異常并且保存/恢復(fù)現(xiàn)場、跳轉(zhuǎn)到真正的異常處理程序處。
  • 第二個(gè)階段的目的是識(shí)別多個(gè)中斷源中究竟哪一個(gè)發(fā)生了中斷,然后調(diào)用相應(yīng)的中斷處理程序來處理這個(gè)中斷。

3、S3C2440的第二階段處理過程

(1)怎么找到具體是哪個(gè)中斷?

  • S3C2440的中斷控制器中有一個(gè)寄存器(32位的),寄存器的每一個(gè)位對應(yīng)一個(gè)中斷源(為了解決支持更多中斷源,2440又設(shè)計(jì)了一個(gè)子中斷機(jī)制。在一級(jí)中斷寄存器中有一些中斷是共用的一個(gè)bit位,譬如AC97和WDT。對于共用中斷,用子中斷來區(qū)分究竟是哪一個(gè)發(fā)生了中斷)

(2)怎么找到對應(yīng)的isr?

  • 首先給每個(gè)中斷做了個(gè)編號(hào),進(jìn)入isr_handler之后先通過查閱中斷源寄存器和子中斷寄存器(中哪一位為1)確定中斷的編號(hào),然后用這個(gè)編號(hào)去isr數(shù)組(isr數(shù)組是中斷初始化時(shí)事先設(shè)定好的,就是把各個(gè)中斷的isr的函數(shù)名組成一個(gè)數(shù)組,用中斷對應(yīng)的編號(hào)作為索引來查詢這個(gè)數(shù)組)中查閱得到isr地址。

評價(jià):第一個(gè)過程中使用子中斷搞成2級(jí)的很麻煩;第二個(gè)過程中計(jì)算中斷編號(hào)是個(gè)麻煩事,很耗費(fèi)時(shí)間。而中斷處理的時(shí)間是很寶貴的(系統(tǒng)有一個(gè)性能指標(biāo),叫實(shí)時(shí)性。實(shí)時(shí)性就是中斷發(fā)生到響應(yīng)的時(shí)間,這個(gè)時(shí)間越短越好。)

4、S5PV210的第二階段處理過程

(1)怎么找到具體是哪個(gè)中斷?

  • S5PV210中因?yàn)橹С值闹袛嘣春芏?#xff0c;所以直接設(shè)計(jì)了4個(gè)中斷寄存器,每個(gè)32位,每位對應(yīng)一個(gè)中斷源。
  • 理論上210最多支持128個(gè)中斷,實(shí)際支持不足128個(gè),有些位是空的;見博客http://blog.csdn.net/oqqhutu12345678/article/details/71747613。
  • 210沒有子中斷寄存器,每個(gè)中斷源都是并列的。
  • 當(dāng)中斷發(fā)生時(shí),在irq_handler中依次去查詢4個(gè)中斷源寄存器,看哪一個(gè)中斷源寄存器的哪一位被置1,則這個(gè)位對應(yīng)的寄存器就發(fā)生了中斷,即找到了中斷編號(hào)。

(2)怎么找到對應(yīng)的isr?

  • 210中支持的中斷源多了很多,如果還使用2440的那一套來尋找isr地址就太慢了,太影響實(shí)時(shí)性了。于是210開拓了一種全新的尋找isr的機(jī)制。210提供了很多寄存器來解決每個(gè)中斷源對應(yīng)isr的尋找問題,具體尋找過程和建立過程見下節(jié),實(shí)現(xiàn)的效果是當(dāng)發(fā)生相應(yīng)中斷時(shí),硬件會(huì)自動(dòng)的將相應(yīng)isr推入一定的寄存器中,我們軟件只要去這個(gè)寄存器中執(zhí)行函數(shù)就行了。

5、總結(jié):第一階段都相同,第二階段各不同

  • 第一階段(異常向量表階段)2440和210幾乎是完全相同的。實(shí)際上幾乎所有的CPU在第一階段都是相同的。
  • 第二階段彼此不同。各個(gè)SoC根據(jù)自己對實(shí)時(shí)性的要求,和支持的中斷源的多少,發(fā)明了各自處理中斷,找到中斷編號(hào),進(jìn)一步找到對應(yīng)isr地址的方式。

四、S5PV210中斷處理的主要寄存器

1、VICnINTENABLE、VICnINTENCLEAR


(1)VICnINTENABLE寄存器負(fù)責(zé)相應(yīng)的中斷的使能,VICnINTENCLEAR寄存器負(fù)責(zé)相應(yīng)的中斷的禁止。

  • 啟用(即當(dāng)硬件產(chǎn)生中斷時(shí)CPU能接收的到)某個(gè)中斷時(shí),需要在此中斷編號(hào)對應(yīng)的VICnINTENABLE的相應(yīng)bit位寫1;
  • 禁止某個(gè)中斷源時(shí),需要向VICnINTENCLEAR中相應(yīng)的位寫1;
  • 有些CPU是中斷使能和禁止是一個(gè)寄存器位,寫1就使能寫0就禁止(或者反過來寫1就進(jìn)制寫0就使能);
  • 有些CPU是使能和禁止分開為2個(gè)寄存器,要使能就寫使能寄存器,要禁止就寫禁止寄存器。

(2)這里的n=0,1,2,3共四個(gè)寄存器,每個(gè)寄存器都是32bit,每個(gè)bit對應(yīng)一個(gè)中斷源是否使能 。?

  • VIC0INTENABLE ?VIC0INTCLEAR;
  • VIC1INTENABLE ?VIC1INTCLEAR
  • VIC2INTENABLE ?VIC2INTCLEAR
  • VIC3INTENABLE ?VIC3INTCLEAR

(3)例如下面的代碼

// 使能中斷 // 通過傳參的intnum來使能某個(gè)具體的中斷源,中斷號(hào)在int.h中定義,是物理中斷號(hào) void intc_enable(unsigned long intnum) {unsigned long temp;// 確定intnum在哪個(gè)寄存器的哪一位// <32就是0~31,必然在VIC0if(intnum<32){temp = VIC0INTENABLE;temp |= (1<<intnum); // 如果是第一種設(shè)計(jì)則必須位操作,第二種設(shè)計(jì)可以// 直接寫。VIC0INTENABLE = temp;}else if(intnum<64){temp = VIC1INTENABLE;temp |= (1<<(intnum-32));VIC1INTENABLE = temp;}else if(intnum<96){temp = VIC2INTENABLE;temp |= (1<<(intnum-64));VIC2INTENABLE = temp;}else if(intnum<NUM_ALL){temp = VIC3INTENABLE;temp |= (1<<(intnum-96));VIC3INTENABLE = temp;}// NUM_ALL : enable all interruptelse{VIC0INTENABLE = 0xFFFFFFFF;VIC1INTENABLE = 0xFFFFFFFF;VIC2INTENABLE = 0xFFFFFFFF;VIC3INTENABLE = 0xFFFFFFFF;}}

// 禁止中斷 // 通過傳參的intnum來禁止某個(gè)具體的中斷源,中斷號(hào)在int.h中定義,是物理中斷號(hào) void intc_disable(unsigned long intnum) {unsigned long temp;if(intnum<32){temp = VIC0INTENCLEAR;temp |= (1<<intnum);VIC0INTENCLEAR = temp;}else if(intnum<64){temp = VIC1INTENCLEAR;temp |= (1<<(intnum-32));VIC1INTENCLEAR = temp;}else if(intnum<96){temp = VIC2INTENCLEAR;temp |= (1<<(intnum-64));VIC2INTENCLEAR = temp;}else if(intnum<NUM_ALL){temp = VIC3INTENCLEAR;temp |= (1<<(intnum-96));VIC3INTENCLEAR = temp;}// NUM_ALL : disable all interruptelse{VIC0INTENCLEAR = 0xFFFFFFFF;VIC1INTENCLEAR = 0xFFFFFFFF;VIC2INTENCLEAR = 0xFFFFFFFF;VIC3INTENCLEAR = 0xFFFFFFFF;}return; }


2、VICnINTSELECT寄存器


(1)設(shè)置各個(gè)中斷的模式為irq還是fiq。一般都設(shè)置成irq。

(2)IRQ和FIQ究竟有何區(qū)別?

  • 210中支持2種中斷,irq和fiq。irq是普通中斷,fiq是快速中斷。
  • 快速中斷提供一種更快響應(yīng)處理的中斷通道,用于對實(shí)時(shí)性要求很高的中斷源。
  • fiq在CPU設(shè)計(jì)時(shí)預(yù)先提供了一些機(jī)制保證fiq可以被快速處理,從而保證實(shí)時(shí)性。
  • fiq的限制就是只能有一個(gè)中斷源被設(shè)置為fiq,其他都是irq。

(3)CPU如何保證fiq比irq快?

  • 第一,fiq模式有專用的r8~r12,因此在fiq的isr中可以直接使用r8-r12而不用保存,這就能節(jié)省時(shí)間;
  • 第二,異常向量表中fiq是最后一個(gè)異常向量入口。因此fiq的isr不需要跳轉(zhuǎn),可以直接寫在原地,這樣就比其他異常少跳轉(zhuǎn)一次,省了些時(shí)間。

(4)這里的n=0,1,2,3共四個(gè)寄存器,可以設(shè)置各個(gè)中斷的模式。

  • VIC0INTSELECT,VIC1INTSELECT,VIC2INTSELECT,VIC3INTSELECT。

(5)代碼

// 清除需要處理的中斷的中斷處理函數(shù)的地址 void intc_clearvectaddr(void) {// VICxADDR:當(dāng)前正在處理的中斷的中斷處理函數(shù)的地址(即isr的入口地址,見3的代碼示例)VIC0ADDR = 0;VIC1ADDR = 0;VIC2ADDR = 0;VIC3ADDR = 0; }// 初始化中斷控制器 void intc_init(void) {// 禁止所有中斷// 為什么在中斷初始化之初要禁止所有中斷?// 因?yàn)橹袛嘁坏┐蜷_,因?yàn)橥獠炕蛘哂布约旱脑虍a(chǎn)生中斷后一定就會(huì)尋找isr// 而我們可能認(rèn)為自己用不到這個(gè)中斷就沒有提供isr,這時(shí)它自動(dòng)拿到的就是亂碼// 則程序很可能跑飛,所以不用的中斷一定要關(guān)掉。// 一般的做法是先全部關(guān)掉,然后再逐一打開自己感興趣的中斷。一旦打開就必須// 給這個(gè)中斷提供相應(yīng)的isr并綁定好。VIC0INTENCLEAR = 0xffffffff;VIC1INTENCLEAR = 0xffffffff;VIC2INTENCLEAR = 0xffffffff;VIC3INTENCLEAR = 0xffffffff;// 這里把所有的中斷源的中斷類型設(shè)置為IRQ;其實(shí)可以具體到設(shè)置每一個(gè)中斷的中斷模式 VIC0INTSELECT = 0x0;VIC1INTSELECT = 0x0;VIC2INTSELECT = 0x0;VIC3INTSELECT = 0x0;// 清VICxADDRintc_clearvectaddr(); }


3、VICnIRQSTATUS、VICnFIQSTATUS



(1)中斷狀態(tài)寄存器
  • 該寄存器是只讀的。
  • 當(dāng)發(fā)生了中斷時(shí),硬件會(huì)自動(dòng)將該寄存器的對應(yīng)位置為1,表示中斷發(fā)生了。
  • 軟件在處理中斷第二階段的第一階段,就是靠查詢這個(gè)寄存器來得到中斷編號(hào)的。
  • 有四個(gè):VIC0IRQSTATUS,VIC1IRQSTATUS,VIC2IRQSTATUS,VIC3IRQSTATUS。

(2)代碼示例

// 通過讀取VICnIRQSTATUS寄存器,判斷其中哪個(gè)有一位為1,來得知哪個(gè)VIC發(fā)生中斷了 unsigned long intc_getvicirqstatus(unsigned long ucontroller) {if(ucontroller == 0)return VIC0IRQSTATUS;else if(ucontroller == 1)return VIC1IRQSTATUS;else if(ucontroller == 2)return VIC2IRQSTATUS;else if(ucontroller == 3)return VIC3IRQSTATUS;else{}return 0; }// 真正的中斷處理程序。意思就是說這里只考慮中斷處理,不考慮保護(hù)/恢復(fù)現(xiàn)場 void irq_handler(void) {//printf("irq_handler.\n");// SoC支持很多個(gè)(在低端CPU例如2440中有30多個(gè),在210中有100多個(gè))中斷// 這么多中斷irq在第一個(gè)階段走的是一條路,都會(huì)進(jìn)入到irq_handler來// 我們在irq_handler中要去區(qū)分究竟是哪個(gè)中斷發(fā)生了,然后再去調(diào)用該中斷// 對應(yīng)的isr。// 雖然硬件已經(jīng)自動(dòng)幫我們把isr放入了VICnADDRESS中,但是因?yàn)橛?個(gè),所以我們必須// 先去軟件的檢查出來到底哪個(gè)VIC中斷了,也就是說isr到底在哪個(gè)VICnADDRESS寄存器中unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};int i=0;void (*isr)(void) = NULL;for(i=0; i<4; i++){// 發(fā)生一個(gè)中斷時(shí),4個(gè)VIC中有3個(gè)是全0,1個(gè)的其中一位不是0if(intc_getvicirqstatus(i) != 0){isr = (void (*)(void)) vicaddr[i];break;}}(*isr)(); // 通過函數(shù)指針來調(diào)用函數(shù) }


4、VICnVECTPRIORITY0~VICnVECTPRIORITY31寄存器

  • 中斷優(yōu)先級(jí)設(shè)置寄存器,設(shè)置多個(gè)中斷同時(shí)發(fā)生時(shí)先處理誰后處理誰的問題。
  • 一般來說高優(yōu)先級(jí)的中斷可以打斷低優(yōu)先級(jí)的中斷,從而嵌套處理中斷。

5、VICnVECTADDR0~VICnVECTADDR31寄存器


(1)這些寄存器和210中斷處理第二階段的第二階段有關(guān)。

(2)VICnVECTADDR0~31這32個(gè)寄存器。

  • 分別用來存放真正的各個(gè)中斷對應(yīng)的isr的函數(shù)地址。即中斷處理函數(shù)的存放地址。
  • 相當(dāng)于每一個(gè)中斷源都有一個(gè)VECTADDR寄存器,程序員在設(shè)置中斷的時(shí)候,把這個(gè)中斷的isr地址直接放入這個(gè)中斷對應(yīng)的VECTADDR寄存器即可。
  • n=0,1,2,3;
(3)代碼 // 綁定我們寫的isr到VICnVECTADDR寄存器 // 綁定過之后我們就把isr地址交給硬件了,剩下的我們不用管了,硬件自己會(huì)處理 // 等發(fā)生相應(yīng)中斷的時(shí)候,我們直接到相應(yīng)的VICnADDR中去取isr地址即可。 // 參數(shù):intnum是int.h定義的物理中斷號(hào),handler是函數(shù)指針,就是我們寫的isr// VIC0VECTADDR定義為VIC0VECTADDR0寄存器的地址,就相當(dāng)于是VIC0VECTADDR0~31這個(gè) // 數(shù)組(這個(gè)數(shù)組就是一個(gè)函數(shù)指針數(shù)組)的首地址,然后具體計(jì)算每一個(gè)中斷的時(shí)候 // 只需要首地址+偏移量即可。 void intc_setvectaddr(unsigned long intnum, void (*handler)(void)) {//VIC0if(intnum<32){*( (volatile unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;}//VIC1else if(intnum<64){*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;}//VIC2else if(intnum<96){*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;}//VIC3else{*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;}return; }

6、VICnADDRESS寄存器


  • 內(nèi)容由硬件自動(dòng)設(shè)置。當(dāng)發(fā)生中斷時(shí),硬件自動(dòng)識(shí)別中斷編號(hào),并且自動(dòng)找到這個(gè)中斷的VECTADDR寄存器,把寄存器的內(nèi)容復(fù)制到VICADDRESS中,以供使用。
  • 這樣的設(shè)計(jì)避免了軟件查找中斷源和isr,節(jié)省了時(shí)間,提高了210的中斷響應(yīng)速度。
// 真正的中斷處理程序。意思就是說這里只考慮中斷處理,不考慮保護(hù)/恢復(fù)現(xiàn)場 void irq_handler(void) {//printf("irq_handler.\n");// SoC支持很多個(gè)(在低端CPU例如2440中有30多個(gè),在210中有100多個(gè))中斷// 這么多中斷irq在第一個(gè)階段走的是一條路,都會(huì)進(jìn)入到irq_handler來// 我們在irq_handler中要去區(qū)分究竟是哪個(gè)中斷發(fā)生了,然后再去調(diào)用該中斷// 對應(yīng)的isr。(函數(shù)指針)// 雖然硬件已經(jīng)自動(dòng)幫我們把isr放入了VICnADDR中,但是因?yàn)橛?個(gè),所以我們必須// 先去軟件的檢查出來到底哪個(gè)VIC中斷了,也就是說isr到底在哪個(gè)VICADDR寄存器中unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};int i=0;void (*isr)(void) = NULL;for(i=0; i<4; i++){// 發(fā)生一個(gè)中斷時(shí),4個(gè)VIC中有3個(gè)是全0,1個(gè)的其中一位不是0if(intc_getvicirqstatus(i) != 0){isr = (void (*)(void)) vicaddr[i];break;}}(*isr)(); // 通過函數(shù)指針來調(diào)用函數(shù) }

五、總結(jié)

整個(gè)中斷過程可以分為兩部分
第一部分是我們?yōu)橹袛囗憫?yīng)而做的預(yù)備工作:
  • 初始化中斷控制器
  • ?綁定寫好的isr到中斷控制器
  • 相應(yīng)中斷的所有條件使能
第二部分是當(dāng)硬件產(chǎn)生中斷后如何自動(dòng)執(zhí)行isr:
  • 第一步,經(jīng)過異常向量表跳轉(zhuǎn)入IRQ/FIQ的入口(IRQ_handl:
  • 第二步,做中斷現(xiàn)場保護(hù)(在start.S中),然后跳入isr_handler
  • 第三步,在isr_handler中先去搞清楚是哪個(gè)VIC中斷了,然后直接去這個(gè)VIC的ADDR寄存器中取isr來執(zhí)行即可
  • 第四步,isr執(zhí)行完,中斷現(xiàn)場恢復(fù),直接返回繼續(xù)做常規(guī)任務(wù)。


總結(jié)

以上是生活随笔為你收集整理的s5pv210——中断系统相关介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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