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