#1. 首先了解一下ARM进入supervisor mode的方法是通过SWI指令.
#2. 参考一下starterware里的代码:
函数:
cpu.c:
void CPUSwitchToPrivilegedMode(void)
[
asm(" SWI #458752"); ]
上面函数的调用会进入SWIHandler, 这里只是做了一个参数的简单比较,当然用户也可以修改这个参数用来实现不同值的传递,达到判断不同条件,从而做不同处理的目的, mode切换就是在下面两条语句实现的。
exceptionhandler.asm:
SWIHandler:
STMFD r13!, [r0-r1, r14] ; Save context in SVC stack
LDR r0, [r14, #-4] ; R0 points to SWI instruction
BIC r0, r0, #MASK_SWI_NUM ; Get the SWI number
CMP r0, #458752
MRSEQ r1, spsr ; Copy SPSR
ORREQ r1, r1, #0x1F ; Change the mode to System
MSREQ spsr_cf, r1 ; Restore SPSR
LDMFD r13!, [r0-r1, pc]^ ; Restore registers from IRQ stack
异常向量表的排放在在startup.c里实现的。
static unsigned int const vecTbl[14]=
[
0xE59FF018,
0xE59FF018,
0xE59FF018,
0xE59FF018,
0xE59FF014,
0xE24FF008,
0xE59FF010,
0xE59FF010,
(unsigned int)Entry,
(unsigned int)UndefInstHandler,
(unsigned int)SWIHandler,
(unsigned int)AbortHandler,
(unsigned int)IRQHandler,
(unsigned int)FIQHandler
];
unsigned int start_boot(void)
[
/* Enable write-protection for registers of SYSCFG module. */
SysCfgRegistersLock();
/* Disable write-protection for registers of SYSCFG module. */
SysCfgRegistersUnlock();
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, 0, PSC_MDCTL_NEXT_ENABLE);
PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_AINTC, 0, PSC_MDCTL_NEXT_ENABLE);
/* Initialize the vector table with opcodes */
CopyVectorTable();
/* Calling the main */
main();
while(1);
]
static void CopyVectorTable(void)
[
unsigned int *dest = (unsigned int *)0xFFFF0000;
unsigned int *src = (unsigned int *)vecTbl;
unsigned int count;
for(count = 0; count < sizeof(vecTbl)/sizeof(vecTbl[0]); count++)
[
dest[count] = src[count];
]
]
对于ARM,这个异常向量表的地址有两种模式,要么放地址0,要么放地址0xFFFF0000. 在L138的ARM上,为0xFFFF0000.
程序中的中断等,将都进入这个向量表再跳转.
http://processors.wiki.ti.com/index.php/Main_Page
Think Over Before Asking.
http://www.catb.org/~esr/faqs/smart-questions.html#goal