arm中斷學(xué)習(xí)及變量長度
使用的的是PHILIPS 的ARM控制器LPC2000系列
本文引用地址:http://www.ex-cimer.com/article/201611/316771.htm1.I/O配置
LPC2000有管腳功能配置寄存器,一個管腳可以通過PINSEL0~2的配置,可以有1~4個功能(有的只有一個),但不是說任意一個管腳可以配置為任意功能,只能通過器件手冊的規(guī)定選擇規(guī)定功能中的一個。
2.中斷
LPC2000的中斷專門有一套寄存器來管理,這套寄存器稱為VIC(向量中斷控制器)。
向量中斷控制器(VIC)具有32 個中斷請求輸入,可將其編程分為3 類:FIQ、向量IRQ 和非向量IRQ。可編程分配機制意味著不同外設(shè)的中斷優(yōu)先級可以動態(tài)分配并調(diào)整。
所謂FIQ,就是快速中斷,要求具有最高優(yōu)先級。如果分配給FIQ 的請求多于1 個,VIC將中斷請求“相或”后向ARM 處理器產(chǎn)生FIQ 信號。當(dāng)只有一個中斷被分配為FIQ 時可實現(xiàn)最短的FIQ 等待時間,因為FIQ 服務(wù)程序只要簡單地啟動器件的處理就可以了。但如果分配給FIQ 級的中斷多于1 個,F(xiàn)IQ 服務(wù)程序從VIC 中讀出一個字來識別產(chǎn)生中斷請求的FIQ 中斷源是哪一個。
向量IRQ,具有中優(yōu)先級,就是IRQ下還可以分為16個優(yōu)先級,根據(jù)VICVectAddr0~15 來排列模塊的優(yōu)先級,0為最高級別,15為最低優(yōu)先級
非向量IRQ,具有最低優(yōu)先級,多個中斷共用一個中斷服務(wù)子程序(ISR)入口,入口地址放到VICDefVectAddr中,并通過讀取中斷的狀態(tài)來判斷是哪個中斷被響應(yīng)。
FIQ和IRQ的選擇由寄存器VICIntEnable、VICIntSelect來配置,向量IRQ和非向量IRQ由VICVectCntl0~15的第5位來選擇,VICVectAddr0~15 所決定的中斷入口地址對應(yīng)的中斷是由VICVectCntl0~15的低4位所代表的中斷號(通道,詳見芯片的數(shù)據(jù)手冊)決定。
雖然可以選擇多個中斷源(通過VICIntSelect)來產(chǎn)生FIQ 請求,但是只有一個專門的中斷服務(wù)程序來服務(wù)響應(yīng)所有可用/出現(xiàn)的FIQ 請求。因此,如果分配為FIQ 的中斷多于一個,F(xiàn)IQ 中斷服務(wù)程序就必須讀取VICFIQStatus 的內(nèi)容來決定如何處理中斷請求。不過還是建議只將一個中斷分配為FIQ。多個FIQ 中斷源會增加中斷延遲。
一旦產(chǎn)生中斷號為N的向量IRQ請求,VICVectAddr 和分配給中斷號為N的ISR地址相同,即VICVectAddr=VICVectAddr X,而VICVectCnt X=0X0000 002N,VICVectAddr X=ISR地址。通常,獲得ISR地址,可以通過將ISR的函數(shù)強制由void轉(zhuǎn)換為usigned long實現(xiàn),比如VICVectAddr0=(unsigned long)time_int();
一旦產(chǎn)生非向量IRQ請求,那么VICVectAddr 的內(nèi)容與VICDefVectAddr 相同。
在中斷服務(wù)程序執(zhí)行完畢后,對外設(shè)中斷標(biāo)志的清零將會對VIC 寄存器(VICRawlntr,VICFIQStatus 和VICIRQStatus)當(dāng)中的對應(yīng)位產(chǎn)生影響。另外,為了能夠服務(wù)下次中斷,必須在中斷返回之前對ICVectAddr 寄存器執(zhí)行寫操作。該寫操作將清零內(nèi)部中斷優(yōu)先級硬件當(dāng)中對應(yīng)的中斷標(biāo)志。
如果看門狗只在溢出或無效喂狗時產(chǎn)生中斷,那么無法清除中斷。唯一的方法是通過VICIntEnClr 禁止VIC 中斷來實現(xiàn)中斷返回。
VICIRQStatus IRQ 狀態(tài)寄存器。該寄存器讀出定義為IRQ 并使能的中斷的狀態(tài)。
VICFIQStatus FIQ 狀態(tài)請求。該寄存器讀出定義為FIQ 并使能的中斷的狀態(tài)。
VICRawIntr 所有中斷的狀態(tài)寄存器。該寄存器讀出32 個中斷請求/軟件中斷的狀態(tài),不管中斷是否使能或分類
VICIntSelect 中斷選擇寄存器。該寄存器將32 個中斷請求的每個都分配為FIQ 或IRQ
VICIntEnable 中斷使能寄存器。該寄存器控制將32 個中斷請求和軟件中斷中的哪些使能為FIQ 或IRQ
VICIntEnClr 中斷使能清零寄存器。該寄存器允許軟件將中斷使能寄存器中的一個或多個位清零
VICSoftInt 軟件中斷寄存器。該寄存器的內(nèi)容與32 個不同外設(shè)的中斷請求“相或”。
VICSoftIntClear 軟件中斷清零寄存器。該寄存器允許軟件將軟件中斷寄存器中的一個或多個位清零。
VICProtection 保護使能寄存器。該寄存器允許特權(quán)模式下運行的軟件對VIC 寄存器進行有限的訪問,運行在用戶模式下的軟件使用該1 位寄存器來控制對VIC 寄存器的訪問。
VICVectAddr 向量地址寄存器。當(dāng)發(fā)生一個IRQ 中斷時,IRQ 服務(wù)程序可讀出該寄存器并跳轉(zhuǎn)到讀出的地址。
VICDefVectAddr 默認(rèn)向量地址寄存器。該寄存器保存了非向量IRQ的中斷服務(wù)程序(ISR)地址。
VICVectAddr0~15 向量地址0~15 寄存器。向量地址寄存器0-15 保存了16個向量IRQ slot 的中斷服務(wù)程序地址。
VICVectCntl0~15 向量控制0~15 寄存器。向量控制寄存器0-15 分別控制16 個向量IRQ slot 中的一個。Slot0 優(yōu)先級最高,而Slot15 優(yōu)先級最低。在VICVectCntl 寄存器中禁止一個向量IRQ slot 不會禁止中斷本身,中斷只是變?yōu)榉窍蛄康男问健?/p>
bit 5 1:向量IRQ 使能,當(dāng)分配的中斷請求或軟件中斷使能,被分配為IRQ 并聲明時,可產(chǎn)生一個唯一的ISR 地址對應(yīng)位的中斷請求使能并分配為FIQ并且聲明。
bit 4:0 分配給此向量IRQ slot 的中斷請求或軟件中斷的編號。作為一個良好的編程習(xí)慣,不要將把相同的中斷編號分配給多于一個使能的向量IRQ slot。但如果這樣做了,當(dāng)中斷請求或軟件中斷使能,被分配為IRQ 并聲明時,會使用最低編號的slot。
VIC 將所有向量和非向量IRQ“相或”向ARM 處理器產(chǎn)生IRQ 信號。IRQ 服務(wù)程序可通過讀取VIC 的一個寄存器立即啟動并跳轉(zhuǎn)到相應(yīng)地址。如果有任意一個向量IRQ 發(fā)出請求,VIC 則提供最高優(yōu)先級請求IRQ 服務(wù)程序的地址,否則提供所默認(rèn)程序的地址。該默認(rèn)程序由所有非向量IRQ 共用。默認(rèn)程序可讀取另一個VIC 寄存器以確定哪個IRQ被激活。
筆者正在學(xué)習(xí)uCOS-II,移植到ARM時考慮到數(shù)據(jù)類型的定義,但對于Keil MDK編譯器的數(shù)據(jù)類型定義還是很模糊,主要就是區(qū)分不了short int、int、long 和long int占用多少字節(jié)。為了得到一個權(quán)威的答案,改用編譯器自身得出。
一、先定義幾個變量,用于存放各數(shù)據(jù)類型的字節(jié)數(shù)。
//#include
#include
unsigned char a,b,c,d,e,f,g;
main()
{
a=sizeof(char);
b=sizeof(short int);
c=sizeof(int);
d=sizeof(long);
e=sizeof(long int);
f=sizeof(float);
g=sizeof(double);
while(1);
}
二、查看各變量的存放地址。View---Symbols Window。
三、查看各地址存放的值。View---memory Window。
由上圖可知得出:
char占用1個字節(jié)
short int占用2字節(jié)
int占用4字節(jié)
long占用4字節(jié)
long int占用4字節(jié)
float占用4字節(jié)
double占用8字節(jié)
我們即可這樣定義宏:
typedef unsigned char uint8; // 無符號8位整型變量
typedef signed char int8; // 有符號8位整型變量
typedef unsigned short uint16; // 無符號16位整型變量
typedef signed short int16; // 有符號16位整型變量
typedef unsigned int uint32; // 無符號32位整型變量
typedef signed int int32; // 有符號32位整型變量
typedef float fp32; // 單精度浮點數(shù)(32位長度)
typedef double fp64; // 雙精度浮點數(shù)(64位長度)
評論