平臺:smart210
CPU:s5pv210
目標:學習s5pv210的中斷體系,從一個子中斷的使能等設置的流程中體會完整的中斷過程。
知識儲備:向量中斷控制器的介紹
主要有4個VIC,4個TZIC還有一個很特殊的ARM PrimeCell PL192。主要的VIC和TZIC可以支持93個中斷源。其中TZIC是為TrustZone技術所準備的,ARM TrustZone? 技術是系統范圍的安全方法,針對高性能計算平臺上的大量應用,包括安全支付、數字版權管理 (DRM)、企業服務和基于 Web 的服務(援引官方的介紹)。TZIC提供了安全控制的nFIQ中斷并且使該這類中斷從傳統的不安全中斷VIC中屏蔽掉,從而達到應用在數據傳輸時的安全性和保密性。
支持的核心功能有固定的硬件中斷優先級以及可編程的軟件中斷優先級(包括設置與屏蔽),還有這是為合理調配中斷而必須要用到的。還有對應的中斷信號生成、中斷請求等等。還有特權模式的訪問。
VIC有四個組,其中每個組均包含有32個中斷源,合計128個中斷源(當然有一些是空的),所支持的中斷源,從GPIO的EINT到UART等各類通訊總線再到多媒體信號等,可以說是無所不包,所以我們只要利用好向量中斷控制器,才能更加高效地使用CPU的計算資源,服務于具體的工作需求。
以VIC0為例,分析具體的寄存器。
RAW INTERRUPT就是該中斷組在沒有設置VIC0INTSELECT和VIC0INTENABLE之前的中斷狀態(初值不確定),而FIQ和IRQ是設置完那兩個寄存器之后的中斷狀態(初值確定為0)。所以我們就有了VIC0IRQSTATUS、VIC0FIQSTATUS與VIC0RAWSTATUS這三個只讀狀態寄存器,每一位都對應著該組(這里是VIC0組)的一個中斷源。
還有一些中斷優先級設置與屏蔽,軟中斷等寄存器可供設置。
其次,還有VIC0VECTADDR0~VICVECTADDR31用來設置各中斷源的中斷服務程序入口,VIC0VECTPRIORITY0~VIC0VECTPRIORITY31用來根據需要設置各中斷源的優先級。還有如下相關的寄存器,我們可以根據需要做相應的讀寫。
VIC0VECTADDR是一個具有特殊功用的寄存器,對它的讀寫最好是在中斷服務程序內,讀的時候能讀出當前中斷運行程序的地址,寫任何值則將清除掉現在正在運行的中斷服務程序,而且要求必須在在中斷服務程序的末尾對該寄存器作任意值寫操作。
VIC0PERIPHID0還有VIC0PCELLID0這些只讀寄存器則只是提供了一些識別信息,基本上不需要用到。
除了上面的內容之外,我們還需要理解以下幾點:
1.異常向量表
我們已知,memory map標志出了Interal SRAM (即iRAM)的地址范圍:0xD002_0000~0xD003_8000,其中的Exception Vector Table是異常向量所屬空間,我們已知ARM有以下的特性:
ARM 系列的處理器可以工作 7 種模式下。除 User Mode 以外的其它 Mode 都叫做特權模式,除 User 和 System 以外的其它 5 種模式叫做異常模式,分別為:
- 快速中斷模式(fiq):高速數據傳輸或通道處理。
- 外部中斷模式(irq):通用的中斷處理。
- 管理模式(svc):操作系統使用的保護模式。
- 數據訪問終止模式(abt):當數據或指令預取終止時進入該模式。
- 定義指令中止模式(und):當未定義的指令執行時進入該模式。
我們需要對這五種異常模式定義好對應的處理程序的入口地址,尤其是常見的兩個中斷模式:FIQ與IRQ,比如當【按鍵中斷】發生的時候,處理器就將進入IRQ模式,首先要進行現場保護(硬件自動完成),然后從固定入口進入中斷處理函數,中斷處理函數首先判斷是哪個中斷組發生中斷,然后直接執行該中斷組對應的VICxINTADDR寄存器里面的函數。我們知道,一個中斷組有32個中斷源,為什么我們可以直接運行中斷組的VICxINTADDR指定的函數而無需知道是具體哪個中斷源觸發了中斷呢?這是由于中斷組內的中斷源在觸發中斷后硬件會自動把對應中斷源的處理函數入口地址賦給所屬組的VICxINTADDR,這樣我們就能省去檢索中斷源再跳轉到對應中斷函數入口的時間了,當然,前提是我們要把【按鍵中斷】的服務程序入口地址賦給某個對應的寄存器(假設是VIC0INTADDR12,所屬組是VIC0組,所對應入口是VIC0INTADDR)。
對應的程序思路是這樣的:
//1.設置異常模式的處理程序入口,應注意到IRQ_handle函數
void system_initexception( void)
{
pExceptionUNDE = (unsigned long)exceptionundef;
pExceptionSWI = (unsigned long)exceptionswi;
pExceptionPABORT = (unsigned long)exceptionpabort;
pExceptionDABORT = (unsigned long)exceptiondabort;
pExceptionIRQ = (unsigned long)IRQ_handle;
pExceptionFIQ = (unsigned long)IRQ_handle;
//左邊都是對應的向量地址,右邊是編寫好的處理程序的函數名,通過賦值達到設置的目的
intc_init();
}
//2.中斷控制器相關初始化
void intc_init(void)
{
//清除中斷使能(禁止中斷)
VIC0INTENCLEAR = 0xffffffff;
VIC1INTENCLEAR = 0xffffffff;
VIC2INTENCLEAR = 0xffffffff;
VIC3INTENCLEAR = 0xffffffff;
//設置所有中斷源為IRQ中斷
VIC0INTSELECT = 0x0;
VIC1INTSELECT = 0x0;
VIC2INTSELECT = 0x0;
VIC3INTSELECT = 0x0;
//清除每個中斷組服務程序入口地址,即四個VICxINTADDR寄存器
intc_clearvectaddr();
}
//3.通過該函數設置外部程序作為對應中斷源服務程序入口,第一個參數為中斷號(一個中斷源對應一個中斷號),第二個參數為函數地址。
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{
//VIC0
if(intnum<32)
{
*( (volatile unsigned long *)(VIC0VECTADDR + 4*intnum) ) = (unsigned)handler;
}
//VIC1
else if(intnum<64)
{
*( (volatile unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;
}
//VIC2
else if(intnum<96)
{
*( (volatile unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;
}
//VIC3
else
{
*( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;
}
return;
}
//4.在start.S中做好一些準備工作,程序最先開始運行start.S,然后設置好CPSR_cxsf后,允許了中斷,跳轉到main函數。
.global _start
.global IRQ_handle
_start:
ldr r0, =0xE2700000
mov r1, #0
str r1, [r0]
ldr sp, =0x40000000
mov r0, #0x53
msr CPSR_cxsf, r0
bl clock_init
bl main
IRQ_handle:
ldr sp, =0xD0037F80
sub lr, lr, #4
stmfd sp!, {r0-r12, lr}
bl irq_handler
ldmfd sp!, {r0-r12, pc}^
//5.main函數的作用
int main(void)
{
int c = 0;
//初始化串口
uart_init();
//初始化異常向量表
system_initexception();
printf('**************Int test *************** rn');
// 1111 = EXT_INT[16] 設置GPIO的H2組作為外部中斷引腳,實質上就是開發板上的實體按鍵
GPH2CON = GPH2_0_EINT16|GPH2_1_EINT17|GPH2_2_EINT18|GPH2_3_EINT19;
GPH3CON = GPH3_0_EINT24|GPH3_1_EINT25|GPH3_2_EINT26|GPH3_3_EINT27;
// 010 = Falling edge triggered
// EXT_INT[16]~EXT_INT[19]是屬于EXT_INT_2的,通過這個寄存器設置為下降沿觸發,而EXT_INT[24]~EXT_INT[27]是屬于EXT_INT_3的。
EXT_INT_2_CON |= 2<<0|2<<4|2<<8|2<<12;
EXT_INT_3_CON |= 2<<0|2<<4|2<<8|2<<12;
//unmask,作用是允許該外部中斷組的具體引腳的中斷觸發功能
EXT_INT_2_MASK &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<3));
EXT_INT_3_MASK &= (~(1<<0)) & (~(1<<1)) & (~(1<<2)) & (~(1<<3));
//NUM_EINT16_31是一個中斷源,只要EINT16到EINT31的任意一個引腳觸發了中斷,就能引發之前設置好的中斷服務程序,這里通過
//intc_setvectaddr()函數把中斷號跟對應中斷服務程序聯系起來。
intc_setvectaddr(NUM_EINT16_31, isr_key);
//使能該中斷源
intc_enable(NUM_EINT16_31);
while (1)
{
printf('%drn',c++);
delay(0x100000);
}
}
void isr_key(void)
{
printf('We get external interrupt:EINT16_31 (key1 to key 8)rn');
//下面的程序是檢測是該中斷源里的哪個引腳觸發的中斷,用來辨別是哪個KEY被按下了。
unsigned long what; what = (EXT_INT_2_PEND & 0x0f) + ((EXT_INT_3_PEND & 0xf) << 4) ;
unsigned long i;
for(i=0;i<8;i++)
{
if(what & 1< printf('Now the key is key%dn',i+1);
} // clear VIC0ADDR
intc_clearvectaddr();
// clear pending bit
EXT_INT_2_PEND |= 1<<0|1<<1|1<<2|1<<3; EXT_INT_3_PEND |= 1<<0|1<<1|1<<2|1<<3;
}void irq_handler(void)
{
unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};
int i=0;
void (*isr)(void) = NULL; for(; i<4; i++)
{
if(intc_getvicirqstatus(i) != 0)
{
isr = (void (*)(void)) vicaddr[i];
break;
}
}
(*isr)();
}
最后,我們來總結一下中斷的設置以及處理的全過程。
首先是進入start.S(清bss,開中斷,設置時鐘,進main),然后是main(初始化串口,初始化異常向量表,初始化中斷控制器,配置GPH2和GPH3作為外部中斷引腳,配置EXT_INT2和EXT_INT3觸發下降沿中斷,取消EXT_INT2與EXT_INT3的中斷屏蔽,設置該外部中斷源的處理函數入口,使能該中斷源的中斷,死循環不斷打印數字)。
當按鍵中斷發生后,根據異常向量表,程序會自動跳轉到IRQ_handle(在start.S內)處執行,IRQ_handle先進行了現場保護,然后跳轉到irq_handler,irq_handler首先是遍歷四個中斷組,看看是哪個中斷組發生了中斷,然后就跳轉到該中斷組的中斷服務程序里(前面已經說到,isr_key作為按鍵中斷服務程序的入口已根據中斷號存入VICxINTADDRn中,而發生中斷的同時,硬件會將中斷源的服務程序入口自動搬移到它所屬的中斷組的VICxINTADDR里),從而間接地運行了isr_key這個程序,在這個程序里,我們做了分析,找出了觸發中斷的具體按鍵,并通過串口打印出來。
上一篇:S5PV210刷機
下一篇:[smart210] 定時器與PWM
推薦閱讀最新更新時間:2025-05-21 20:27
![[<font color='red'>smart210</font>] Nand Flash K9F4G08U0B 的配置與讀寫控制(一)](https://6.eewimg.cn/news/statics/images/loading.gif)



設計資源 培訓 開發板 精華推薦
- LTC2975 的典型應用 - 具有準確輸入電流和能量測量功能的 4 通道 PMBU 電源系統管理器
- STM32 Nucleo-64 開發板,帶 STM32WB15CC,支持 Arduino、ST Morpho 連接
- 使用 Analog Devices 的 LT1302CN8-5 的參考設計
- MC33364臨界導通模式反激轉換器的典型應用電路
- AD9754-EB,用于 AD9754、14 位、125 MSPS 高性能 D/A 轉換器的評估板
- LTC1064-3,優于用于數據通信的貝塞爾線性相位濾波器
- NCS2001SN2T1G 0.9V單電源運放正電容乘法器典型應用電路
- AM6TW-4803DH35Z ±3.3V 6 瓦雙路輸出 DC/DC 轉換器的典型應用
- 使用 Analog Devices 的 LTC1538IG-AUX 的參考設計
- DC1198B-B,使用 LTM4607EV、6 至 36 Vin 至 12V、5A 高效降壓-升壓 DC/DC 模塊穩壓器的演示板