本文所有的測試是基於stm32f103測試的,因為stm32f103是cortex-m3核心的晶元,而且恰好我手裡有這個晶元,所以就用它了。為了清晰明了,全部使用暫存器方式測試。
在使用cortex-m3系列核心晶元的時候必須掌握其中的nvic中斷向量控制器。必須搞清楚其中的每乙個細節。
nvic管理240個外部中斷,這裡的外部指核心外部,比如看門狗中斷,定時器中斷等等都叫做外部中斷。
那麼核心的異常優先順序怎麼設定呢,比如sistick,pendsv呢?核心異常優先順序由系統控制塊管理。
那我們先看一下核心的優先順序究竟怎麼設定,我們先來看乙個函式nvic_setpriority
static __inline void nvic_setpriority(irqn_type irqn, uint32_t priority)
/* set priority for cortex-m3 system interrupts */
else
/* set priority for device specific interrupts */
}
引數irqn
代表中斷號,引數priority
表示優先順序。我們知道核心的中斷號全部是負數,函式內部對負數的中斷號操作是在scb中的shp陣列裡,找到shp
的位址,shp的起始位址是0xe000ed18,這個大家可以算一下,篇幅原因,這裡不推算了。
m3權威指南中清楚的給出了每個核心異常名字,優先順序設定位址,異常使能位。
我們推算出的位址和m3權威指南中的給出的位址相吻合,那我們是不是可以設定一下核心中的優先順序了呢,感受一下
把menmanage fault的中斷優先順序設定為2,試一下。
上**
scb->shp[0]
=(0x02<<4)
;//設定memorymanagement中斷優先順序為2
使用stm32f103 測試的,st使用了高4位表示優先順序,所有要左移4位。
上圖
優先順序設定完了,使能中斷我們也試一下,
scb->shcsr = 1<<16;//使能memorymanagement中斷
就不貼了,memorymanagement中斷確實是使能了。
其餘的核心異常也是同樣的設定方法。
外部中斷
我們接下來看一下核心之外片上外設的中斷,cortex-m3是如何管理的?
在說外部中斷之前,我們先來了解一下,cortex-m3優先順序分組的概念,
優先順序分組在scb->aircr
暫存器中
上圖是stm32對cortex的裁剪,只用了4個位表示優先順序。
回過頭我們看nvic_setpriority函式,片上外設的中斷優先順序是在nvic的ip暫存器組中設定的,
core_cm3.**件下對nvic的結構體如下
typedef
struct
nvic_type;
這些暫存器在m3權威指南中都有詳細的說明。
中斷使能,除能與懸起,解懸都是成對出現的。為什麼要搞成一對暫存器而不是一組暫存器,因為這些暫存器只有寫1有效,寫0是無效的。因此要開啟某個中斷我們只要相應的位寫1其餘位寫0就可以了。是不是很便捷,如果是一組暫存器,寫1使能中斷寫0關閉中斷,那麼我們想要使能某乙個中斷就必須先把暫存器的值讀取出來,然後將對應位置1,在將資料寫回暫存器,這樣就存在乙個讀,修改,寫的過程。搞清楚了成對出現的原因以後我們看下每一組暫存器的含義。
uint32_t iser[8];
中斷使能暫存器,寫1使能中斷,寫0無效。
cortex-m3可以管理240個外部中斷,每個外部中斷用乙個bit表示。iser
的型別是uint32_t
型別,陣列8個元素,那麼就是32*8 = 256位。256個bit完全可以容納240個中斷了,最後乙個32bit的陣列元素沒有用完。
每乙個bit和外部中斷(片上外設中斷)是如何對應的呢?
下面是m3權威指南給出的解釋,
也就是說外部中斷0對應iser[0]中的bit0,外部中斷1對應iser[0]中的bit1,外部中斷32對應iser[1]中的bit0.依次類推。
uint32_t icer[8];
外部中斷除能暫存器。寫1除能,寫0無效。用法和含義同上不再贅述。
uint32_t ispr[8];
外部中斷懸起暫存器。寫1懸起,寫0無效。如果中斷發生時,正在處理同級或高優先順序異常,或者被掩蔽,則中斷不能立即得到響應。此時中斷被懸起。中斷的懸起狀態可以通過「中斷設定懸起暫存器(setpend)」和「中斷懸起清除暫存器(clrpend)」來讀取,還可以寫它們來手工懸起中斷。
uint32_t icpr[8];
外部中斷解懸暫存器,寫1解懸。寫0無效。
iabr[8];
中斷活躍暫存器。該暫存器唯讀。在處理器執行了其 isr 的第一條指令後,它的活動位就被置 1,並且直到 isr 返回時才硬體清零。如果該中斷被搶占,在執行更高優先順序的中斷時該為依然為1.直到返回,又硬體自動清0。
uint8_t ip[240];
中斷優先順序暫存器,每個外部中斷占用1個位元組。
明白了這些我們用**來測試一下吧,使用timer2
設定優先順序分組2
scb->aircr =
0x05fa0000|(
0x05
<<8)
;//bit10~bit8 101 分組2
配置timer和nvic
可以看nvic中外部中斷定時器2的中斷已經使能了,中斷優先順序是12。為什麼是12呢? 12的二進位制是 1100。因為優先順序分組設定了組2,即搶占式優先順序佔2位,次優先順序佔2位。搶占優先順序在高,次優先順序在低。我們設定的搶占式優先順序是3,次優先順序是0。那麼恰好就是1100了,即十進位制的12.
Cortex M3異常筆記
異常型別 cortex m3編號為1 15對應系統異常,大於等於16的全部是核心級額外部中斷,除個別異常 復位,nmi,硬fault 的優先順序被定死之外,其他異常優先順序都是可以程式設計的。如果乙個發生的異常不能即刻響應,就稱它被 懸起 pending 少數異常時不能被懸起的。乙個異常被懸起的原因...
cortex m3核心中斷
m3核心中有乙個r w 中斷暫存器陣列 該陣列記錄了外部從0到239個中斷的名字pri 0 239,中斷暫存器位址,中斷的優先順序 8位,stm32用了其中的高4位,復位之後是0 如下 另外還有乙個應用中斷控制與復位暫存器r w aircr 這裡面記錄了優先順序分組方法 10 8 對應著前面陣列暫存...
Cortex M3復位序列
在離開復位狀態後,cm3 做的第一件事就是讀取下列兩個32 位整數的值 從位址 0x0000,0000 處取出msp 的初始值。從位址 0x0000,0004 處取出pc 的初始值 這個值是復位向量,lsb 必須是1。然後從這個值所對應的位址處取指。請注意,這與傳統的arm 架構不同 其實也和絕大多...