當前位置:首頁 > 單片機 > 單片機
[導(dǎo)讀]編譯器內(nèi)部函數(shù)__disable_irq、__enable_irq、__disable_fiq和__enable_fiq用于控制IRQ和FIQ中斷。只有當處理器處于特權(quán)模式才可以使用這些內(nèi)部函數(shù),因為這些函數(shù)要改變寄存器CPSR和SPSR(ARM7、ARM9等)或者PRIMAS

編譯器內(nèi)部函數(shù)__disable_irq、__enable_irq、__disable_fiq和__enable_fiq用于控制IRQ和FIQ中斷。
只有當處理器處于特權(quán)模式才可以使用這些內(nèi)部函數(shù),因為這些函數(shù)要改變寄存器CPSR和SPSR(ARM7、ARM9等)或者PRIMASK和FAULTMASK寄存器(Cortex-M3、M4等),而這些寄存器只有在特權(quán)模式下才能被訪問。
這些內(nèi)部函數(shù)對所有架構(gòu)的處理器都有效,無論是ARM狀態(tài)還是Thumb狀態(tài),如下所述:
如果使用的是ARMv6(ARM11)或更新架構(gòu),編譯器會將這些函數(shù)用CPS指令代替。
如果使用的是ARMv4或者ARMv5架構(gòu)并且處于ARM狀態(tài),編譯器會將這些函數(shù)用MRS和MSR指令代替。一般情況下ARM7屬于ARMv4架構(gòu),ARM9屬于ARMv5架構(gòu)。
如果使用的是ARMv4或者ARMv5架構(gòu)并且處于Thumb狀態(tài)或編譯器使能-compatible參數(shù),則編譯器會調(diào)用一個輔助函數(shù)比如__ARM_disable_irq來控制中斷。

1. __enable_fiq

使能FIQ中斷。
通常是通過清除寄存器CPSR中的F位來實現(xiàn)的。注意FIQ中斷一般只存在于ARMv4和ARMv5架構(gòu)中(即ARM7和ARM9),ARMv6架構(gòu)的處理器不支持此函數(shù)。對于ARMv7架構(gòu)的處理器(Cortex-M3),這個函數(shù)清除FAULTMASK寄存器的值。
語法:void __enable_fiq(void)
限制:只能在特權(quán)級別下使用,用戶模式下無效。

2.__disable_fiq

禁用FIQ中斷。
通常是通過置一CPSR的F位來實現(xiàn)的。注意FIQ中斷一般只存在于ARMv4和ARMv5架構(gòu)中(即ARM7和ARM9),ARMv6架構(gòu)的處理器不支持此函數(shù)。對于ARMv7架構(gòu)的處理器(Cortex-M3),這個函數(shù)置位FAULTMASK寄存器,這意味著此后只有NMI可以響應(yīng),所有其它的異常,包括中斷和 Fault都不能響應(yīng)。
語法:__disable_fiq有兩個版本,一個是返回值為空的void __disable_fiq(void),另一個返回值為整形值的int __disable_fiq(void),函數(shù)名都是__disable_fiq。
用法:int __disable_fiq(void),禁止FIQ中斷(ARMv4和ARMv5)或禁用除NMI之外的所有中斷(ARMv7)。在禁用中斷前,將中斷使能狀態(tài)返回。
void __disable_fiq(void),禁用FIQ中斷(ARMv4和ARMv5)或禁用除NMI之外的所有中斷(ARMv7)。
限制:只能在特權(quán)級別下使用,用戶模式下無效。如果編譯器參數(shù)設(shè)置為-cpu=7,則不支持int __disable_fiq(void)函數(shù),這是因為通用ARMv7架構(gòu)和ARMv7 R及ARMv7 M-profiles架構(gòu)的異常處理模式不同所導(dǎo)致的。這意味著如果編譯器參數(shù)設(shè)置為-cpu=7,編譯器不能為int __disable_fiq(void)函數(shù)產(chǎn)生所有ARMv7架構(gòu)通用的指令序列,此時只能使用void __disable_fiq(void)。
舉例:

voidfunc(void)

{

intwas_masked=__disable_fiq();

/*其它處理*/

if(!was_masked)

__enable_fiq();

}

為什么例子中要使用變量was_masked獲取之前的中斷使能信息,并且在使能中斷時還要先判斷這個變量?直接使用__disable_fiq()和__enable_fiq()函數(shù)不是更簡單嗎?
這是因為如果之前系統(tǒng)的中斷已經(jīng)是關(guān)閉的,當你直接使用__enable_fiq()函數(shù)就會無條件打開中斷,這樣可能是很危險的。所以在打開中斷前,要檢查之前中斷是不是已經(jīng)是禁止狀態(tài),如果是的話就不要使能中斷。

3.__enable_irq

使能IRQ中斷。
對于ARMv4和ARMv5架構(gòu)(ARM7和ARM9),編譯器插入下列指令清除CPSR寄存器的I位。

MRSr0,CPSR

ANDr0,r0,#0x7F

MSRCPSR_c,r0

對于ARMv6(ARM11)和ARMv7(Cortex-M3等)指令,編譯器插入下列指令使能中斷:

CPSIEI

比如Cortex-M3架構(gòu)處理器,該指令清除PRIMASK寄存器,使能中斷。
語法:void __enable_irq(void)
限制:只能在特權(quán)級別下使用,用戶模式下無效。

4. __disable_irq

禁止IRQ中斷。
對于ARMv4和ARMv5架構(gòu)(ARM7和ARM9),編譯器插入下列指令置位CPSR寄存器的I位。

MRSr0,CPSR

ORRr0,r0,#0x80

MSRCPSR_c,r0

對于ARMv6(ARM11)和ARMv7(Cortex-M3等)指令,編譯器插入下列指令禁用中斷:

CPSIDI

比如Cortex-M3架構(gòu)處理器,該指令置位PRIMASK寄存器,表示禁止中斷和可屏蔽的異常,只剩下NMI和硬Fault可以響應(yīng)。
__disable_irq函數(shù)有兩種形式,返回值為空的void __disable_irq(void)和返回值為整形數(shù)的int __disable_irq(void)。前者直接禁用中斷,后者在禁用中斷前,將中斷使能狀態(tài)返回。
舉例:

voidfunc(void)

{

intwas_masked=__disable_irq();

/*其它處理*/

if(!was_masked)

__enable_irq();

}

為什么例子中要使用變量was_masked獲取之前的中斷使能信息,并且在使能中斷時還要先判斷這個變量?直接使用__disable_irq()和__enable_irq()函數(shù)不是更簡單嗎?
這是因為如果之前系統(tǒng)的中斷已經(jīng)是關(guān)閉的,當你直接使用__enable_irq()函數(shù)就會無條件打開中斷,這樣可能是很危險的。所以在打開中斷前,要檢查之前中斷是不是已經(jīng)是禁止狀態(tài),如果是的話就不要使能中斷。
限制:只能在特權(quán)級別下使用,用戶模式下無效。如果編譯器參數(shù)設(shè)置為-cpu=7,則不支持int __disable_irq(void)函數(shù),這是因為通用ARMv7架構(gòu)和ARMv7 R及ARMv7 M-profiles架構(gòu)的異常處理模式不同所導(dǎo)致的。這意味著如果編譯器參數(shù)設(shè)置為-cpu=7,編譯器不能為int __disable_irq(void)函數(shù)產(chǎn)生所有ARMv7架構(gòu)通用的指令序列,此時只能使用void __disable_irq(void)。

我們再從匯編層面上看一下返回整形數(shù)的__disable_irq:

intdisable_irq(void)

{

return__disable_irq();

}

在-cpu=Cortex-M3時,Keil MDK編譯器產(chǎn)生的匯編代碼為:

MRSr0,PRIMASK

ANDr0,r0,#1

CPSIDi

BXlr

5.這些函數(shù)有什么用處?

保護共享資源

禁止中斷嵌套

保護共享資源很好理解,但禁止中斷嵌套可能很多人不理解:中斷嵌套可以提高系統(tǒng)響應(yīng)時間,為什么要禁用掉?
雖然中斷嵌套能提高響應(yīng)時間,但絕大多數(shù)的應(yīng)用并不需要如此高的響應(yīng)時間;更重要的是,中斷嵌套增加了程序運行的不確定性。所以我建議在不需要極致的響應(yīng)時間使,禁止中斷嵌套。方法也很簡單,在進入中斷服務(wù)函數(shù)后和退出中斷服務(wù)函數(shù)前中調(diào)用本文講的這些中斷控制函數(shù)即可。

6.移植性

與編譯器特性相關(guān),不具備移植性,建議使用前先用宏進行封裝。


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉