1、異常向量表基址
s5pv210 默認指定了異常向量基址0xD003_4700, 當異常比如中斷觸發時,會自動跳轉到基址查找異常處理函數s5pv210 默認指定了異常向量基址0xD003_4700, 當異常比如中斷觸發時,會自動跳轉到基址查找異常處理函數
通過代碼可以這樣實現,通過代碼可以這樣實現,
#define _Exception_Vector 0xD0037400
#define pExceptionRESET ( *((volatile unsigned long *)(_Exception_Vector + 0x0)) )
#define pExceptionUNDEF ( *((volatile unsigned long *)(_Exception_Vector + 0x4)) )
#define pExceptionSWI ( *((volatile unsigned long *)(_Exception_Vector + 0x8)) )
#define pExceptionPABORT ( *((volatile unsigned long *)(_Exception_Vector + 0xc)) )
#define pExceptionDABORT ( *((volatile unsigned long *)(_Exception_Vector + 0x10)) )
#define pExceptionRESERVED ( *((volatile unsigned long *)(_Exception_Vector + 0x14)) )
#define pExceptionIRQ ( *((volatile unsigned long *)(_Exception_Vector + 0x18)) )
#define pExceptionFIQ ( *((volatile unsigned long *)(_Exception_Vector + 0x1c)) )
void system_vector_init( void)
{
pExceptionRESET = (unsigned long)exceptionreset;
pExceptionUNDEF = (unsigned long)exceptionundef;
pExceptionSWI = (unsigned long)SWI_handle;
pExceptionSWI1 = (unsigned long)exceptionswi;
pExceptionPABORT = (unsigned long)exceptionpabort;
pExceptionDABORT = (unsigned long)exceptiondabort;
pExceptionIRQ = (unsigned long)IRQ_handle;
pExceptionFIQ = (unsigned long)exceptionfiq;
}
雖然IRQ中斷可以成功實現跳轉,但是SWI軟中斷卻失敗。
查找三星手冊也沒有找到原因。
2、異常向量基址可以設置
s5pv210 也通過操作協處理器設置向量基址爲高地址,或者通過MMU映射到內存的任何地方,但是它具有更靈活的功能,可以設置異常向量基址到任何地方,這樣方便移植裸機和移植RTOS。
s5pv210可以設置三種模式(安全模式 監視模式 和 非安全模式)的異常向量基址。
通過測試,通過設置異常向量基址,SWI軟中斷測試成功.
通過修改C12設置當前模式下異常向量基址:
.global _set_interrupt_vector
_set_interrupt_vector:
mcr p15, 0, r0, c12, c0, 0
mrc p15, 0, r0, c12, c0, 0
mov pc, lr
在C代碼中也可以讀取向量基址
static inline unsigned int get_vectors_address(void)
{
unsigned int temp;
/* read SCTLR */
__asm__ __volatile__(
"mrc p15, 0, %0, c1, c0, 0\n"
:"=r"(temp)
:
);
if (temp & (1<<13))
return (unsigned int ) 0xffff0000;
/* read VBAR */
__asm__ __volatile__("mrc p15, 0, %0, c12, c0, 0\n"
: "=r" (temp) : );
return (unsigned int ) temp;
}
3、軟中斷
通過 “swi xxx” 或者 “svc xxx”可以觸發軟中斷, xxx必須是立即數,不能是 寄存器。
軟中斷觸發之後,處理器(硬件上)會自動把 swi的下一條指令,保存到 svc模式下的lr,把當前下的cpsr保存到 svc模式下的spsr。swi必須有下一條指令,並且可以正常運行。
所以,可以這樣實現swi觸發函數
switest:
stmfd sp!, {fp, lr}
swi 0x8
ldmfd sp!, {fp, pc}
swi的下一條指令 正好可以把swi中斷完成之後的操作 放到switest函數後面。
swi的處理函數可以這樣完成:
swi_handle:
stmfd sp!, {r0-r12, lr}
mov r1, r0
mrs r0, spsr
stmfd sp!, {r0}
tst r0, #0x20
ldrne r0, [lr, #-2]
bicne r0, r0, #0xff00
ldreq r0, [lr, #-4]
biceq r0, r0, #0xff000000
bl c_swi_handler
ldmfd sp!, {r0}
msr spsr_cf, r0
ldmfd sp!, {r0-r12, pc}^
先保存寄存器,再保存spsr,因爲不知道swi處理的過程中有沒有再次異常發生,注意判斷c程序是不是thump編譯的,所以需要檢測spsr的thump標誌位。 處理完成後,處理器會從svc模式返回到 執行swi之前的模式。
4、程序運行
Timer0IntCounter = 0
Timer0IntCounter = 1
Timer0IntCounter = 2
swi test:1
c_swi_handler:8,arg:3
Timer0IntCounter = 3
Timer0IntCounter = 4
Timer0IntCounter = 5
swi test:2
c_swi_handler:8,arg:6
Timer0IntCounter = 6
Timer0IntCounter = 7
Timer0IntCounter = 8
swi test:3
c_swi_handler:8,arg:9
Timer0IntCounter = 9
Timer0IntCounter = 10
Timer0IntCounter = 11
swi test:4
demo鏈接http://download.csdn.net/detail/liujia2100/8102515