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。
AREA exception,CODE,READONLY
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 等。
这一步,至少要关中断,禁用看门狗。否则程序一不小心就飞了。。
ColdReset
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 UserStack
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 入口
void ARMTargetInit(void)
{
//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();
}