裸机篇 -- S5PV210的中断体系
生活随笔
收集整理的這篇文章主要介紹了
裸机篇 -- S5PV210的中断体系
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? 本帖主要通過外部中斷實驗來學習S5PV210的中斷體系。
S5PV210的中斷體系結構
在官方datasheet --?S5PV210_UM_REV1.1?中的sections 04_interrupt 有對整個體系的詳細介紹。
? ?? ?S5PV210的中斷控制器是由4個向量中斷控制器(VIC)、ARM?PrimeCell PL192 和 4個 TrustZone Interrupt Controller (TZIC)共同組成。
? ?? ?S5PV210共支持93個中斷源,datasheet中有詳細的表格:
? ?? ?S5PV210中的四個VIC對應的寄存器很多,但很多都是重復意義的。
OK210的按鍵外設
本次實驗是用外部中斷來實現,所以需要用到開發板的復位按鍵。通過OK210的核心板和底板的原理圖,可以知道按鍵是接在哪個GPIO上:
? ?? ?相對應有用的寄存器:
程序編寫思路
本次實驗的很多程序文件還是沿用之前的,時鐘、串口的初始化直接照搬,Makefile只需做稍微的修改,main函數不用說,測試部分基本在里面,所以新增的中斷int.c文件是主要的。
? ?? ?在S5PV210的啟動流程中,可以知道如下模塊地址映射圖:?其中一塊是異常向量表,這個地址對于本次實驗相當重要。
? ?? ?
? ?? ?對于start.S的啟動,需要增加中斷服務程序: IRQ_handle:
? ? ? ? // 設置中斷模式的棧
? ? ? ? ldr sp, =0xD0037F80
? ? ? ? // 保存現場
? ? ? ? sub lr, lr, #4? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? stmfd sp!, {r0-r12, lr}
? ? ? ? // 跳轉到中斷處理函數
? ? ? ? bl? ? ? ? irq_handler? ? ? ? ? ? ? ??
? ? ? ? // 恢復現場
? ? ? ? ldmfd sp!, {r0-r12, pc}^ 復制代碼 ? ???初始化中斷控制器的思路: // 禁止所有中斷
? ? VIC0INTENCLEAR = 0xffffffff;
? ? VIC1INTENCLEAR = 0xffffffff;
? ? VIC2INTENCLEAR = 0xffffffff;
? ? VIC3INTENCLEAR = 0xffffffff;
? ? // 選擇中斷類型為IRQ
? ? VIC0INTSELECT = 0x0;
? ? VIC1INTSELECT = 0x0;
? ? VIC2INTSELECT = 0x0;
? ? VIC3INTSELECT = 0x0;
? ? // 清VICxADDR
? ? intc_clearvectaddr(); 復制代碼 ? ???清除需要處理的中斷的中斷處理函數的地址: // VICxADDR:當前正在處理的中斷的中斷處理函數的地址
? ? VIC0ADDR = 0;
? ? VIC1ADDR = 0;
? ? VIC2ADDR = 0;
? ? VIC3ADDR = 0; 復制代碼 ? ???main函數實現測試前,可以宏定義一些寄存器: #define ? ? ? ? GPH0CON ? ? ? ? (*(volatile unsigned long *) 0xE0200C00)
#define ? ? ? ? GPH0DAT? ? ? ? ? ? ? ? (*(volatile unsigned long *) 0xE0200C04)
#define ? ? ? ? GPH0_3_EINT3 ? ? ? ? (0xf<<(3*4))
#define ? ? ? ? GPH0_4_EINT4 ? ? ? ? (0xf<<(4*4))
#define ? ? ? ? GPH0_5_EINT5 ? ? ? ? (0xf<<(5*4))
#define ? ? ? ? GPH0_6_EINT6 ? ? ? ? (0xf<<(6*4))
#define ? ? ? ? GPH0_7_EINT7 ? ? ? ? (0xf<<(7*4))
#define? ? ? ? ? ? ? ? EXT_INT_0_CON??? ? ? ? ? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200E00) )
#define? ? ? ? ? ? ? ? EXT_INT_1_CON??? ? ? ? ? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200E04) )
#define? ? ? ? ? ? ? ? EXT_INT_2_CON??? ? ? ? ? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200E08) )
#define? ? ? ? ? ? ? ? EXT_INT_3_CON??? ? ? ? ? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200E0C) )
#define? ? ? ? ? ? ? ? EXT_INT_0_MASK? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F00) )
#define? ? ? ? ? ? ? ? EXT_INT_1_MASK? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F04) )
#define? ? ? ? ? ? ? ? EXT_INT_2_MASK? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F08) )
#define? ? ? ? ? ? ? ? EXT_INT_3_MASK? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F0C) )
#define? ? ? ? ? ? ? ? EXT_INT_0_PEND? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F40) )
#define? ? ? ? ? ? ? ? EXT_INT_1_PEND? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F44) )
#define? ? ? ? ? ? ? ? EXT_INT_2_PEND? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F48) )
#define? ? ? ? ? ? ? ? EXT_INT_3_PEND? ?? ? ? ? ? ? ? ? ( *((volatile unsigned long *)0xE0200F4C) ) 復制代碼 ? ???外部中斷相關的設置: // 1111 = EXT_INT[3]?
? ? ? ? GPH0CON |= 0xF << 12;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? // 010 = Falling edge triggered
? ? ? ? EXT_INT_0_CON |= 0x2 << 12;? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? // unmasked
? ? ? ? EXT_INT_0_MASK &= ~(1<<3); 復制代碼 ? ???保存需要處理的中斷的中斷處理函數的地址: //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;
? ? } 復制代碼 ? ???使能中斷: unsigned long temp;
? ? if(intnum<32)
? ? {
? ?? ???temp = VIC0INTENABLE;
? ?? ???temp |= (1<<intnum);
? ?? ???VIC0INTENABLE = temp;
? ? }
? ? else if(intnum<64)
? ? {
? ?? ???temp = VIC1INTENABLE;
? ?? ???temp |= (1<<(intnum-32));
? ?? ???VIC1INTENABLE = temp;
? ? }
? ? else if(intnum<96)
? ? {
? ?? ???temp = VIC2INTENABLE;
? ?? ???temp |= (1<<(intnum-64));
? ?? ???VIC2INTENABLE = temp;
? ? }
? ? else if(intnum<NUM_ALL)
? ? {
? ?? ???temp = VIC3INTENABLE;
? ?? ???temp |= (1<<(intnum-96));
? ?? ???VIC3INTENABLE = temp;
? ? }
? ? // NUM_ALL : enable all interrupt
? ? else
? ? {
? ?? ???VIC0INTENABLE = 0xFFFFFFFF;
? ?? ???VIC1INTENABLE = 0xFFFFFFFF;
? ?? ???VIC2INTENABLE = 0xFFFFFFFF;
? ?? ???VIC3INTENABLE = 0xFFFFFFFF;
? ? }
復制代碼 ? ?? ?外部中斷按鍵掃描: printf("we get company:EINT3\r\n");
? ? ? ??
? ? ? ? // clear VIC0ADDR
? ? ? ? intc_clearvectaddr();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? // clear pending bit? ? ? ??
? ? ? ? EXT_INT_0_PEND |= 1<<3;? ? ? ? 復制代碼
實驗現象
將程序燒入SD卡,取出插入開發板上,上電后通過SecureCRT即可看到數字從0開始遞增,如果按下開發板上的 K1 鍵(search),就會顯示信息 “we get company:EINT3”。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
S5PV210的中斷體系結構
在官方datasheet --?S5PV210_UM_REV1.1?中的sections 04_interrupt 有對整個體系的詳細介紹。
? ?? ?S5PV210的中斷控制器是由4個向量中斷控制器(VIC)、ARM?PrimeCell PL192 和 4個 TrustZone Interrupt Controller (TZIC)共同組成。
? ?? ?S5PV210共支持93個中斷源,datasheet中有詳細的表格:
? ?? ?S5PV210中的四個VIC對應的寄存器很多,但很多都是重復意義的。
OK210的按鍵外設
本次實驗是用外部中斷來實現,所以需要用到開發板的復位按鍵。通過OK210的核心板和底板的原理圖,可以知道按鍵是接在哪個GPIO上:
? ?? ?相對應有用的寄存器:
程序編寫思路
本次實驗的很多程序文件還是沿用之前的,時鐘、串口的初始化直接照搬,Makefile只需做稍微的修改,main函數不用說,測試部分基本在里面,所以新增的中斷int.c文件是主要的。
? ?? ?在S5PV210的啟動流程中,可以知道如下模塊地址映射圖:?其中一塊是異常向量表,這個地址對于本次實驗相當重要。
? ?? ?
? ?? ?對于start.S的啟動,需要增加中斷服務程序:
實驗現象
將程序燒入SD卡,取出插入開發板上,上電后通過SecureCRT即可看到數字從0開始遞增,如果按下開發板上的 K1 鍵(search),就會顯示信息 “we get company:EINT3”。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的裸机篇 -- S5PV210的中断体系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TQ210裸机编程(4)——按键(中断法
- 下一篇: Tiny4412裸机程序,按键检测(轮询