>>Drew的主页---->程序示例---->ARM Boot

主页

VxWorks

ARM

PowerPC

硬件驱动

网络协议

程序示例

下载

个人兴趣

 

ARM Boot 示例

 

   程序主要作用是通过串口下载VxWorks到ARM Flash ROM,主要过程是初始化ARM硬件,初始化串口UART1,从串口接收VxWorks image到DRAM,初始化Flash ROM.最后将DRAM中的VxWorks写入Flash ROM. ARM 串口与PC机串口连接,由PC机下载(download)VxWorks 到主板Flash ROM.

该程序对学习和理解ARM编程很有帮助.为了便于理解,这里我全部采用实际地址,不用宏定义.

程序语言为 ARM 汇编,具体过程参考ARM编程,具体寄存器接口定义参见ARM硬件手册


VramBaseAddress EQU 0xC0000000                ;DRAM起始地址,在ARM硬件地址映射定义,见ARM编程
Length1    EQU        0x100                  


FlashBase         EQU         0x70000000      ;Flash的基地址,在Boot模式下,为0x70000000
MMUCP             CP         15                ;协处理器15

    AREA |C$$code|, CODE, READONLY

    ENTRY

    EXPORT main

main
        MOV         r14, #0x70                ;设置MMU无效, 32位模式, Little endian
        MCR         MMUCP, 0, r14, c1, c0, 0

        MRS         r14, CPSR
        BIC         r14, r14, #0x1f             ;Mask
        ORR         r14, r14, #0xc0 + 0x13   ;关闭所有 IRQ FIQ, 用SVC32 模式
        MSR         CPSR, r14

        LDR         r11, =0x80000000         ;内部寄存器基地址 0x80000000
        LDR         r12, =0x80001000

        MOV         r0, #0

        STR         r0, [r11, #0x280]        ;disable 所有中断
        STR         r0, [r12, #0x280]

        LDR         r0, =0x840100            ;在系统控制寄存器SYSCON1中
        STR         r0, [r11, #0x100]        ;使能外部时钟 EXCKEN 和串口 UART1

 
        LDR         r0, =0x06                ;在系统控制寄存器SYSCON2中
        STR         r0, [r12, #0x100]        ;使能16-bit DRAM, 键盘KBD6

        LDR         r0, =0x03010100          ;在存储控制寄存器MEMCFG1中
        STR         r0, [r11, #0x180]        ;设置外设数据线宽度CS0:16位,CS1,2:32位,CS3:8位

;特别注意:

  1. 如设置线宽为16位,由于CPU是32位,CPU会把32位数据分两次操作写入,每次写16位,这样对32位的外设来说是一种浪费

例如:       LDR      r0, =0x10000000
            LDR      r1, =0x12345678
            STR      r1,[r0]
实际情况是 第一次写入地址0x10000000的数据是 0x1234
          第二次写入地址0x10000002的数据是 0x5678

示波器上观察的情况是一个片选信号/CS低电平范围内,有两个写入信号/WE低电平.

  1. 如设置线宽为32位,CPU会把32位数据一次写入,如果外设是16位的话,如ISA网卡,就会造成高16位丢失.

例如:       LDR      r0, =0x10000000
            LDR      r1, =0x12345678
            STR      r1,[r0]
实际情况是 一次写入地址0x10000000的数据是 0x12345678

          

        LDR         r0, = 0xff               ;DRAM刷新率refresh rate,设置要适当,否则数据丢失
        STR         r0, [r11, #0x200]

        LDR         r13, =0xc0020000         ;设置堆栈 Stack, r13 为ARM定义的堆栈指针
;Init OK
        LDR         r0, =receiving_msg
        BL         printmsg

        BL         dram_test                 ;跳转指令,执行测试DRAM

        LDR         r0, =startloader_cmdmsg
        BL         printmsg

        BL         Beep

        LDR         r0, =0x60005             ;设置波特率 38400, 8位
        LDR         r11, =0x80000000
        STR         r0, [r11, #0x4c0]        ;初始化串口 UART
;Receive data and save it to buffer        ;开始接收数据
        LDR         r12, =SaveAddr             ;First 8 bytes are start address and length
;Receive address
        LDR         r5, =0x4                 ;Read first 4 bytes
        MOV         r0, #0
rx_loop1
        LDR         r1, [r11, #0x140]        ;检查系统状态寄存器System Status Register 1
        TST         r1, #0x00400000           ;UART1 Rx 是否为空
        BNE         rx_loop1                  ;等待数据 Wait data
        LDR         r1, [r11, #0x480]         ;读数据 Read data
        AND         r1, r1, #0xff
        ORR         r0, r1, r0, ROR #8
        SUBS    r5, r5, #1
        BNE         rx_loop1
        MOV         r0, r0, ROR #8

        STR         r0, [r12]
        ADD         r12, r12, #4

;Receive count
        LDR         r12, =Count
        LDR         r5, =0x4                 ;Read second 4 bytes
        MOV         r0, #0
rx_loop2
        LDR         r1, [r11, #0x140]        ;检查系统状态寄存器System Status Register 1
        TST         r1, #0x00400000           ;UART1 Rx 是否为空
        BNE         rx_loop2                  ;等待数据 Wait data
        LDR         r1, [r11, #0x480]        ;读数据 Read data
        AND         r1, r1, #0xff
        ORR         r0, r1, r0, ROR #8
        SUBS    r5, r5, #1
        BNE         rx_loop2
        MOV         r0, r0, ROR #8

        STR         r0, [r12]
        MOV         r6, r0                     ;Save the count to r6

;Receive data
        MOV         r5, r0
        MOV         r9, #0
        LDR         r10, =BufferBase
        MOV         r12, #0
rx_loop3
        LDR         r1, [r11, #0x140]         ;System Status Register 1
        TST         r1, #0x00400000           ;UART1 Rx Empty
        BNE         rx_loop3                  ;Wait data
        LDR         r1, [r11, #0x480]         ;Read data
        AND         r1, r1, #0xff
        STRB    r1, [r10, r12]
        ADD         r12, r12, #1

nextbyte                                     ;读下一个字节
        SUBS    r5, r5, #1
        BNE         rx_loop3
;Receive data OK                            ;数据接收完毕

        MOV         r1, #0x31
        BL         send_char
        MOV         r1, #0x0d
        BL         send_char
        MOV         r1, #0x0a
        BL         send_char

;Save it to Flash ROM                         把数据写入Flash ROM

    写入Flash参见Flash ROM驱动 部分