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

歡迎訪問 生活随笔!

生活随笔

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

windows

TQ2440中断系统

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

1.1?? S3C2440系統(tǒng)中斷

CPU和外設(shè)構(gòu)成了計(jì)算機(jī)系統(tǒng),CPU和外設(shè)之間通過總線進(jìn)行連接,用于數(shù)據(jù)通信和控制,CPU管理監(jiān)視計(jì)算機(jī)系統(tǒng)中所有硬件,通常以兩種方式來對(duì)硬件進(jìn)行管理監(jiān)視:

  • ? 查詢方式:CPU不停的去查詢每一個(gè)硬件的當(dāng)前狀態(tài),根據(jù)硬件的狀態(tài)決定處理與否。好比是工廠里的檢查員,不停的檢查各個(gè)崗位工作狀態(tài),發(fā)現(xiàn)情況及時(shí)處 理。這種方式實(shí)現(xiàn)起來簡(jiǎn)單,通常用在只有少量外設(shè)硬件的系統(tǒng)中,如果一個(gè)計(jì)算機(jī)系統(tǒng)中有很多硬件,這種方式無(wú)疑是耗時(shí),低效的,同時(shí)還大量占用CPU資 源,并且對(duì)多任務(wù)系統(tǒng)反應(yīng)遲鈍。
  • ? 中斷方式:當(dāng)某個(gè)硬件產(chǎn)生需要CPU處理的事件時(shí),主動(dòng)通過一根信號(hào)線“告知”CPU,同時(shí)設(shè)置某個(gè)寄存器里對(duì)應(yīng)的位,CPU一旦發(fā)現(xiàn)這根信號(hào)線上的電平 有變化,就會(huì)中斷當(dāng)前程序,然后去處理發(fā)出該中斷請(qǐng)求。這就像是醫(yī)院重危病房,病房每張病床床頭有一個(gè)應(yīng)急按鈕,該按鈕連接到病房監(jiān)控室里控制臺(tái)一盞指示 燈,只要該張病床出現(xiàn)緊急情況病人按下按鈕,病房監(jiān)控室里電鈴會(huì)響起,通知醫(yī)護(hù)人員有緊急情況,醫(yī)護(hù)人員這時(shí)查看控制臺(tái)上的指示燈,找出具體病房,病床 號(hào),直接過去處理緊急情況。中斷處理方式相對(duì)查詢方式要復(fù)雜的多,并且需要硬件的支持,但是它處理的實(shí)時(shí)性更高,嵌入式系統(tǒng)里基本上都使用這種方式來處 理。

系統(tǒng)中斷是嵌入式硬件實(shí)時(shí)地處理內(nèi)部或外部事件的一種機(jī)制。對(duì)于不同CPU而言,中斷的處理只是細(xì)節(jié)不同,大體處理流程都一樣,S3C2440A的中斷控制器結(jié)構(gòu)如下圖所示:

圖3-3 S3C2440中斷控制器

  中斷請(qǐng)求由硬件產(chǎn)生,根據(jù)中斷源類型分別將中斷信號(hào)送到SUBSRCPND(SubSourcePending)和 SRCPND(SourcePending)寄存器,SUBSRCPND是子中斷源暫存寄存器,用來保存子中斷源信號(hào),SRCPND是中斷源暫存寄存器, 用來保存中斷源信號(hào)。中斷信號(hào)可通過編程方式屏蔽掉,SUBMASK是子中斷源屏蔽寄存器,可以屏蔽指定的子中斷信號(hào), MASK功能同SUBMASK用來屏蔽中斷源信號(hào)。中斷分為兩種模式:一般中斷的和快速中斷,MODE是中斷模式判斷寄存器,用來判斷當(dāng)前中斷是否為快速 中斷,如果為快速中斷直接將快速中斷信號(hào)送給ARM內(nèi)核,如果不是快速中斷,還要將中斷信號(hào)進(jìn)行仲裁選擇。S3C2440A支持多達(dá)60種中斷,很有可能 多個(gè)硬件同時(shí)產(chǎn)生中斷請(qǐng)求,這時(shí)要求中斷控制器做出裁決,Priority是中斷源優(yōu)先級(jí)仲裁選擇器,當(dāng)多個(gè)中斷產(chǎn)生時(shí),選擇出優(yōu)先級(jí)最高的中斷源進(jìn)行處 理,INTPND是中斷源結(jié)果寄存器,里面存放優(yōu)先級(jí)仲裁出的唯一中斷源。

1? 中斷的產(chǎn)生-中斷源

  S3C2440A支持60種中斷源,基本上滿足了開發(fā)板內(nèi)部,外部設(shè)備等對(duì)中斷的需求。其中每一個(gè)中斷源對(duì)應(yīng)寄存器中的一位,顯然要支持60種中斷 至少需要二個(gè)32位寄存器,SUBSRCPND和SRCPND分別保存中斷源信號(hào)。S3C2440A對(duì)60種中斷源的管理是按層級(jí)分的。如圖3-4所示:

?

圖3-4中斷源信號(hào)復(fù)合示意圖

  S3C2440A將中斷源分為兩級(jí):中斷源和子中斷源,中斷源里包含單一中斷源和復(fù)合中斷源,復(fù)合中斷源是子中斷源的復(fù)合信號(hào)。如實(shí)時(shí)時(shí)鐘中斷,該 硬件只會(huì)產(chǎn)生一種中斷,它是單一中斷源,直接將其中斷信號(hào)線連接到中斷源寄存器上。對(duì)于復(fù)合中斷源,以UART串口為例進(jìn)行說明,S3C2440A可以支 持3個(gè)UART串口,每個(gè)串口對(duì)應(yīng)一個(gè)復(fù)合中斷源信號(hào)INT_UARTn,每個(gè)串口可以產(chǎn)生三種中斷,也就是三個(gè)子中斷:接收數(shù)據(jù)中斷INT_RXDn, 發(fā)送數(shù)據(jù)中斷INT_TXDn,數(shù)據(jù)錯(cuò)誤中斷INT_ERRn,這三個(gè)子中斷信號(hào)在中斷源寄存器復(fù)合為一個(gè)中斷信號(hào),三種中斷任何一個(gè)產(chǎn)生都會(huì)將中斷信號(hào) 傳遞給對(duì)應(yīng)的中斷源INT_UARTn,然后通過中斷信號(hào)線傳遞給ARM內(nèi)核。

?

圖3-5 UART串口中斷源信號(hào)復(fù)合示意圖

總中斷源詳下面表中列出了S3C2440A部分中斷源,它分別對(duì)應(yīng)中斷源寄存器里某個(gè)位:詳細(xì)中斷源請(qǐng)查看S3C2440A硬件手冊(cè)。

表3-5 部分中斷源信號(hào)

中斷源

描述

優(yōu)先級(jí)仲裁分組

INT_ADC

數(shù)模轉(zhuǎn)換和觸摸屏中斷

ARB5

INT_RTC

實(shí)時(shí)時(shí)鐘中斷

ARB5

INT_UART0

UART0中斷(包含子中斷)

ARB5

INT_NFCON

NandFlash控制中斷

ARB4

INT_WDT_AC97

看門狗中斷

ARB1

EINT8-23

外部中斷8~23(包含外部子中斷)

ARB1

EINT4-7

外部中斷4~7(包含外部子中斷)

ARB1

EINT3

外部中斷3

ARB0

EINT2

外部中斷2

ARB0

EINT1

外部中斷1

ARB0

EINT 0

外部中斷0

ARB0

中斷信號(hào)除上述分法之外,還可以按照硬件位置分為:外部中斷源和內(nèi)部中斷源。

  • ? 內(nèi)部中斷源:它是嵌入式系統(tǒng)中常見硬件產(chǎn)生的中斷信號(hào),比如:UART串口中斷源,時(shí)鐘Timer中斷源,看門狗中斷源等
  • ? 外部中斷源:有時(shí)嵌入式系統(tǒng)里要在外部接口上掛載一些外部設(shè)備,這些設(shè)備并不是一個(gè)通用嵌入式系統(tǒng)里必備硬件,比如:藍(lán)牙模塊,各種傳感器,WIFI無(wú)線 通信模塊,這些硬件也要產(chǎn)生中斷讓CPU來處理數(shù)據(jù),因此這些外設(shè)硬件通過中斷信號(hào)線連接到中斷控制器上,它們產(chǎn)生的中斷叫做外部中斷信號(hào)。它們有著和內(nèi) 部中斷一樣的處理機(jī)制,只不過,它沒有一個(gè)固定的中斷號(hào)與之對(duì)應(yīng),硬件與嵌入式系統(tǒng)的連接方式與中斷處理完全由系統(tǒng)硬件與軟件設(shè)計(jì)者實(shí)現(xiàn)。

  外設(shè)硬件通過輸入輸出接口I/O Ports掛接到嵌入式系統(tǒng)上,I/O Ports向外設(shè)提供外部中斷信號(hào)線,輸出電源,頻率時(shí)鐘和輸入輸出信號(hào)線,外部硬件根據(jù)自己需要連接到I/O Ports上,產(chǎn)生中斷時(shí)向外部中斷信號(hào)線上送出中斷信號(hào),通過外部中斷信號(hào)線傳遞到中斷控制器。

按鍵Key可以認(rèn)為最為簡(jiǎn)單的一種硬件設(shè)備了,如下圖所示:

?

圖3-6按鍵硬件接線原理圖

  它功能很簡(jiǎn)單,可以將電路接通,按鍵K1~K6一端接地為低電平,另外一端接電源正極為高電 平,EINT8,EINT11,EINT13,EINT14,EINT15,EINT19六根中斷信號(hào)線分別和高電平端按鍵相連,當(dāng)按鍵按下時(shí)電路接通, 整個(gè)電路變成低電平,中斷信號(hào)線上電壓產(chǎn)生變化,通過設(shè)置中斷觸發(fā)方式,產(chǎn)生外部中斷請(qǐng)求,輸入到CPU內(nèi)部,從而實(shí)現(xiàn)按鍵中斷控制。

  S3C2440A可以支持EINT0~EINT23共24種外部中斷,完全可以滿足小型嵌入式設(shè)備外設(shè)硬件的需求。

  外部中斷源也分為外部中斷源和外部子中斷源,其處理方式和內(nèi)部中斷源基本一樣。

1.1.1?? 中斷優(yōu)先級(jí)

  S3C2440A支持60種中斷,多個(gè)硬件可能同時(shí)產(chǎn)生中斷請(qǐng)求,由于CPU只能處理一個(gè)中斷,中斷控制器怎么選擇出一個(gè)最佳的中斷,交給ARM內(nèi) 核進(jìn)行處理呢? 中斷控制器采用優(yōu)先級(jí)仲裁比較的方式進(jìn)行選擇,找出優(yōu)先級(jí)最高的中斷源。中斷控制器將60種中斷源分成7組,如下圖所示,它類似體育賽事里的比賽方式,所 有參賽選手在小組賽PK,選擇出小組賽最優(yōu)秀選手,然后進(jìn)入決賽階段和其它小組最優(yōu)先選擇再PK,最后優(yōu)勝者就是總冠軍。其中 ARBITER0~ARBITER5為“小組賽”階段,中斷源信號(hào)在各自小組里進(jìn)行優(yōu)先級(jí)仲裁,選擇出最高優(yōu)先級(jí)中斷信號(hào),每小組選出的中斷信號(hào)送到 ARBITER6,也就是決賽階段,選擇出最高優(yōu)先級(jí)中斷信號(hào),交給ARM內(nèi)核。

?

圖3-7 S3C2440優(yōu)先級(jí)仲裁示意圖

中斷信號(hào)在7個(gè)分組里PK時(shí)的優(yōu)先級(jí)是可編程的,通過PRIORITY寄存器進(jìn)行優(yōu)先級(jí)設(shè)置。如下表(只列出PRIORITY寄存器部分位):

表3-6 中斷優(yōu)先級(jí)控制寄存器(PRIORITY)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

PRIORITY

0x4A00000C

R/W

中斷優(yōu)先級(jí)控制寄存器

0x7F

?

PRIORITY

描述

初始值

ARB_SEL6

[20:19]

仲裁組6優(yōu)先級(jí)排序方式

00 = REQ 0-1-2-3-4-5

01 = REQ 0-2-3-4-1-5

10 = REQ 0-3-4-1-2-5

11 = REQ 0-4-1-2-3-5

0x00

ARB_SEL5

[18:17]

仲裁組5優(yōu)先級(jí)排序

00 = REQ 1-2-3-4

01 = REQ 2-3-4-1

10 = REQ 3-4-1-2

11 = REQ 4-1-2-3

00

ARB_MODE6

[6]

仲裁組6優(yōu)先級(jí)是否輪轉(zhuǎn):

0 = 不輪轉(zhuǎn),???? 1 = 輪轉(zhuǎn)

1

ARB_MODE5

[5]

仲裁組5優(yōu)先級(jí)是否輪轉(zhuǎn):

0 = 不輪轉(zhuǎn),???? 1 = 輪轉(zhuǎn)

1

  通過設(shè)置仲裁組n優(yōu)先級(jí)排序方式位,設(shè)置每個(gè)仲裁組內(nèi)中斷信號(hào)的優(yōu)先級(jí)順序,比如:ARB_SEL5分組時(shí)包含四個(gè)中斷信號(hào):REQ1 INT_UART0, REQ2 INT_SPI1, REQ3 INT_RTC, REQ4 INT_ADC,ARB_SEL5位采用默認(rèn)值:00,當(dāng)INT_UART0和INT_RTC中斷信號(hào)同時(shí)產(chǎn)生時(shí),INT_UART0會(huì)被選出,通過可編 程方式改變優(yōu)先級(jí)排序方式來改變中斷信號(hào)優(yōu)先級(jí)。

  ARB_MODE0~ ARB_MODE6為每個(gè)仲裁分組的優(yōu)先級(jí)輪轉(zhuǎn)設(shè)置位,采用默認(rèn)值時(shí),當(dāng)前中斷信號(hào)被選擇處理之后,再次產(chǎn)生中斷請(qǐng)求時(shí),它的優(yōu)先級(jí)自動(dòng)輪轉(zhuǎn)到該組最低, 這樣可以保證優(yōu)先級(jí)低的中斷信號(hào)可以被及時(shí)處理,不至于出現(xiàn)優(yōu)先級(jí)高且中斷請(qǐng)求頻繁的中斷每次都被優(yōu)先處理,而優(yōu)先級(jí)低的被“餓死”的情況。顯然,這種方 式更民主,實(shí)時(shí)性更佳。

2?? 中斷控制器相關(guān)寄存器

(1)SUBSRCPND子中斷源暫存寄存器

表3-7 子中斷源暫存寄存器(SUBSRCPND)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

SUBSRCPND

0x4A000018

R/W

子中斷源暫存寄存器,保存中斷請(qǐng)求狀態(tài):

0:沒有中斷請(qǐng)求信號(hào)

1:中斷請(qǐng)求信號(hào)產(chǎn)生

0x00000000

?

SUBSRCPND

對(duì)應(yīng)SRCPND

描述

初始值

Reserved

無(wú)

[31:15]

未使用

0

INT_AC97

INT_WDT_AC97

[14]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

INT_RXD0

INT_UART0

[0]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

該寄存器用來標(biāo)識(shí)保存子中斷源信號(hào),當(dāng)某個(gè)子中斷信號(hào)產(chǎn)生之后,SUBSRCPND對(duì)應(yīng)位被自動(dòng)置1,該位會(huì)一直保持被置位,只到中斷處理程序?qū)⑵淝宄秊橹?#xff0c;需要注意一下,清除中斷是通過向?qū)?yīng)位寫入1來清除,而不是寫入0,寫入0無(wú)效。

(2)INTSUBMSK子中斷源屏蔽寄存器

表3-8 子中斷源屏蔽寄存器(INTSUBMSK)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

INTSUBMSK

0x4A00001C

R/W

子中斷源信號(hào)屏蔽存寄存器,設(shè)置相應(yīng)位來屏蔽中斷信號(hào):

0:未屏蔽,中斷可用

1:屏蔽中斷信號(hào)

0xFFFF

?

INTSUBMSK

描述

初始值

Reserved

[31:15]

未使用

0

INT_AC97

[14]

0 = 未屏蔽1 = 屏蔽中斷

1

INT_RXD0

[0]

0 = 未屏蔽1 = 屏蔽中斷

1

該寄存器用來屏蔽子中斷源信號(hào),默認(rèn)值為全部子中斷都被屏蔽掉,因此要想處理某個(gè)硬件中斷,必須要打開中斷屏蔽位,通過寫入0來取消屏蔽中斷。

(3)SRCPND中斷源暫存寄存器

表3-9中斷源暫存寄存器(SRCPND)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

SRCPND

0x4A000000

R/W

中斷源暫存寄存器,保存中斷請(qǐng)求狀態(tài):

0:沒有中斷請(qǐng)求信號(hào)

1:中斷請(qǐng)求信號(hào)產(chǎn)生

0x00000000

?

SRCPND

描述

初始值

INT_ADC

[31]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

EINT0

[0]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

該寄存器用來保存中斷源信號(hào),當(dāng)某個(gè)中斷信號(hào)產(chǎn)生之后, SRCPND對(duì)應(yīng)位被自動(dòng)置1,該位會(huì)一直保持被置位,只到中斷處理程序?qū)⑵淝宄秊橹?#xff0c;需要注意一下,清除中斷是通過向?qū)?yīng)位寫入1來清除,而不是寫入0,寫入0無(wú)效。

(4)INTMSK中斷源屏蔽寄存器

表3-10中斷源屏蔽寄存器(INTMSK)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

INTMSK

0x4A000008

R/W

中斷源信號(hào)屏蔽存寄存器,設(shè)置相應(yīng)位來屏蔽中斷信號(hào):

0:未屏蔽,中斷可用

1:屏蔽中斷信號(hào)

0xFFFFFFFF

?

INTMSK

描述

初始值

INT_ADC

[31]

0 = 未屏蔽1 = 屏蔽中斷

1

EINT0

[0]

0 = 未屏蔽1 = 屏蔽中斷

1

該寄存器用來屏蔽中斷源信號(hào),默認(rèn)值為全部中斷都被屏蔽掉,因此要想處理某個(gè)硬件中斷,必須要打開中斷屏蔽位,通過寫入0來取消屏蔽中斷。

(5)INTPND最高優(yōu)先級(jí)中斷暫存寄存器

表3-11最高優(yōu)先級(jí)中斷暫存寄存器(INTPND)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

INTPND

0x4A000010

R/W

最高優(yōu)先級(jí)中斷暫存寄存器里面保存有經(jīng)過優(yōu)先級(jí)仲裁的結(jié)果:

0:沒有中斷請(qǐng)求信號(hào)

1:中斷請(qǐng)求信號(hào)產(chǎn)生

0x00000000

?

INTPND

描述

初始值

INT_ADC

[31]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

EINT0

[0]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

該寄存器保存了經(jīng)過優(yōu)先級(jí)仲裁出的中斷信號(hào)位,它是所有當(dāng)前中斷請(qǐng)求里優(yōu)先級(jí)別最高的中斷,因此該寄存器里的值最多有一位被置1,通常中斷處理程序中會(huì)通過讀取該寄存器的值來獲得當(dāng)前正在處理的中斷請(qǐng)求。中斷處理完成之后,通過寫入1來清除中斷。

(6)INTOFFSET中斷號(hào)偏移量寄存器

表3-12中斷號(hào)偏移量寄存器(INTOFFSET)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

INTOFFSET

0x4A000014

R

中斷號(hào)偏移量寄存器,用來保存當(dāng)前處理的中斷號(hào)

0x0000000

該寄存器里存放的是經(jīng)過優(yōu)先級(jí)仲裁出的中斷信號(hào)對(duì)應(yīng)的中斷號(hào),是一個(gè)0~31之間的整數(shù),其實(shí)它就是INTPND里對(duì)應(yīng)的位號(hào),比 如:INT_UART0產(chǎn)生了中斷,INTPND里第28位置1,INTOFFSET里保存的整數(shù)就是28,多出來這個(gè)寄存器的目的主要是方便中斷處理程 序查詢中斷源,清除中斷源:

1 #define TIMER0_IRQ_OFT 10 // 時(shí)鐘0定時(shí)中斷 2 3 #define EINT0_IRQ_OFT 0 // 開發(fā)板K1按鍵1對(duì)應(yīng)外部中斷EINT0 4 5 void handle_irq() 6 7 { 8 9 unsigned long irqOffSet = INTOFFSET; // 取得中斷號(hào) 10 11 switch(irqOffSet) 12 13 { 14 15 case TIMER0_IRQ_OFT: // 當(dāng)前中斷為定時(shí)器0中斷 16 17 do_timer(); // 跳入定時(shí)器0處理程序 18 19 break; 20 21 case EINT0_IRQ_OFT: // 當(dāng)前中斷為K1按鍵觸發(fā) 22 23 do_key1_pressed(); // 處理K1按下事件 24 25 break; 26 27 } 28 29 30 31 SRCPND &= (1<<irqOffSet); // 清除中斷源 32 33 INTPND = INTPND; // 清除最高優(yōu)先級(jí)中斷暫存寄存器中斷 34 35 }

?(7)INTMOD中斷模式寄存器

表3-13中斷模式寄存器(INTMOD)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

INTMOD

0x4A000004

R/W

中斷模式寄存器,指定對(duì)應(yīng)中斷模式:

0 = IRQ一般中斷模式

1 = FIQ快速中斷模式

0x0000000

?

INTMOD

描述

初始值

INT_ADC

[31]

0 = IRQ 1 = FIQ

0

EINT0

[0]

0 = IRQ 1 = FIQ

0

通過設(shè)置INTMOD寄存器對(duì)應(yīng)位,來指定對(duì)應(yīng)中斷模式,如果指定為一般中斷,那么中斷信號(hào)會(huì)進(jìn)行優(yōu)先級(jí)仲裁,如果指定為快速中斷,那么中斷信號(hào)直接送給ARM內(nèi)核產(chǎn)生中斷。需要注意的是,快速中斷不存在優(yōu)先級(jí)仲裁,只能有一位被設(shè)置為FIQ模式。

**********************************************************************************************************************************************************

*************************************************************************************************************************************************************

1.1?? ARM處理器異常處理

所謂異常就是正常的用戶程序被暫時(shí)中止,處理器就進(jìn)入異常模式,例如響應(yīng)一個(gè)來自外設(shè)的中斷,或者當(dāng)前程序非法訪問內(nèi)存地址都會(huì)進(jìn)入相應(yīng)異常模式。

1.1.1?? 異常分類

(1)復(fù)位異常

當(dāng)CPU剛上電時(shí)或按下reset重啟鍵之后進(jìn)入該異常,該異常在管理模式下處理。

(2)一般/快速中斷請(qǐng)求

CPU和外部設(shè)備是分別獨(dú)立的硬件執(zhí)行單元,CPU對(duì)全部設(shè)備進(jìn)行管理和資源調(diào)度處理,CPU要想知道外部設(shè)備的運(yùn)行狀態(tài),要么CPU定時(shí)的去查看 外部設(shè)備特定寄存器,要么讓外部設(shè)備在出現(xiàn)需要CPU干涉處理時(shí)“打斷”CPU,讓它來處理外部設(shè)備的請(qǐng)求,毫無(wú)疑問第二種方式更合理,可以讓CPU“專 心”去工作,這里的“打斷”操作就叫做中斷請(qǐng)求,根據(jù)請(qǐng)求的緊急情況,中斷請(qǐng)求分一般中斷和快速中斷,快速中斷具有最高中斷優(yōu)先級(jí)和最小的中斷延遲,通常 用于處理高速數(shù)據(jù)傳輸及通道的中數(shù)據(jù)恢復(fù)處理,如DMA等,絕大部分外設(shè)使用一般中斷請(qǐng)求。

(3)預(yù)取指令中止異常

該異常發(fā)生在CPU流水線取指階段,如果目標(biāo)指令地址是非法地址進(jìn)入該異常,該異常在中止異常模式下處理。

(4)未定義指令異常

該異常發(fā)生在流水線技術(shù)里的譯碼階段,如果當(dāng)前指令不能被識(shí)別為有效指令,產(chǎn)生未定義指令異常,該異常在未定義異常模式下處理。

(5)軟件中斷指令(swi)異常

該異常是應(yīng)用程序自己調(diào)用時(shí)產(chǎn)生的,用于用戶程序申請(qǐng)?jiān)L問硬件資源時(shí),例如:printf()打印函數(shù),要將用戶數(shù)據(jù)打印到顯示器上,用戶程序要想 實(shí)現(xiàn)打印必須申請(qǐng)使用顯示器,而用戶程序又沒有外設(shè)硬件的使用權(quán),只能通過使用軟件中斷指令切換到內(nèi)核態(tài),通過操作系統(tǒng)內(nèi)核代碼來訪問外設(shè)硬件,內(nèi)核態(tài)是 工作在特權(quán)模式下,操作系統(tǒng)在特權(quán)模式下完成將用戶數(shù)據(jù)打印到顯示器上。這樣做的目的無(wú)非是為了保護(hù)操作系統(tǒng)的安全和硬件資源的合理使用,該異常在管理模 式下處理。

(6)數(shù)據(jù)中止訪問異常

該異常發(fā)生在要訪問數(shù)據(jù)地址不存在或者為非法地址時(shí),該異常在中止異常模式下處理。

1.1.2?? 異常發(fā)生的硬件操作

在異常發(fā)生后,ARM內(nèi)核會(huì)自動(dòng)做以下工作:

  • ? 保存執(zhí)行狀態(tài):將CPSR復(fù)制到發(fā)生的異常模式下SPSR中;
  • ? 模式切換:將CPSR模式位強(qiáng)制設(shè)置為與異常類型相對(duì)應(yīng)的值,同時(shí)處理器進(jìn)入到ARM執(zhí)行模式,禁止所有IRQ中斷,當(dāng)進(jìn)入FIQ快速中斷模式時(shí)禁止FIQ中斷;
  • ? 保存返回地址:將下一條指令的地址(被打斷程序)保存在LR(異常模式下LR_excep)中。
  • ? 跳入異常向量表:強(qiáng)制設(shè)置PC的值為相應(yīng)異常向量地址,跳轉(zhuǎn)到異常處理程序中。

(1)保存執(zhí)行狀態(tài)

當(dāng)前程序的執(zhí)行狀態(tài)是保存在CPSR里面的,異常發(fā)生時(shí),要保存當(dāng)前的CPSR里的執(zhí)行狀態(tài)到異常模式里的SPSR里,將來異常返回時(shí),恢復(fù)回CPSR,恢復(fù)執(zhí)行狀態(tài)。

(2)模式切換

硬件自動(dòng)根據(jù)當(dāng)前的異常類型,將異常碼寫入CPSR里的M[4:0]模式位,這樣CPU就進(jìn)入了對(duì)應(yīng)異常模式下。不管是在ARM狀態(tài)下還是在 THUMB狀態(tài)下發(fā)生異常,都會(huì)自動(dòng)切換到ARM狀態(tài)下進(jìn)行異常的處理,這是由硬件自動(dòng)完成的,將CPSR[5] 設(shè)置為 0。同時(shí),CPU會(huì)關(guān)閉中斷IRQ(設(shè)置CPSR 寄存器I位),防止中斷進(jìn)入,如果當(dāng)前是快速中斷FIQ異常,關(guān)閉快速中斷(設(shè)置CPSR寄存器F位)。

(3)保存返回地址

當(dāng)前程序被異常打斷,切換到異常處理程序里,異常處理完之后,返回當(dāng)前被打斷模式繼續(xù)執(zhí)行,因此必須要保存當(dāng)前執(zhí)行指令的下一條指令的地址到 LR_excep(異常模式下LR,并不存在LR_excep寄存器,為方便讀者理解加上_excep,以下道理相同),由于異常模式不同以及ARM內(nèi)核 采用流水線技術(shù),異常處理程序里要根據(jù)異常模式計(jì)算返回地址。

(4)跳入異常向量表

該操作是CPU硬件自動(dòng)完成的,當(dāng)異常發(fā)生時(shí),CPU強(qiáng)制將PC的值修改為一個(gè)固定內(nèi)存地址,這個(gè)固定地址叫做異常向量(詳見3.2.4章節(jié))。

1.1.3?? 異常返回地址

由1.1.3節(jié)可知,一條指令的執(zhí)行分為:取指,譯碼,執(zhí)行三個(gè)主要階段, CPU由于使用流水線技術(shù),造成當(dāng)前執(zhí)行指令的地址應(yīng)該是PC – 8(32位機(jī)一條指令四個(gè)字節(jié)),那么執(zhí)行指令的下條指令應(yīng)該是PC – 4。在異常發(fā)生時(shí),CPU自動(dòng)會(huì)將將PC – 4 的值保存到LR里,但是該值是否正確還要看異常類型才能決定。

各模式的返回地址說明如下:

(a)一般/快速中斷請(qǐng)求:

快速中斷請(qǐng)求和一般中斷請(qǐng)求返回處理是一樣的。通常處理器執(zhí)行完當(dāng)前指令后,查詢FIQ/IRQ中斷引腳,并查看是否允許FIQ/IRQ中斷,如果 某個(gè)中斷引腳有效,并且系統(tǒng)允許該中斷產(chǎn)生,處理器將產(chǎn)生FIQ/IRQ異常中斷,當(dāng)FIQ/IRQ異常中斷產(chǎn)生時(shí),程序計(jì)數(shù)器pc的值已經(jīng)更新,它指向 當(dāng)前指令后面第3條指令(對(duì)于ARM指令,它指向當(dāng)前指令地址加12字節(jié)的位置;對(duì)于Thumb指令,它指向當(dāng)前指令地址加6字節(jié)的位置),當(dāng) FIQ/IRQ異常中斷產(chǎn)生時(shí),處理器將值(pc-4)保存到FIQ/IRQ異常模式下的寄存器lr_irq/lr_irq中,它指向當(dāng)前指令之后的第2 條指令,因此正確返回地址可以通過下面指令算出:

1 SUBS PC,LR_irq,#4 ; 一般中斷 2 3 SUBS PC,LR_fiq,#4 ; 快速中斷

注:LR_irq/LR_fiq分別為一般中斷和快速中斷異常模式下LR,并不存在LR_xxx寄存器,為方便讀者理解加上_xxx

(b)預(yù)取指中止異常:

  在指令預(yù)取時(shí),如果目標(biāo)地址是非法的,該指令被標(biāo)記成有問題的指令,這時(shí),流水線上該指令之前的指令繼續(xù)執(zhí)行,當(dāng)執(zhí)行到該被標(biāo)記成有問題的指令時(shí), 處理器產(chǎn)生指令預(yù)取中止異常中斷。發(fā)生指令預(yù)取異常中斷時(shí),程序要返回到該有問題的指令處,重新讀取并執(zhí)行該指令,因此指令預(yù)取中止異常中斷應(yīng)該返回到產(chǎn) 生該指令預(yù)取中止異常中斷的指令處,而不是當(dāng)前指令的下一條指令。

  指令預(yù)取中止異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)指令預(yù)取中止異常中斷發(fā)生時(shí),程序計(jì)數(shù)器pc的值還未更新,它指向當(dāng)前指令后面第2 條指令(對(duì)于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對(duì)于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置)。此時(shí)處理器將值(pc-4)保存 到lr_abt中,它指向當(dāng)前指令的下一條指令,所以返回操作可以通過下面指令實(shí)現(xiàn):

SUBS PC,LR_abt,#4

注:LR_abt為中止模式下LR,并不存在LR_abt寄存器,為方便讀者理解加上_abt

(c)未定義指令異常:

  未定義指令異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)未定義指令異常中斷產(chǎn)生時(shí),程序計(jì)數(shù)器pc的值還未更新,它指向當(dāng)前指令后面第2條指 令(對(duì)于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對(duì)于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置),當(dāng)未定義指令異常中斷發(fā)生時(shí),處理器 將值(pc-4)保存到lr_und中,此時(shí)(pc-4)指向當(dāng)前指令的下一條指令,所以從未定義指令異常中斷返回可以通過如下指令來實(shí)現(xiàn):

?MOV PC, LR_und?

注:LR_und為未定義模式下LR,并不存在LR_und寄存器,為方便讀者理解加上_und

(d)軟中斷指令(SWI)異常:

  SWI異常中斷和未定義異常中斷指令一樣,也是由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)SWI指令執(zhí)行時(shí),pc的值還未更新,它指向當(dāng)前指令后面 第2條指令(對(duì)于ARM指令,它指向當(dāng)前指令地址加8字節(jié)的位置;對(duì)于Thumb指令,它指向當(dāng)前指令地址加4字節(jié)的位置),當(dāng)未定義指令異常中斷發(fā)生 時(shí),處理器將值(pc-4)保存到lr_svc中,此時(shí)(pc-4)指向當(dāng)前指令的下一條指令,所以從SWI異常中斷處理返回的實(shí)現(xiàn)方法與從未定義指令異 常中斷處理返回一樣:

?MOV PC, LR_svc?

注:LR_svc為管理模式下LR,并不存在LR_svc寄存器,為方便讀者理解加上_svc

(e)數(shù)據(jù)中止異常:

  發(fā)生數(shù)據(jù)訪問異常中斷時(shí),程序要返回到該有問題的指令處,重新訪問該數(shù)據(jù),因此數(shù)據(jù)訪問異常中斷應(yīng)該返回到產(chǎn)生該數(shù)據(jù)訪問中止異常中斷的指令處,而不是當(dāng)前指令的下一條指令。

  數(shù)據(jù)訪問異常中斷由當(dāng)前執(zhí)行的指令在ALU里執(zhí)行時(shí)產(chǎn)生,當(dāng)數(shù)據(jù)訪問異常中斷發(fā)生時(shí),程序計(jì)數(shù)器pc的值已經(jīng)更新,它指向當(dāng)前指令后面第3條指令 (對(duì)于ARM指令,它指向當(dāng)前指令地址加12字節(jié)的位置;對(duì)于Thumb指令,它指向當(dāng)前指令地址加6字節(jié)的位置)。此時(shí)處理器將值(pc-4)保存到 lr_abt中,它指向當(dāng)前指令后面第2條指令,所以返回操作可以通過下面指令實(shí)現(xiàn):

?SUBS PC, LR_abt, #8?

注:LR_abt為中止模式下LR,并不存在LR_abt寄存器,為方便讀者理解加上_abt

上述每一種異常發(fā)生時(shí),其返回地址都要根據(jù)具體異常類型進(jìn)行重新修復(fù)返回地址,再次強(qiáng)調(diào)下,被打斷程序的返回地址保存在對(duì)應(yīng)異常模式下的LR_excep里。

1.1.4?? 異常向量表

  異常向量表是一段特定內(nèi)存地址空間,每種ARM異常對(duì)應(yīng)一個(gè)字長(zhǎng)空間(4Bytes),正好是一條32位指令長(zhǎng)度,當(dāng)異常發(fā)生時(shí),CPU強(qiáng)制將PC的值設(shè)置為當(dāng)前異常對(duì)應(yīng)的固定內(nèi)存地址。如表3-4所示是S3C2440的異常向量表。

表3-4 異常向量表

?

注:

  異常向量也可以出現(xiàn)在高地址0xFFFF0000處,當(dāng)今操作系統(tǒng)為了控制內(nèi)存訪問權(quán)限,通常會(huì)開啟虛擬內(nèi)存,開啟了虛擬內(nèi)存之后,內(nèi)存的開始空間通常為內(nèi)核進(jìn)程空間,和頁(yè)表空間,異常向量表不能再安裝在0地址處了

  ARM的例外優(yōu)先級(jí)從高到低依次為Reset→Data abort→FIQ→IRQ→Prefetch abort→Undefined instruction/SWI。

  跳入異常向量表操作是異常發(fā)生時(shí),硬件自動(dòng)完成的,剩下的異常處理任務(wù)完全交給了程序員。由上表可知,異常向量是一個(gè)固定的內(nèi)存地址,我們可以通過向該地址處寫一條跳轉(zhuǎn)指令,讓它跳向我們自己定義的異常處理程序的入口,就可以完成異常處理了。

  正是由于異常向量表的存在,才讓硬件異常處理和程序員自定義處理程序有機(jī)聯(lián)系起來。異常向量表里0x00000000地址處是reset復(fù)位異常, 之所以它為0地址,是因?yàn)镃PU在上電時(shí)自動(dòng)從0地址處加載指令,由此可見將復(fù)位異常安裝在此地址處也是前后接合起來設(shè)計(jì)的,不得不感嘆CPU設(shè)計(jì)師的偉 大,其后面分別是其余7種異常向量,每種異常向量都占有四個(gè)字節(jié),正好是一條指令的大小,最后一個(gè)異常是快速中斷異常,將其安裝在此也有它的意義,在 0x0000001C地址處可以直接存放快速中斷的處理程序,不用設(shè)置跳轉(zhuǎn)指令,這樣可以節(jié)省一個(gè)時(shí)鐘周期,加快快速中斷處理時(shí)間。

我們可以通過簡(jiǎn)單的使用下面的指令來安裝異常向量表:

b reset ;跳入reset處理程序b HandleUndef ;跳入未定義處理程序b HandSWI ;跳入軟中斷處理程序b HandPrefetchAbt ;跳入預(yù)取指令處理程序b HandDataAbt ;跳入數(shù)據(jù)訪問中止處理程序b HandNoUsed ;跳入未使用程序b HandleIRQ ;跳入中斷處理程序b HandleFIQ ;跳入快速中斷處理程序

通常安裝完異常向量表,跳到我們自己定義的處理程序入口,這時(shí)我們還沒有保存被打斷程序的現(xiàn)場(chǎng),因此在異常處理程序的入口里先要保存打斷程序現(xiàn)場(chǎng)。

保存執(zhí)行現(xiàn)場(chǎng):

異常處理程序最開始,要保存被打斷程序的執(zhí)行現(xiàn)場(chǎng),程序的執(zhí)行現(xiàn)場(chǎng)無(wú)非就是保存當(dāng)前操作寄存器里的數(shù)據(jù),可以通過下面的棧操作指令實(shí)現(xiàn)保存現(xiàn)場(chǎng):

?STMFD SP_excep!, {R0 – R12, LR_excep}?

注:LR_abt,SP_excep分別為對(duì)應(yīng)異常模式下LR和SP,為方便讀者理解加上_abt

需要注意的是,在跳轉(zhuǎn)到異常處理程序入口時(shí),已經(jīng)切換到對(duì)應(yīng)異常模式下了,因此這里的SP是異常模式下的SP_excep了,所以被打斷程序現(xiàn)場(chǎng) (寄存器數(shù)據(jù))是保存在異常模式下的棧里,上述指令將R0~R12全部都保存到了異常模式棧,最后將修改完的被打斷程序返回地址入棧保存,之所以保存該返 回地址就是將來可以通過類似:MOV? PC,? LR的指令,返回用戶程序繼續(xù)執(zhí)行。

異常發(fā)生后,要針對(duì)異常類型進(jìn)行處理,因此,每種異常都有自己的異常處理程序,異常處理過程通過下節(jié)的系統(tǒng)中斷處理來進(jìn)行分析。

1.1.5?? 異常處理的返回

異常處理完成之后,返回被打斷程序繼續(xù)執(zhí)行,具體操作如下:

  • ? 恢復(fù)被打斷程序運(yùn)行時(shí)寄存器數(shù)據(jù)
  • ? 恢復(fù)程序運(yùn)行時(shí)狀態(tài)CPSR
  • ? 通過進(jìn)入異常時(shí)保存的返回地址,返回到被打斷程序繼續(xù)執(zhí)行

異常發(fā)生后,進(jìn)入異常處理程序時(shí),將用戶程序寄存器R0~R12里的數(shù)據(jù)保存在了異常模式下棧里面,異常處理完返回時(shí),要將棧里保存的的數(shù)據(jù)再恢復(fù) 回原先R0~R12里,毫無(wú)疑問在異常處理過程中必須要保證異常處理入口和出口時(shí)棧指針SP_excep要一樣,否則恢復(fù)到R0~R12里的數(shù)據(jù)不正確, 返回被打斷程序時(shí)執(zhí)行現(xiàn)場(chǎng)不一致,出現(xiàn)問題,雖然將執(zhí)行現(xiàn)場(chǎng)恢復(fù)了,但是此時(shí)還是在異常模式下,CPSR里的狀態(tài)是異常模式下狀態(tài),因此要恢復(fù) SPSR_excep里的保存狀態(tài)到CPSR里,SPSR_excep是被打斷程序執(zhí)行時(shí)的狀態(tài),在恢復(fù)SPSR_excep到CPSR的同時(shí),CPU的 模式和狀態(tài)從異常模式切換回了被打斷程序執(zhí)行時(shí)的模式和狀態(tài)。此刻程序現(xiàn)場(chǎng)恢復(fù)了,狀態(tài)也恢復(fù)了,但PC里的值仍然指向異常模式下的地址空間,我們要讓 CPU繼續(xù)執(zhí)行被打斷程序,因此要再手動(dòng)改變PC的值為進(jìn)入異常時(shí)的返回地址,該地址在異常處理入口時(shí)已經(jīng)計(jì)算好,直接將PC = LR_excep即可。

上述操作可以一步一步實(shí)現(xiàn),但是通常我們可以通過一條指令實(shí)現(xiàn)上述全部操作:

?LDMFD SP_excp!, {r0-r12, pc}^?

注:SP_excep為對(duì)應(yīng)異常模式下SP,^符號(hào)表示恢復(fù)SPSR_excep到CPSR

以上操作可以用下圖來描述:

?

圖3-2中斷處理示意圖

****************************************************************************************************************************************************************

****************************************************************************************************************************************************************

?

ARM系統(tǒng)中斷產(chǎn)生流程

分類: ARM體系結(jié)構(gòu) 2011-06-20 14:40 247人閱讀評(píng)論(2) 收藏舉報(bào)

?

中斷源按照硬件位置分為外部中斷源和內(nèi)部中斷源,外部中斷源和內(nèi)部中斷源又包含子外部中斷源和子內(nèi)部中斷源,如上圖所示(畫了一整天)。

1. 子內(nèi)部中斷源的產(chǎn)生

  以UART0接收數(shù)據(jù)產(chǎn)生INT_RXD0中斷為例,INT_RXD0產(chǎn)生后進(jìn)入SUBSRCPND子中斷源暫存寄存器,設(shè)置INT_RXD0對(duì)應(yīng) 的中斷位,中斷信號(hào)經(jīng)過INTSUBMSK子中斷屏蔽寄存器,如果INT_RXD0信號(hào)對(duì)應(yīng)位沒有被置位(屏蔽掉),中斷信號(hào)繼續(xù)向前傳遞,經(jīng)過子內(nèi)部中 斷源聚合器,將INT_RXD0聚合成對(duì)應(yīng)的中斷源信號(hào)INT_UART0,設(shè)置SRCPND中斷源暫存寄存器里INT_UART0位,經(jīng)過INTMSK 中斷屏蔽寄存器,如果INT_UART0信號(hào)沒有被屏蔽掉,中斷信號(hào)進(jìn)入INTMOD中斷模式寄存器判斷是否為快速中斷,如果被編程為快速中斷,直接打斷 ARM內(nèi)核,進(jìn)入中斷處理,如果中斷信號(hào)為一般中斷,進(jìn)入中斷優(yōu)先級(jí)仲裁器進(jìn)入優(yōu)先級(jí)仲裁,如果INT_UART0信號(hào)為最高優(yōu)先級(jí)或只有 INT_UART0中斷信號(hào)產(chǎn)生,則該中斷信號(hào)被記錄到INTPND最高優(yōu)先級(jí)中斷暫存寄存器,同時(shí)設(shè)置INTOFFSET的值為中斷號(hào)28,最終將中斷 信號(hào)打斷ARM內(nèi)核進(jìn)行中斷處理。如果同時(shí)產(chǎn)生多個(gè)中斷且INT_UART0不是最高優(yōu)先級(jí),則該中斷信號(hào)不會(huì)被處理,等最高優(yōu)先級(jí)信號(hào)處理完后,再次進(jìn) 行優(yōu)先級(jí)仲裁,也就是說中斷信號(hào)不消失,一直保存在SRCPND里,只到被處理為止。

2. 內(nèi)部中斷源的產(chǎn)生

該過程在子內(nèi)部中斷處理過程中已經(jīng)包含,中斷信號(hào)產(chǎn)生后直接進(jìn)入SRCPND里,然后經(jīng)歷上述子內(nèi)部中斷后期處理過程。

3. 子外部中斷的產(chǎn)生

外部中斷源共有24個(gè),其中EINT0~EINT3為外部中斷源,EINT4_7,EINT8_23為復(fù)合中斷源,他們包含有子外部中斷源。

由于外部硬件直接掛接到I/O Ports(詳見S3C2440A硬件手冊(cè)第9章)上的,我們要想讓外設(shè)硬件中斷得到處理,要先從EINT0~EINT23里選擇中斷信號(hào),我們以EINT11為例,介紹子外部中斷處理過程。

通常CPU內(nèi)部引出引腳都是復(fù)用的,也就是說一根CPU引腳可以有多種功能,可以設(shè)置其為輸入信號(hào)線,輸出信號(hào)線或中斷信號(hào)線,要想讓硬件產(chǎn)生中 斷,首先要對(duì)可以產(chǎn)生中斷的引腳進(jìn)行編程,設(shè)置該引腳為中斷信號(hào)線。EINT11中斷信號(hào)對(duì)應(yīng)CPU引腳為GPG3,通過設(shè)置GPGCON[7:6] = 0b10,可以設(shè)置該引腳為中斷信號(hào)線。

表3-14 GPGCON寄存器

?

?

設(shè)置了CPU管腳為中斷信號(hào)線之后,還要通過設(shè)置EXTINT0寄存器來指定中斷信號(hào)的觸發(fā)方式:高電平觸發(fā),低電平觸發(fā),電平上升沿,下除沿,雙沿觸發(fā)。

?

圖3-9 電平信號(hào)觸發(fā)示意圖

由于按鍵按下時(shí)讓它產(chǎn)生中斷,也就是從高電平變?yōu)榈碗娖綍r(shí)產(chǎn)生(上節(jié)按鍵中斷原理),因此我們?cè)O(shè)置EINT11中斷信號(hào)的觸發(fā)方式為下降沿觸發(fā),EXTINT1[14:12] = 0b01x

表3-15 EXTINT1寄存器

?

  設(shè)置完觸發(fā)方式之后,當(dāng)外設(shè)中斷信號(hào)線上的電平達(dá)到觸發(fā)條件時(shí),通過外部中斷產(chǎn)生器產(chǎn)生中斷信號(hào),然后將子外部中斷暫存寄存器EINTPND中對(duì)應(yīng) 的EINT11位置1,中斷信號(hào)再進(jìn)入EINTMSK子外部中斷屏蔽寄存器,如果EINT11中斷源信號(hào)沒有被屏蔽,則EINT11中斷信號(hào)進(jìn)入子外部中 斷聚合器,復(fù)合成EINT8_23中斷信號(hào),然后再經(jīng)歷與前面子內(nèi)部中斷信號(hào)一樣的處理機(jī)制。

(1)EINTPEND外部中斷暫存寄存器

表3-16外部中斷暫存寄存器(EINTPEND)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

EINTPEND

0x560000A8

R/W

外部中斷信號(hào)暫存寄存器

0:沒有中斷請(qǐng)求信號(hào)

1:中斷請(qǐng)求信號(hào)產(chǎn)生

0x0000000

?

EINTPEND

描述

初始值

EINT23

[23]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

EINT4

[4]

0 = 未產(chǎn)生中斷 1 = 產(chǎn)生中斷

0

保留位

[3:0]

無(wú)

0000

?

(2)EINTMASK外部中斷屏蔽寄存器

表3-17外部中斷屏蔽寄存器(EINTMASK)

寄存器名

地址

是否讀寫

描述

復(fù)位默認(rèn)值

EINTMASK

0x560000A4

R/W

外部中斷信號(hào)屏蔽寄存器

0:未屏蔽,中斷可用

1:屏蔽中斷信號(hào)

0x000FFFFF

?

EINTMASK

描述

初始值

EINT23

[23]

0 = 未屏蔽1 = 屏蔽中斷

1

EINT4

[4]

0 = 未屏蔽1 = 屏蔽中斷

1

保留位

[3:0]

無(wú)

1111

4. 外部中斷源的產(chǎn)生

外部中斷產(chǎn)生過程讀者可以根據(jù)上面中斷圖自行分析。

按鍵控制LED燈實(shí)驗(yàn)

本實(shí)驗(yàn)分三個(gè)版本,分別針對(duì)三種開發(fā)板:友善之臂QQ2440,友善之臂MINI2440,天嵌TQ2440。每種開發(fā)板對(duì)應(yīng)工程在:“sys_irq_開發(fā)板名”目錄下。下面實(shí)驗(yàn)內(nèi)容為針對(duì)MINI2440開發(fā)板。

head.s:

主要實(shí)現(xiàn)安裝異常向量表,處理復(fù)位異常,初始化必要硬件,中斷入口處理等功能。

1 ;********************************************************************** 2 3 ; 系統(tǒng)中斷實(shí)驗(yàn)(MINI2440) 4 5 ;********************************************************************** 6 7 GPBCON EQU 0x56000010 8 9 GPBDAT EQU 0x56000014 10 11 EXPORT SYS_IRQ 12 13 AREA SYS_IRQ,CODE,READONLY 14 15 ENTRY 16 17 ;********************************************************************** 18 19 ; 設(shè)置中斷向量,除Reset和HandleIRQ外,其它異常都沒有使用(如果不幸發(fā)生了, 20 21 ; 將導(dǎo)致死機(jī)) 22 23 ;********************************************************************** 24 25 ; 0x00: 復(fù)位Reset異常 26 27 b Reset 28 29 30 31 ; 0x04: 未定義異常(未處理) 32 33 HandleUndef 34 35 b HandleUndef 36 37 38 39 ; 0x08: 軟件中斷異常(未處理) 40 41 HandleSWI 42 43 b HandleSWI 44 45 46 47 ; 0x0c: 指令預(yù)取異常(未處理) 48 49 HandlePrefetchAbt 50 51 b HandlePrefetchAbt 52 53 54 55 ; 0x10: 數(shù)據(jù)訪問中止異常(未處理) 56 57 HandleDataAbt 58 59 b HandleDataAbt 60 61 62 63 ; 0x14: 未使用異常(未處理) 64 65 HandleNotUsed 66 67 b HandleNotUsed 68 69 70 71 ; 0x18: 一般中斷異常,跳往HandleIRQ 72 73 b HandleIRQ 74 75 76 77 ; 0x1c: 快速中斷異常(未處理) 78 79 HandleFIQ 80 81 b HandleFIQ 82 83 84 85 Reset ; 復(fù)位異常處理入口 86 87 ; 關(guān)閉看門狗 88 89 ldr r0, = 0x53000000 90 91 mov r1, #0 92 93 str r1, [r0] 94 95 bl initmem 96 97 ldr sp, =0x32000000 ; 設(shè)置管理模式棧指針 98 99 IMPORT uart_init 100 101 bl uart_init ; UART串口初始化 102 103 IMPORT irq_init 104 105 bl irq_init ; 系統(tǒng)中斷初始化 106 107 IMPORT key_init 108 109 bl key_init ; 按鍵初始化 110 111 IMPORT led_init 112 113 bl led_init ; LED燈初始化 114 115 msr cpsr_cxsf, #0xd2 ; 切換到中斷模式下 116 117 ldr sp, =0x31000000 ; 設(shè)置中斷模式棧指針 118 119 120 121 msr cpsr_cxsf, #0x13 ; 返回管理模式 122 123 124 125 ldr lr, =halt_loop ; 設(shè)置管理模式下返回地址 126 127 IMPORT main 128 129 ldr pc, =main ; 跳入主函數(shù)main里執(zhí)行 130 131 ;*********************************************************************** 132 133 ; 中斷處理 134 135 ;*********************************************************************** 136 137 HandleIRQ 138 139 sub lr,lr,#4 ; 修正返回地址 140 141 stmdb sp!,{r0-r12,lr} ; 保存程序執(zhí)行現(xiàn)場(chǎng) 142 143 ldr lr,=int_return ; 設(shè)置中斷處理程序返回地址 144 145 IMPORT handle_irq 146 147 ldr pc,=handle_irq ; 跳入中斷處理程序 148 149 150 151 int_return ; 中斷處理返回標(biāo)簽 152 153 ldmia sp!,{r0-r12,pc}^ 恢復(fù)程序執(zhí)行現(xiàn)場(chǎng),返回繼續(xù)執(zhí)行 154 155 156 157 halt_loop 158 159 b halt_loop 160 161 initmem 162 163 ldr r0, =0x48000000 164 165 ldr r1, =0x48000034 166 167 ;ldr r2, =memdata 168 169 adr r2, memdata 170 171 initmemloop 172 173 ldr r3, [r2], #4 174 175 str r3, [r0], #4 176 177 teq r0, r1 178 179 bne initmemloop 180 181 mov pc,lr 182 183 184 185 memdata 186 187 DCD 0x22000000 ;BWSCON 188 189 DCD 0x00000700 ;BANKCON0 190 191 DCD 0x00000700 ;BANKCON1 192 193 DCD 0x00000700 ;BANKCON2 194 195 DCD 0x00000700 ;BANKCON3 196 197 DCD 0x00000700 ;BANKCON4 198 199 DCD 0x00000700 ;BANKCON5 200 201 DCD 0x00018005 ;BANKCON6 202 203 DCD 0x00018005 ;BANKCON7 204 205 DCD 0x008e07a3 ;REFRESH 206 207 DCD 0x000000b1 ;BANKSIZE 208 209 DCD 0x00000030 ;MRSRB6 210 211 DCD 0x00000030 ;MRSRB7 212 213 END ; 代碼結(jié)束

?該程序主要設(shè)置異常向量表,除了Reset異常和中斷處理被處理以外,其它異常都未被處理,如果發(fā)生時(shí),會(huì)產(chǎn)生死循環(huán),Reset異常里主要實(shí)現(xiàn)了 硬件的基本初始化,如:按鍵,LED燈等,設(shè)置棧指針,用于執(zhí)行C程序,最后跳入C程序的main函數(shù)。在中斷處理異常處理中首先修正返回地址,保存用戶 執(zhí)行現(xiàn)場(chǎng),跳入到中斷處理例程中執(zhí)行。

sys_init.c:

硬件初始化文件,里面包含LED,KEY的初始化函數(shù)。

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 #define TXD0READY (1<<2) //發(fā)送數(shù)據(jù)狀態(tài)OK 8 9 #define RXD0READY (1) //接收數(shù)據(jù)狀態(tài)OK 10 11 12 13 /* UART串口初始化 */ 14 15 void uart_init() 16 17 { 18 19 GPHCON |= 0xa0; //GPH2,GPH3 used as TXD0,RXD0 20 21 GPHUP = 0x0; //GPH2,GPH3內(nèi)部上拉 22 23 ULCON0 = 0x03; //8N1 24 25 UCON0 = 0x05; //查詢方式為輪詢或中斷;時(shí)鐘選擇為PCLK 26 27 UFCON0 = 0x00; //不使用FIFO 28 29 UMCON0 = 0x00; //不使用流控 30 31 UBRDIV0 = 12; //波特率為57600,PCLK=12Mhz 32 33 } 34 35 36 37 /* UART串口單個(gè)字符打印函數(shù) */ 38 39 extern void putc(unsigned char c) 40 41 { 42 43 while( ! (UTRSTAT0 & TXD0READY) ); 44 45 UTXH0 = c; 46 47 } 48 49 50 51 /* UART串口接受單個(gè)字符函數(shù) */ 52 53 extern unsigned char getc(void) 54 55 { 56 57 while( ! (UTRSTAT0 & RXD0READY) ); 58 59 return URXH0; 60 61 } 62 63 64 65 /* UART串口字符串打印函數(shù) */ 66 67 extern int printk(const char* str) 68 69 { 70 71 int i = 0; 72 73 while( str[i] ){ 74 75 utc( (unsigned char) str[i++] ); 76 77 } 78 79 return i; 80 81 } 82 83 84 85 /* 按鍵初始化 */ 86 87 int key_init() 88 89 { 90 91 // 設(shè)置K1,K2,K3,K4,K5,K6對(duì)應(yīng)控制寄存器為中斷模式 92 93 GPGCON = (2<<0) | (2<<6) | (2<<10) | (2<<12) | (2<<14) | (2<<22); 94 95 /* 96 97 01x falling edge triggered下降沿觸發(fā) 98 99 10x Rising edge triggered上升沿觸發(fā) 100 101 11x Both edge triggered雙沿觸發(fā) 102 103 */ 104 105 // 設(shè)置K1,K2,K3,K4,K5按鍵中斷觸發(fā)方式為上升沿觸發(fā) 106 107 EXTINT1 = (3<<0) | (3<<12) | (3<<20) | (3<<24) | (3<<28); 108 109 EXTINT2 = (3<<12); // 設(shè)置K6按鍵中斷觸發(fā)方式為上升沿觸 110 111 printk("按鍵初始化OK/r/n"); 112 113 return 0; 114 115 } 116 117 118 119 /* Led1~Led4初始化*/ 120 121 #define LED1 (1<<5) //LED1 GPBDAT[5] 122 123 #define LED2 (1<<6) //LED2 GPBDAT[6] 124 125 #define LED3 (1<<7) //LED3 GPBDAT[7] 126 127 #define LED4 (1<<8) //LED4 GPBDAT[8] 128 129 130 131 /* 點(diǎn)亮對(duì)應(yīng)num號(hào)led燈 */ 132 133 extern int led_on(int num) 134 135 { 136 137 switch(num) 138 139 { 140 141 case 1: 142 143 GPBDAT = GPBDAT & ~LED1; break; 144 145 case 2: 146 147 GPBDAT = GPBDAT & ~LED2; break; 148 149 case 3: 150 151 GPBDAT = GPBDAT & ~LED3; break; 152 153 case 4: 154 155 GPBDAT = GPBDAT & ~LED4; break; 156 157 default: 158 159 return 0; 160 161 } 162 163 return num; 164 165 } 166 167 168 169 /* 關(guān)閉num號(hào)led燈 */ 170 171 extern int led_off(int num) 172 173 { 174 175 switch(num) 176 177 { 178 179 case 1: 180 181 GPBDAT = GPBDAT | LED1; break; 182 183 case 2: 184 185 GPBDAT = GPBDAT | LED2; break; 186 187 case 3: 188 189 GPBDAT = GPBDAT | LED3; break; 190 191 case 4: 192 193 GPBDAT = GPBDAT | LED4; break; 194 195 default: 196 197 return 0; 198 199 } 200 201 return num; 202 203 } 204 205 206 207 /* 關(guān)閉全部led燈 */ 208 209 extern int all_led_off(void) 210 211 { 212 213 GPBDAT = GPBDAT | LED1 | LED2 | LED3 | LED4; 214 215 return 0; 216 217 } 218 219 220 221 /* led燈初始化 */ 222 223 int led_init(void) 224 225 { 226 227 GPBCON = 0x15400; //設(shè)置GPB7為輸出口 228 229 all_led_off(); 230 231 printk("led初始化OK/r/n"); 232 233 return 0; 234 235 } 236 237 238 239 /* 中斷初始化 */ 240 241 void irq_init(void) 242 243 { 244 245 // 打開KEY1~KEY6的屏蔽位 246 247 INTMSK &= ~(1<<5); 248 249 EINTMASK &= ~((1<<8) | (1<<11) | (1<<13) | (1<<14) | (1<<15) | (1<<19)); 250 251 printk("中斷初始化OK/r/n"); 252 253 }

該文件是相關(guān)硬件初始化程序,主要包含了看門狗驅(qū)動(dòng),按鍵驅(qū)動(dòng),系統(tǒng)中斷驅(qū)動(dòng),LED驅(qū)動(dòng)。

??? handle_irq.c:

中斷處理函數(shù),查出中斷源,中斷處理,清除中斷源。

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 #define EINT_Key_REQUEST 5 // Key中斷源中斷號(hào)(6個(gè)按鍵全部使用外部子中斷) 8 9 #define K1_EINT_BIT (1<<8) // K1外部子中斷位 10 11 #define K2_EINT_BIT (1<<11) // K2外部子中斷位 12 13 #define K3_EINT_BIT (1<<13) // K3外部子中斷位 14 15 #define K4_EINT_BIT (1<<14) // K4外部子中斷位 16 17 #define K5_EINT_BIT (1<<15) // K5外部子中斷位 18 19 #define K6_EINT_BIT (1<<19) // K6外部子中斷位 20 21 /* 系統(tǒng)中斷處理函數(shù) */ 22 23 void handle_irq() 24 25 { 26 27 unsigned long irqOffSet = INTOFFSET; // 取得中斷號(hào) 28 29 all_led_off(); // 關(guān)閉全部Led燈 30 31 if(EINT_Key_REQUEST==irqOffSet){ // Key中斷產(chǎn)生(6個(gè)按鍵使用一個(gè)總中斷號(hào)) 32 33 if(K1_EINT_BIT & EINTPEND){ 34 35 led_on(1); // 點(diǎn)亮Led1 36 37 printk("Key1 pressed/r/n"); 38 39 EINTPEND &= K1_EINT_BIT; // 清除外部子中斷源 40 41 }else if(K2_EINT_BIT & EINTPEND){ 42 43 led_on(2); // 點(diǎn)亮Led2 44 45 printk("Key2 pressed/r/n"); 46 47 EINTPEND &= K2_EINT_BIT; // 清除外部子中斷源 48 49 }else if(K3_EINT_BIT & EINTPEND){ 50 51 led_on(3); // 點(diǎn)亮Led3 52 53 printk("Key3 pressed/r/n"); 54 55 EINTPEND &= K3_EINT_BIT; // 清除外部子中斷源 56 57 }else if(K4_EINT_BIT & EINTPEND){ 58 59 led_on(4); // 點(diǎn)亮Led4 60 61 printk("Key4 pressed/r/n"); 62 63 EINTPEND &= K4_EINT_BIT; // 清除外部子中斷源 64 65 }else if(K5_EINT_BIT & EINTPEND){ 66 67 all_led_off(1); // 熄滅全部Led 68 69 printk("Key5 pressed/r/n"); 70 71 EINTPEND &= K5_EINT_BIT; // 清除外部子中斷源 72 73 }else if(K6_EINT_BIT & EINTPEND){ 74 75 all_led_on(); // 點(diǎn)亮全部Led 76 77 printk("Key6 pressed/r/n"); 78 79 EINTPEND &= K6_EINT_BIT; // 清除外部子中斷源 80 81 } 82 83 } 84 85 SRCPND &= (1<<irqOffSet); // 清除中斷源 86 87 INTPND = INTPND; // 清除中斷結(jié)果 88 89 }

main.c:

包含主函數(shù)和延時(shí)函數(shù),主要實(shí)現(xiàn)字符串的循環(huán)打印。

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 /* 延時(shí) */ 8 9 void delay(int msec) 10 11 { 12 13 int i, j; 14 15 for(i = 1000; i > 0; i--) 16 17 for(j = msec*10; j > 0; j--) 18 19 /* do nothing */; 20 21 } 22 23 24 25 /* 主函數(shù) */ 26 27 int main() 28 29 { 30 31 while(1) 32 33 { 34 35 printk("main函數(shù)在運(yùn)行.../r/n"); 36 37 delay(5); //delay 38 39 } 40 41 return 0; 42 43 }

?


完。

總結(jié)

以上是生活随笔為你收集整理的TQ2440中断系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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