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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

TQ2440中断系统

發布時間:2023/12/20 windows 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TQ2440中断系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.1?? S3C2440系統中斷

CPU和外設構成了計算機系統,CPU和外設之間通過總線進行連接,用于數據通信和控制,CPU管理監視計算機系統中所有硬件,通常以兩種方式來對硬件進行管理監視:

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

系統中斷是嵌入式硬件實時地處理內部或外部事件的一種機制。對于不同CPU而言,中斷的處理只是細節不同,大體處理流程都一樣,S3C2440A的中斷控制器結構如下圖所示:

圖3-3 S3C2440中斷控制器

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

1? 中斷的產生-中斷源

  S3C2440A支持60種中斷源,基本上滿足了開發板內部,外部設備等對中斷的需求。其中每一個中斷源對應寄存器中的一位,顯然要支持60種中斷 至少需要二個32位寄存器,SUBSRCPND和SRCPND分別保存中斷源信號。S3C2440A對60種中斷源的管理是按層級分的。如圖3-4所示:

?

圖3-4中斷源信號復合示意圖

  S3C2440A將中斷源分為兩級:中斷源和子中斷源,中斷源里包含單一中斷源和復合中斷源,復合中斷源是子中斷源的復合信號。如實時時鐘中斷,該 硬件只會產生一種中斷,它是單一中斷源,直接將其中斷信號線連接到中斷源寄存器上。對于復合中斷源,以UART串口為例進行說明,S3C2440A可以支 持3個UART串口,每個串口對應一個復合中斷源信號INT_UARTn,每個串口可以產生三種中斷,也就是三個子中斷:接收數據中斷INT_RXDn, 發送數據中斷INT_TXDn,數據錯誤中斷INT_ERRn,這三個子中斷信號在中斷源寄存器復合為一個中斷信號,三種中斷任何一個產生都會將中斷信號 傳遞給對應的中斷源INT_UARTn,然后通過中斷信號線傳遞給ARM內核。

?

圖3-5 UART串口中斷源信號復合示意圖

總中斷源詳下面表中列出了S3C2440A部分中斷源,它分別對應中斷源寄存器里某個位:詳細中斷源請查看S3C2440A硬件手冊。

表3-5 部分中斷源信號

中斷源

描述

優先級仲裁分組

INT_ADC

數模轉換和觸摸屏中斷

ARB5

INT_RTC

實時時鐘中斷

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

中斷信號除上述分法之外,還可以按照硬件位置分為:外部中斷源和內部中斷源。

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

  外設硬件通過輸入輸出接口I/O Ports掛接到嵌入式系統上,I/O Ports向外設提供外部中斷信號線,輸出電源,頻率時鐘和輸入輸出信號線,外部硬件根據自己需要連接到I/O Ports上,產生中斷時向外部中斷信號線上送出中斷信號,通過外部中斷信號線傳遞到中斷控制器。

按鍵Key可以認為最為簡單的一種硬件設備了,如下圖所示:

?

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

  它功能很簡單,可以將電路接通,按鍵K1~K6一端接地為低電平,另外一端接電源正極為高電 平,EINT8,EINT11,EINT13,EINT14,EINT15,EINT19六根中斷信號線分別和高電平端按鍵相連,當按鍵按下時電路接通, 整個電路變成低電平,中斷信號線上電壓產生變化,通過設置中斷觸發方式,產生外部中斷請求,輸入到CPU內部,從而實現按鍵中斷控制。

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

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

1.1.1?? 中斷優先級

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

?

圖3-7 S3C2440優先級仲裁示意圖

中斷信號在7個分組里PK時的優先級是可編程的,通過PRIORITY寄存器進行優先級設置。如下表(只列出PRIORITY寄存器部分位):

表3-6 中斷優先級控制寄存器(PRIORITY)

寄存器名

地址

是否讀寫

描述

復位默認值

PRIORITY

0x4A00000C

R/W

中斷優先級控制寄存器

0x7F

?

PRIORITY

描述

初始值

ARB_SEL6

[20:19]

仲裁組6優先級排序方式

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優先級排序

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優先級是否輪轉:

0 = 不輪轉,???? 1 = 輪轉

1

ARB_MODE5

[5]

仲裁組5優先級是否輪轉:

0 = 不輪轉,???? 1 = 輪轉

1

  通過設置仲裁組n優先級排序方式位,設置每個仲裁組內中斷信號的優先級順序,比如:ARB_SEL5分組時包含四個中斷信號:REQ1 INT_UART0, REQ2 INT_SPI1, REQ3 INT_RTC, REQ4 INT_ADC,ARB_SEL5位采用默認值:00,當INT_UART0和INT_RTC中斷信號同時產生時,INT_UART0會被選出,通過可編 程方式改變優先級排序方式來改變中斷信號優先級。

  ARB_MODE0~ ARB_MODE6為每個仲裁分組的優先級輪轉設置位,采用默認值時,當前中斷信號被選擇處理之后,再次產生中斷請求時,它的優先級自動輪轉到該組最低, 這樣可以保證優先級低的中斷信號可以被及時處理,不至于出現優先級高且中斷請求頻繁的中斷每次都被優先處理,而優先級低的被“餓死”的情況。顯然,這種方 式更民主,實時性更佳。

2?? 中斷控制器相關寄存器

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

SUBSRCPND

0x4A000018

R/W

子中斷源暫存寄存器,保存中斷請求狀態:

0:沒有中斷請求信號

1:中斷請求信號產生

0x00000000

?

SUBSRCPND

對應SRCPND

描述

初始值

Reserved

[31:15]

未使用

0

INT_AC97

INT_WDT_AC97

[14]

0 = 未產生中斷 1 = 產生中斷

0

INT_RXD0

INT_UART0

[0]

0 = 未產生中斷 1 = 產生中斷

0

該寄存器用來標識保存子中斷源信號,當某個子中斷信號產生之后,SUBSRCPND對應位被自動置1,該位會一直保持被置位,只到中斷處理程序將其清除為止,需要注意一下,清除中斷是通過向對應位寫入1來清除,而不是寫入0,寫入0無效。

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

INTSUBMSK

0x4A00001C

R/W

子中斷源信號屏蔽存寄存器,設置相應位來屏蔽中斷信號:

0:未屏蔽,中斷可用

1:屏蔽中斷信號

0xFFFF

?

INTSUBMSK

描述

初始值

Reserved

[31:15]

未使用

0

INT_AC97

[14]

0 = 未屏蔽1 = 屏蔽中斷

1

INT_RXD0

[0]

0 = 未屏蔽1 = 屏蔽中斷

1

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

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

SRCPND

0x4A000000

R/W

中斷源暫存寄存器,保存中斷請求狀態:

0:沒有中斷請求信號

1:中斷請求信號產生

0x00000000

?

SRCPND

描述

初始值

INT_ADC

[31]

0 = 未產生中斷 1 = 產生中斷

0

EINT0

[0]

0 = 未產生中斷 1 = 產生中斷

0

該寄存器用來保存中斷源信號,當某個中斷信號產生之后, SRCPND對應位被自動置1,該位會一直保持被置位,只到中斷處理程序將其清除為止,需要注意一下,清除中斷是通過向對應位寫入1來清除,而不是寫入0,寫入0無效。

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

INTMSK

0x4A000008

R/W

中斷源信號屏蔽存寄存器,設置相應位來屏蔽中斷信號:

0:未屏蔽,中斷可用

1:屏蔽中斷信號

0xFFFFFFFF

?

INTMSK

描述

初始值

INT_ADC

[31]

0 = 未屏蔽1 = 屏蔽中斷

1

EINT0

[0]

0 = 未屏蔽1 = 屏蔽中斷

1

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

(5)INTPND最高優先級中斷暫存寄存器

表3-11最高優先級中斷暫存寄存器(INTPND)

寄存器名

地址

是否讀寫

描述

復位默認值

INTPND

0x4A000010

R/W

最高優先級中斷暫存寄存器里面保存有經過優先級仲裁的結果:

0:沒有中斷請求信號

1:中斷請求信號產生

0x00000000

?

INTPND

描述

初始值

INT_ADC

[31]

0 = 未產生中斷 1 = 產生中斷

0

EINT0

[0]

0 = 未產生中斷 1 = 產生中斷

0

該寄存器保存了經過優先級仲裁出的中斷信號位,它是所有當前中斷請求里優先級別最高的中斷,因此該寄存器里的值最多有一位被置1,通常中斷處理程序中會通過讀取該寄存器的值來獲得當前正在處理的中斷請求。中斷處理完成之后,通過寫入1來清除中斷。

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

INTOFFSET

0x4A000014

R

中斷號偏移量寄存器,用來保存當前處理的中斷號

0x0000000

該寄存器里存放的是經過優先級仲裁出的中斷信號對應的中斷號,是一個0~31之間的整數,其實它就是INTPND里對應的位號,比 如:INT_UART0產生了中斷,INTPND里第28位置1,INTOFFSET里保存的整數就是28,多出來這個寄存器的目的主要是方便中斷處理程 序查詢中斷源,清除中斷源:

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

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

INTMOD

0x4A000004

R/W

中斷模式寄存器,指定對應中斷模式:

0 = IRQ一般中斷模式

1 = FIQ快速中斷模式

0x0000000

?

INTMOD

描述

初始值

INT_ADC

[31]

0 = IRQ 1 = FIQ

0

EINT0

[0]

0 = IRQ 1 = FIQ

0

通過設置INTMOD寄存器對應位,來指定對應中斷模式,如果指定為一般中斷,那么中斷信號會進行優先級仲裁,如果指定為快速中斷,那么中斷信號直接送給ARM內核產生中斷。需要注意的是,快速中斷不存在優先級仲裁,只能有一位被設置為FIQ模式。

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

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

1.1?? ARM處理器異常處理

所謂異常就是正常的用戶程序被暫時中止,處理器就進入異常模式,例如響應一個來自外設的中斷,或者當前程序非法訪問內存地址都會進入相應異常模式。

1.1.1?? 異常分類

(1)復位異常

當CPU剛上電時或按下reset重啟鍵之后進入該異常,該異常在管理模式下處理。

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

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

(3)預取指令中止異常

該異常發生在CPU流水線取指階段,如果目標指令地址是非法地址進入該異常,該異常在中止異常模式下處理。

(4)未定義指令異常

該異常發生在流水線技術里的譯碼階段,如果當前指令不能被識別為有效指令,產生未定義指令異常,該異常在未定義異常模式下處理。

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

該異常是應用程序自己調用時產生的,用于用戶程序申請訪問硬件資源時,例如:printf()打印函數,要將用戶數據打印到顯示器上,用戶程序要想 實現打印必須申請使用顯示器,而用戶程序又沒有外設硬件的使用權,只能通過使用軟件中斷指令切換到內核態,通過操作系統內核代碼來訪問外設硬件,內核態是 工作在特權模式下,操作系統在特權模式下完成將用戶數據打印到顯示器上。這樣做的目的無非是為了保護操作系統的安全和硬件資源的合理使用,該異常在管理模 式下處理。

(6)數據中止訪問異常

該異常發生在要訪問數據地址不存在或者為非法地址時,該異常在中止異常模式下處理。

1.1.2?? 異常發生的硬件操作

在異常發生后,ARM內核會自動做以下工作:

  • ? 保存執行狀態:將CPSR復制到發生的異常模式下SPSR中;
  • ? 模式切換:將CPSR模式位強制設置為與異常類型相對應的值,同時處理器進入到ARM執行模式,禁止所有IRQ中斷,當進入FIQ快速中斷模式時禁止FIQ中斷;
  • ? 保存返回地址:將下一條指令的地址(被打斷程序)保存在LR(異常模式下LR_excep)中。
  • ? 跳入異常向量表:強制設置PC的值為相應異常向量地址,跳轉到異常處理程序中。

(1)保存執行狀態

當前程序的執行狀態是保存在CPSR里面的,異常發生時,要保存當前的CPSR里的執行狀態到異常模式里的SPSR里,將來異常返回時,恢復回CPSR,恢復執行狀態。

(2)模式切換

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

(3)保存返回地址

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

(4)跳入異常向量表

該操作是CPU硬件自動完成的,當異常發生時,CPU強制將PC的值修改為一個固定內存地址,這個固定地址叫做異常向量(詳見3.2.4章節)。

1.1.3?? 異常返回地址

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

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

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

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

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

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

(b)預取指中止異常:

  在指令預取時,如果目標地址是非法的,該指令被標記成有問題的指令,這時,流水線上該指令之前的指令繼續執行,當執行到該被標記成有問題的指令時, 處理器產生指令預取中止異常中斷。發生指令預取異常中斷時,程序要返回到該有問題的指令處,重新讀取并執行該指令,因此指令預取中止異常中斷應該返回到產 生該指令預取中止異常中斷的指令處,而不是當前指令的下一條指令。

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

SUBS PC,LR_abt,#4

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

(c)未定義指令異常:

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

?MOV PC, LR_und?

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

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

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

?MOV PC, LR_svc?

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

(e)數據中止異常:

  發生數據訪問異常中斷時,程序要返回到該有問題的指令處,重新訪問該數據,因此數據訪問異常中斷應該返回到產生該數據訪問中止異常中斷的指令處,而不是當前指令的下一條指令。

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

?SUBS PC, LR_abt, #8?

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

上述每一種異常發生時,其返回地址都要根據具體異常類型進行重新修復返回地址,再次強調下,被打斷程序的返回地址保存在對應異常模式下的LR_excep里。

1.1.4?? 異常向量表

  異常向量表是一段特定內存地址空間,每種ARM異常對應一個字長空間(4Bytes),正好是一條32位指令長度,當異常發生時,CPU強制將PC的值設置為當前異常對應的固定內存地址。如表3-4所示是S3C2440的異常向量表。

表3-4 異常向量表

?

注:

  異常向量也可以出現在高地址0xFFFF0000處,當今操作系統為了控制內存訪問權限,通常會開啟虛擬內存,開啟了虛擬內存之后,內存的開始空間通常為內核進程空間,和頁表空間,異常向量表不能再安裝在0地址處了

  ARM的例外優先級從高到低依次為Reset→Data abort→FIQ→IRQ→Prefetch abort→Undefined instruction/SWI。

  跳入異常向量表操作是異常發生時,硬件自動完成的,剩下的異常處理任務完全交給了程序員。由上表可知,異常向量是一個固定的內存地址,我們可以通過向該地址處寫一條跳轉指令,讓它跳向我們自己定義的異常處理程序的入口,就可以完成異常處理了。

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

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

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

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

保存執行現場:

異常處理程序最開始,要保存被打斷程序的執行現場,程序的執行現場無非就是保存當前操作寄存器里的數據,可以通過下面的棧操作指令實現保存現場:

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

注:LR_abt,SP_excep分別為對應異常模式下LR和SP,為方便讀者理解加上_abt

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

異常發生后,要針對異常類型進行處理,因此,每種異常都有自己的異常處理程序,異常處理過程通過下節的系統中斷處理來進行分析。

1.1.5?? 異常處理的返回

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

  • ? 恢復被打斷程序運行時寄存器數據
  • ? 恢復程序運行時狀態CPSR
  • ? 通過進入異常時保存的返回地址,返回到被打斷程序繼續執行

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

上述操作可以一步一步實現,但是通常我們可以通過一條指令實現上述全部操作:

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

注:SP_excep為對應異常模式下SP,^符號表示恢復SPSR_excep到CPSR

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

?

圖3-2中斷處理示意圖

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

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

?

ARM系統中斷產生流程

分類: ARM體系結構 2011-06-20 14:40 247人閱讀評論(2) 收藏舉報

?

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

1. 子內部中斷源的產生

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

2. 內部中斷源的產生

該過程在子內部中斷處理過程中已經包含,中斷信號產生后直接進入SRCPND里,然后經歷上述子內部中斷后期處理過程。

3. 子外部中斷的產生

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

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

通常CPU內部引出引腳都是復用的,也就是說一根CPU引腳可以有多種功能,可以設置其為輸入信號線,輸出信號線或中斷信號線,要想讓硬件產生中 斷,首先要對可以產生中斷的引腳進行編程,設置該引腳為中斷信號線。EINT11中斷信號對應CPU引腳為GPG3,通過設置GPGCON[7:6] = 0b10,可以設置該引腳為中斷信號線。

表3-14 GPGCON寄存器

?

?

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

?

圖3-9 電平信號觸發示意圖

由于按鍵按下時讓它產生中斷,也就是從高電平變為低電平時產生(上節按鍵中斷原理),因此我們設置EINT11中斷信號的觸發方式為下降沿觸發,EXTINT1[14:12] = 0b01x

表3-15 EXTINT1寄存器

?

  設置完觸發方式之后,當外設中斷信號線上的電平達到觸發條件時,通過外部中斷產生器產生中斷信號,然后將子外部中斷暫存寄存器EINTPND中對應 的EINT11位置1,中斷信號再進入EINTMSK子外部中斷屏蔽寄存器,如果EINT11中斷源信號沒有被屏蔽,則EINT11中斷信號進入子外部中 斷聚合器,復合成EINT8_23中斷信號,然后再經歷與前面子內部中斷信號一樣的處理機制。

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

EINTPEND

0x560000A8

R/W

外部中斷信號暫存寄存器

0:沒有中斷請求信號

1:中斷請求信號產生

0x0000000

?

EINTPEND

描述

初始值

EINT23

[23]

0 = 未產生中斷 1 = 產生中斷

0

EINT4

[4]

0 = 未產生中斷 1 = 產生中斷

0

保留位

[3:0]

0000

?

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

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

寄存器名

地址

是否讀寫

描述

復位默認值

EINTMASK

0x560000A4

R/W

外部中斷信號屏蔽寄存器

0:未屏蔽,中斷可用

1:屏蔽中斷信號

0x000FFFFF

?

EINTMASK

描述

初始值

EINT23

[23]

0 = 未屏蔽1 = 屏蔽中斷

1

EINT4

[4]

0 = 未屏蔽1 = 屏蔽中斷

1

保留位

[3:0]

1111

4. 外部中斷源的產生

外部中斷產生過程讀者可以根據上面中斷圖自行分析。

按鍵控制LED燈實驗

本實驗分三個版本,分別針對三種開發板:友善之臂QQ2440,友善之臂MINI2440,天嵌TQ2440。每種開發板對應工程在:“sys_irq_開發板名”目錄下。下面實驗內容為針對MINI2440開發板。

head.s:

主要實現安裝異常向量表,處理復位異常,初始化必要硬件,中斷入口處理等功能。

1 ;********************************************************************** 2 3 ; 系統中斷實驗(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 ; 設置中斷向量,除Reset和HandleIRQ外,其它異常都沒有使用(如果不幸發生了, 20 21 ; 將導致死機) 22 23 ;********************************************************************** 24 25 ; 0x00: 復位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: 指令預取異常(未處理) 48 49 HandlePrefetchAbt 50 51 b HandlePrefetchAbt 52 53 54 55 ; 0x10: 數據訪問中止異常(未處理) 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 ; 復位異常處理入口 86 87 ; 關閉看門狗 88 89 ldr r0, = 0x53000000 90 91 mov r1, #0 92 93 str r1, [r0] 94 95 bl initmem 96 97 ldr sp, =0x32000000 ; 設置管理模式棧指針 98 99 IMPORT uart_init 100 101 bl uart_init ; UART串口初始化 102 103 IMPORT irq_init 104 105 bl irq_init ; 系統中斷初始化 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 ; 設置中斷模式棧指針 118 119 120 121 msr cpsr_cxsf, #0x13 ; 返回管理模式 122 123 124 125 ldr lr, =halt_loop ; 設置管理模式下返回地址 126 127 IMPORT main 128 129 ldr pc, =main ; 跳入主函數main里執行 130 131 ;*********************************************************************** 132 133 ; 中斷處理 134 135 ;*********************************************************************** 136 137 HandleIRQ 138 139 sub lr,lr,#4 ; 修正返回地址 140 141 stmdb sp!,{r0-r12,lr} ; 保存程序執行現場 142 143 ldr lr,=int_return ; 設置中斷處理程序返回地址 144 145 IMPORT handle_irq 146 147 ldr pc,=handle_irq ; 跳入中斷處理程序 148 149 150 151 int_return ; 中斷處理返回標簽 152 153 ldmia sp!,{r0-r12,pc}^ 恢復程序執行現場,返回繼續執行 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 ; 代碼結束

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

sys_init.c:

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

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 #define TXD0READY (1<<2) //發送數據狀態OK 8 9 #define RXD0READY (1) //接收數據狀態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內部上拉 22 23 ULCON0 = 0x03; //8N1 24 25 UCON0 = 0x05; //查詢方式為輪詢或中斷;時鐘選擇為PCLK 26 27 UFCON0 = 0x00; //不使用FIFO 28 29 UMCON0 = 0x00; //不使用流控 30 31 UBRDIV0 = 12; //波特率為57600,PCLK=12Mhz 32 33 } 34 35 36 37 /* UART串口單個字符打印函數 */ 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串口接受單個字符函數 */ 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串口字符串打印函數 */ 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 // 設置K1,K2,K3,K4,K5,K6對應控制寄存器為中斷模式 92 93 GPGCON = (2<<0) | (2<<6) | (2<<10) | (2<<12) | (2<<14) | (2<<22); 94 95 /* 96 97 01x falling edge triggered下降沿觸發 98 99 10x Rising edge triggered上升沿觸發 100 101 11x Both edge triggered雙沿觸發 102 103 */ 104 105 // 設置K1,K2,K3,K4,K5按鍵中斷觸發方式為上升沿觸發 106 107 EXTINT1 = (3<<0) | (3<<12) | (3<<20) | (3<<24) | (3<<28); 108 109 EXTINT2 = (3<<12); // 設置K6按鍵中斷觸發方式為上升沿觸 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 /* 點亮對應num號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 /* 關閉num號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 /* 關閉全部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; //設置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 }

該文件是相關硬件初始化程序,主要包含了看門狗驅動,按鍵驅動,系統中斷驅動,LED驅動。

??? handle_irq.c:

中斷處理函數,查出中斷源,中斷處理,清除中斷源。

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 #define EINT_Key_REQUEST 5 // Key中斷源中斷號(6個按鍵全部使用外部子中斷) 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 /* 系統中斷處理函數 */ 22 23 void handle_irq() 24 25 { 26 27 unsigned long irqOffSet = INTOFFSET; // 取得中斷號 28 29 all_led_off(); // 關閉全部Led燈 30 31 if(EINT_Key_REQUEST==irqOffSet){ // Key中斷產生(6個按鍵使用一個總中斷號) 32 33 if(K1_EINT_BIT & EINTPEND){ 34 35 led_on(1); // 點亮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); // 點亮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); // 點亮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); // 點亮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(); // 點亮全部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; // 清除中斷結果 88 89 }

main.c:

包含主函數和延時函數,主要實現字符串的循環打印。

1 #include "register.h" 2 3 #include "comm_fun.h" 4 5 6 7 /* 延時 */ 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 /* 主函數 */ 26 27 int main() 28 29 { 30 31 while(1) 32 33 { 34 35 printk("main函數在運行.../r/n"); 36 37 delay(5); //delay 38 39 } 40 41 return 0; 42 43 }

?


完。

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩av福利| 色视频一区 | 黄色小视频免费在线观看 | 午夜不卡久久精品无码免费 | 亚洲网站在线 | 国产欧美一区二区三区国产幕精品 | 搡老熟女老女人一区二区 | 成品人视频ww入口 | 岛国av一区二区三区 | 好吊妞视频一区二区三区 | 日本a√在线观看 | 中文字幕在线资源 | 久久人人爽人人爽人人片 | 国产高清不卡视频 | 欧美第一页在线观看 | 男女无遮挡网站 | 国产一区免费视频 | 国产精品观看 | 日本激情视频一区二区三区 | 国产视频在线一区二区 | 人人插插| 亚洲爱v| 国产精品久久久999 www日本高清视频 | 免费在线观看毛片视频 | 日韩精品乱码 | 成年人在线播放 | 毛片毛片毛片 | 免费看片亚洲 | 亚洲欧美伊人 | 亚洲污视频 | 亚洲AV无码精品黑人黑人 | 永久免费看mv网站入口78 | 国产精品一区二区av白丝下载 | 国产在线播放一区二区三区 | 国产无遮挡又黄又爽免费网站 | 午夜大片在线观看 | 91破处视频| 日本大胆欧美人术艺术 | 精品国产一区二区三区久久狼黑人 | 少妇无内裤下蹲露大唇视频 | 欧美极品少妇xxxxⅹ猛交 | 国产欧美一区二区三区在线老狼 | 97人人在线视频 | 激情内射亚洲一区二区三区爱妻 | a级全黄| 丝袜 中出 制服 人妻 美腿 | 亚洲精品一区久久久久久 | 男人天堂中文字幕 | 亚洲成人免费看 | 日韩欧美自拍 | 中文字幕免费av | 毛片aa| 黄色成人在线网站 | 97在线观看免费 | 神马午夜麻豆 | 欧美精品黄 | 日韩精品一二三四 | 成 人免费va视频 | 中国黄色一级大片 | 久9精品| 色综合天天综合网国产成人网 | 久久亚洲欧洲 | 久久精品国产亚洲av成人 | 91丨九色丨丰满人妖 | 亚洲av综合色区无码一二三区 | 怡红院成人影院 | 久草毛片 | 国产一区二区精品在线观看 | 欧美又黑又粗 | 免费成人在线观看 | av三级在线播放 | 极品色影视 | 俄罗斯女人裸体性做爰 | 亚洲情趣 | 99国产精品国产免费观看 | 欧美成人黄色片 | 国产网址在线观看 | 国产精品乱码一区 | 性喷潮久久久久久久久 | 草逼国产 | 在线观看的av| 五月天一区二区 | 欧美高清成人 | 日韩欧美www | 国产黄色网址在线观看 | 成人av高清在线观看 | 久久久国产成人 | 成年人黄网站 | 中文字幕一区二区三区四区免费看 | 韩国一区二区三区在线观看 | 欧美老肥婆性猛交视频 | 电影《两个尼姑》免费播放 | 99一区二区| 1024视频在线| 中文在线中文资源 | 三年大片在线观看 | 麻豆国产精品777777在线 | 国产日韩久久久 | 国产真人真事毛片 |