ARM移植之BootLoader(2)
3.1硬件設備初始化
基本的硬件初始化工作包括:
·屏蔽所有的中斷;
·設置CPU的速度和時鐘頻率;
·RAM初始化;
·初始化LED
ARM的中斷向量表設置在0地址開始的8個字空間中,如下表:
每當其中的某個異常發(fā)生后即將PC值置到相應的中斷向量處,每個中斷向量處放置一個跳轉指令到相應的中斷服務程序去進行處理,中斷向量表的程序如下:
@ 0x00: Reset b Reset @ 0x04: Undefined instruction exception UndefEntryPoint: b HandleUndef @ 0x08: Software interrupt exception SWIEntryPoint: b HandleSWI @ 0x0c: Prefetch Abort (Instruction Fetch Memory Abort) PrefetchAbortEnteryPoint: b HandlePrefetchAbort @ 0x10: Data Access Memory Abort DataAbortEntryPoint: b HandleDataAbort @ 0x14: Not used NotUsedEntryPoint: b HandleNotUsed @ 0x18: IRQ(Interrupt Request) exception IRQEntryPoint: b HandleIRQ @ 0x1c: FIQ(Fast Interrupt Request) exception FIQEntryPoint: b HandleFIQ |
復位時關閉看門狗定時器、屏蔽所有中斷:
Reset: @ disable watch dog timer mov r1, #0x53000000 mov r2, #0x0 str r2, [r1] @ disable all interrupts mov r1, #INT_CTL_BASE mov r2, #0xffffffff str r2, [r1, #oINTMSK] ldr r2, =0x7ff str r2, [r1, #oINTSUBMSK] |
設置系統(tǒng)時鐘:
@init clk @ 1:2:4 mov r1, #CLK_CTL_BASE mov r2, #0x3 str r2, [r1, #oCLKDIVN] mrc p15, 0, r1, c1, c0, 0 @ read ctrl register orr r1, r1, #0xc0000000 @ Asynchronous mcr p15, 0, r1, c1, c0, 0 @ write ctrl register @ now, CPU clock is 200 Mhz mov r1, #CLK_CTL_BASE ldr r2, mpll_200mhz str r2, [r1, #oMPLLCON] |
點亮所有的用戶LED:
@ All LED on mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F ldr r2,=0x55aa str r2, [r1, #oGPIO_CON] mov r2, #0xff str r2, [r1, #oGPIO_UP] mov r2, #0x00 str r2, [r1, #oGPIO_DAT] |
設置(初始化)內存映射:
ENTRY(memsetup) @ initialise the static memory @ set memory control registers mov r1, #MEM_CTL_BASE adrl r2, mem_cfg_val add r3, r1, #52 1: ldr r4, [r2], #4 str r4, [r1], #4 cmp r1, r3 bne 1b mov pc, lr |
設置(初始化)UART:
@ set GPIO for UART mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_H ldr r2, gpio_con_uart str r2, [r1, #oGPIO_CON] ldr r2, gpio_up_uart str r2, [r1, #oGPIO_UP] bl InitUART @ Initialize UART @ @ r0 = number of UART port InitUART: ldr r1, SerBase mov r2, #0x0 str r2, [r1, #oUFCON] str r2, [r1, #oUMCON] mov r2, #0x3 str r2, [r1, #oULCON] ldr r2, =0x245 str r2, [r1, #oUCON] #define UART_BRD ((50000000 / (UART_BAUD_RATE * 16)) - 1) mov r2, #UART_BRD str r2, [r1, #oUBRDIV] mov r3, #100 mov r2, #0x0 1: sub r3, r3, #0x1 tst r2, r3 bne 1b #if 0 mov r2, #U str r2, [r1, #oUTXHL] 1: ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne 1b mov r2, #0 str r2, [r1, #oUTXHL] 1: ldr r3, [r1, #oUTRSTAT] and r3, r3, #UTRSTAT_TX_EMPTY tst r3, #UTRSTAT_TX_EMPTY bne 1b #endif mov pc, lr |
此外,vivi還提供了幾個匯編情況下通過串口打印字符的函數(shù)PrintChar、PrintWord和PrintHexWord:
@ PrintChar : prints the character in R0 @ r0 contains the character @ r1 contains base of serial port @ writes ro with XXX, modifies r0,r1,r2 @ TODO : write ro with XXX reg to error handling PrintChar: TXBusy: ldr r2, [r1, #oUTRSTAT] and r2, r2, #UTRSTAT_TX_EMPTY tst r2, #UTRSTAT_TX_EMPTY beq TXBusy str r0, [r1, #oUTXHL] mov pc, lr @ PrintWord : prints the 4 characters in R0 @ r0 contains the binary word @ r1 contains the base of the serial port @ writes ro with XXX, modifies r0,r1,r2 @ TODO : write ro with XXX reg to error handling PrintWord: mov r3, r0 mov r4, lr bl PrintChar mov r0, r3, LSR #8 /* shift word right 8 bits */ bl PrintChar mov r0, r3, LSR #16 /* shift word right 16 bits */ bl PrintChar mov r0, r3, LSR #24 /* shift word right 24 bits */ bl PrintChar mov r0, #r bl PrintChar mov r0, #n bl PrintChar mov pc, r4 @ PrintHexWord : prints the 4 bytes in R0 as 8 hex ascii characters @ followed by a newline @ r0 contains the binary word @ r1 contains the base of the serial port @ writes ro with XXX, modifies r0,r1,r2 @ TODO : write ro with XXX reg to error handling PrintHexWord: mov r4, lr mov r3, r0 mov r0, r3, LSR #28 bl PrintHexNibble mov r0, r3, LSR #24 bl PrintHexNibble mov r0, r3, LSR #20 bl PrintHexNibble mov r0, r3, LSR #16 bl PrintHexNibble mov r0, r3, LSR #12 bl PrintHexNibble mov r0, r3, LSR #8 bl PrintHexNibble mov r0, r3, LSR #4 bl PrintHexNibble mov r0, r3 bl PrintHexNibble mov r0, #r bl PrintChar mov r0, #n bl PrintChar mov pc, r4 |
評論