1. 程式人生 > >STM32中斷和異常

STM32中斷和異常

異常主要分為中斷(如IO口,UART,等)和系統異常(如NMI,SYCTICK,等),注意區分中斷和系統異常,下文異常為統稱,

在CMSIS中,IRQn_Type為異常型別的列舉,系統異常一般為負數,中斷則從0開始

常用的操作異常的CMSIS函式,為了可移植性,建議使用這些函式操作異常。中斷相關暫存器主要在NVIC,系統異常相關暫存器主要在SCB中。


這些函式在core_cm4.h中定義

系統復位時,所有中斷都是禁止的,並且優先順序為0(最高優先順序),所有系統初始化時要呼叫一次NVIC_PriorityGroupConfig來設定優先順序分組情況。

異常優先順序分為搶佔優先順序子優先順序

,高搶佔優先順序的異常(優先順序數字較小)可以搶佔低搶佔優先順序(優先順序數字較大)的異常。子優先順序決定搶佔優先順序相同的異常誰先執行。如果搶佔優先順序和子優先順序都相同,則異常號小的異常先執行。

hard fault,NMI,reset,優先順序為-1,-2,-3,不可設定,其他異常的優先順序只能設定0和以上的數字,所以他們在任何時候都可以搶佔其他異常。

中斷的狀態:

    中斷可以是Enable或Disable或,由軟體設定和清除

    中斷可以是Pending或Not Pending,當中斷產生時Pending位會被硬體置位,中斷消失後不會清除,進入中斷處理函式時會被硬體清除,也可以軟體設定和清除

    中斷可以是Active或Inactive,由硬體設定和清除,正在執行的異常為Active,其他為Inactive,當高優先順序中斷搶佔時,被搶佔的中斷仍是Active

當中斷產生時Pending位會硬體被置位,處理器會馬上處理Pending的中斷,但有些時候,當中斷產生時,處理器正在處理其他高優先順序的異常,則處理完後,會根據Penging位再處理該中斷。如果在處理高優先順序異常過程中,Pending位被清除,則高優先順序異常處理完成後不會再處理該中斷。

如果中斷產生時,該中斷被遮蔽了,Pending位也會被置位。例如在執行中斷時(此時為Active),將該中斷Disable,此時又有該中斷產生,則該中斷Pending位會被置位。

除了NVIC的Pending位以外,EXTI有相應的Pending位在EXTI暫存器中,TIMER等也是,所以在中斷處理函式中要呼叫相應的清除函式EXTI_ClearITPendingBit,TIM_ClearITPendingBit等,而NVIC的Pending位在進入中斷處理函式時會被硬體清除

PRIMASK暫存器(只有最低位有用,其他為保留位)用於禁止所有異常,除了NMI和Hard Fault,只能在特權模式下訪問

CMSIS操作的函式:

void __enable_irq();

void __disable_irq();

彙編操作:

CPSIE I           ;Clear PRIMASK (Enable interrupts)
CPSID I           ;Set PRIMASK (Disable interrupts)

需要軟體觸發中斷可以使用:NVIC_SetPendingIRQ(Timer0_IRQn);

如果需要中斷處理函式在下條指令前執行則需要加Barrier

NVIC_SetPendingIRQ(Timer0_IRQn);
__DSB();               //Data Synchronization Barrier
__ISB();                //Instruction Synchronization Barrier

ARM體系結構的C編譯器遵循AAPCS原則,對函式呼叫由如下規定:

R0-R3, R12, LR, and PSR為呼叫者儲存暫存器,就是當呼叫一個函式前需要儲存這些暫存器,呼叫完後恢復,如果呼叫完後不關心這些暫存器則呼叫前可以不儲存。

R4-R11為被呼叫者儲存暫存器,就是任何函式如果要操作這些暫存器則要先儲存,函式返回前要恢復。

浮點數單元的暫存器也一樣

S0-S15 為呼叫者儲存暫存器

S16-S31 為被呼叫者儲存暫存器

R0-R3也被用作函式輸入引數(R0為第一個引數...),R0也用作函式返回值(如果返回值為64bit,則也會用R1)

在進入異常處理函式前,硬體會將如下暫存器入棧(使用PSP或MSP),如果沒有浮點數單元,則只有8個(xPSR,返回地址,LR,R12,R3-R0),這些暫存器組稱為Stack Frame

根據AAPCS,在函式進入和退出時,SP的值必須double-word對齊,否則會插入padding以保證對齊。該對齊也可以關閉(xPSR的bit9為0時則不對齊)對齊都由硬體根據xPSR的bit9自動完成

操作CCR暫存器對是否對齊進行設定:

SCB->CCR |= SCB_CCR_STKALIGN_Msk;           // Set STKALIGN bit (bit 9) of CCR


進入異常處理函式後,LR暫存器的值被設定為EXC_RETURN,該值根據此時處理器的狀態設定為相應的值,如下圖。

由於高四位永遠是0xF,所以異常處理函式返回地址不能在0xF0000000 到 0xFFFFFFFF之間,但這部分割槽間是不能執行區,所以對程式並不造成什麼問題。


在Thread Mode下可以使用PSP或MSP,在Handler Mode下只能使用MSP。由於EXC_RETURN的bit2決定了入棧時用的SP,所以在出棧時也會用該SP,這樣線上程模式進入異常處理模式,以及異常巢狀時都不會造成棧的混亂。也一樣模式。

參考文獻:

STM32F3 and STM32F4 Series Cortex®-M4 programming manual(PM0214)

The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors