1. 设置 异常向量表,即在 0x0 – 0x1c 位置放置7条跳转指令(其中 0x14 为空)
ENTRY
b ColdReset
b Enter_UNDEF ;UndefinedInstruction
b Enter_SWI ;syscall_handler or SWI
b Enter_PABORT ;PrefetchAbort
b Enter_DABORT ;DataAbort
b . ;ReservedHandler
b IRQ_Handler ;IRQHandler
b Enter_FIQ ;FIQHandler
2. 分别实现每种异常的处理程序,其中包括 Reset_Handler、Undefined_Handler、SWI_Handler、Prefetch_Handler、Abort_Handler、IRQ_Handler、FIQ_Handler。
IMPORT __use_no_semihosting_swi
ENTRY
IMPORT ColdReset
IMPORT Enter_UNDEF
IMPORT Enter_SWI
IMPORT Enter_PABORT
IMPORT Enter_DABORT
IMPORT IRQ_Handler
IMPORT Enter_FIQ
ldr pc, = ColdReset ;reset
ldr pc, = Enter_UNDEF ;UndefinedInstruction
ldr pc, = Enter_SWI ;syscall_handler or SWI
ldr pc, = Enter_PABORT ;PrefetchAbort
ldr pc, = Enter_DABORT ;DataAbort
b . ;ReservedHandler
ldr pc, = IRQ_Handler ;IRQHandler
ldr pc, = Enter_FIQ ;FIQHandler
LTORG ; for save exception address
ColdReset主要工作有禁用中断,初始化堆栈,拷贝中断向量表到0地址。
LTORG参考http://hi.baidu.com/zpf912/blog/item/99eb914291cff81a72f05d68.html
3. 程序从 Reset_Handler 进入后,需要首先进行相关硬件的初始化操作,例如 初始化SDRAM、CPU speed、Interrupt Controller、UART、timer 等。
这一步,至少要关中断,禁用看门狗。否则程序一不小心就飞了。。
ldr r0, = WTCON ;watch dog disable
ldr r1, = 0x0
str r1,[r0]
ldr r0, = INTMSK
ldr r1, = 0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0, = INTSUBMSK
ldr r1, = 0x7ff ;all sub interrupt disable, 2002 / 04 / 10
str r1,[r0]
上面说的很多硬件的操作主要是留给后面用C语言写。
因为下面的通过设置堆栈后就可以进入到C语言的入口了。
4.建立每种异常状态下的系统堆栈,为了简单起见可以只在 svc 态 和 irq 态下的建立堆栈:setup_svc_stack ,setup_irq_stack。
IMPORT SVCStack
IMPORT UndefStack
IMPORT IRQStack
IMPORT AbortStack
IMPORT FIQStack
InitStacks
;Don ' t use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.50 , ' msr cpsr,r1 ' can be used instead of ' msr cpsr_cxsf,r1 '
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE | NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp, = UndefStack
orr r1,r0,#ABORTMODE | NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp, = AbortStack
orr r1,r0,#IRQMODE | NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp, = IRQStack
orr r1,r0,#FIQMODE | NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp, = FIQStack
;bic r0,r0,#MODEMASK | NOINT
orr r1,r0,#SVCMODE | NOINT
msr cpsr_cxsf,r1 ;SVCMode
ldr sp, = SVCStack
;USER mode is not initialized.
mov pc,lr ;The LR register may be not valid for the mode changes.
5. 强制 ARM 处理器状态转换为 svc 管理态。
6.跳转到uC/OS-II 代码的 main 入口,实际上是编译链接后产生的 __main 入口
{
// MMU_Init();
s3c2410_cpu_init();
Uart_Init( 0 , 115200 );
Uart_Init( 2 , 9600 );
printk( " \nBegin to run uC/OS-II!\n " );
hudelay( 0 ); // 计算延时循环
// init_SIO();
#if (USE_YAFFS==0)
NandFlash_init();
#endif
uHALr_InitInterrupts();
uHALr_InitTimers();
uHALr_InterruptRequestInit();
}