免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4595 | 回复: 12
打印 上一主题 下一主题

在ARM开发板上实现了 一个最简单的HelloWorld程序(参考了G-bios上半部分) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-25 19:35 |只看该作者 |倒序浏览
现在贴出来,与大家分享一下一个最简单的HelloWorld 程序。
部分代码参考了G-bios的上半部份。


简要分析一下,标号TigerEntry是程序的入口地址,CPU在上电复位后执行该处的第一条指令,即 “ldr pc,vect_rest”。

本程序主要向大家演示了如何让CPU在上电复位后以最快的速度从串口控制台中输出“Hello Maxwit”信息。
最后一直让CPU处于空转状态。

写得比较乱,有不当之处请大家指正,详细的代码如下:




#define AT91SAM926X_WDT_BASE        0xfffffd40
#define AT91SAM926X_PA_PMC          0xfffffc00
#define PMC_IDR                     0x64
#define PMC_PLLAR                   0x28
#define PMC_SR                      0x68
#define PMC_MCKR                    0x30


#define AT91SAM926X_PIOA_BASE          0xfffff400
#define PIO_PER                        0x00
#define PIO_PDR                        0x04
#define PIO_OER                        0x10
#define PIO_CODR                       0x34
#define PIO_ASR                        0x70

#define AT921SAM926X_DEBUG_BASE        0xfffff200

.global TigerEntry
.global Hang

TigerEntry:
        ldr pc,vect_rest
        ldr pc,vect_undef
        ldr pc,vect_swi
        ldr pc,vect_iabort
        ldr pc,vect_dabort
        .word (TigerEnd-TigerEntry)
        ldr pc,vect_irq
        ldr pc,vect_fiq

vect_rest:
        .word handle_reset
vect_undef:
        .word handle_undef
vect_swi:
        .word handle_swi
vect_iabort:
        .word handle_iabort
vect_dabort:
        .word handle_dabort
vect_irq:
        .word handle_irq
vect_fiq:
        .word handle_fiq

handle_fiq:
handle_irq:
handle_dabort:
handle_iabort:
handle_swi:
handle_undef:
handle_reset:
        msr cpsr,#(0x13 | 1<<6 | 1<<7)

        @now to disable the watch dog
        ldr r0,=AT91SAM926X_WDT_BASE
        mov r1,#(1<<15)
        str r1,[r0,#4]

        
        @now to light the LED
        ldr r0,=AT91SAM926X_PIOA_BASE

        mov r1,#(1<<14)
        str r1,[r0,#PIO_PER]
        str r1,[r0,#PIO_OER]        
        str r1,[r0,#PIO_CODR]

        mov r1,#(1<<23)
        str r1,[r0,#PIO_PER]
        str r1,[r0,#PIO_OER]        
        str r1,[r0,#PIO_CODR]


        @now to initialize the system clock
        ldr r0,=AT91SAM926X_PA_PMC

        mvn r1,#0
        str r1,[r0,#PMC_IDR]

        ldr r1,=0x2060bf09
        str r1,[r0, #PMC_PLLAR]
L1:
        ldr r1,[r0,#PMC_SR]
        adds r1,r1,#2
        beq L1
        

        ldr r1,=0x102
        str r1,[r0,#PMC_MCKR]

L2:
        ldr r1,[r0,#PMC_SR]
        tst r1,#8
        beq L2


        @now to configure PioA port for debug unit
        ldr r0,=AT91SAM926X_PIOA_BASE
        mov r1,#(3<<9)
        str r1,[r0,#PIO_PDR]
        str r1,[r0,#PIO_ASR]

        @now to init debug unit
#define CPU_CLOCK        208305913
#define M_CLOCK                (CPU_CLOCK/2)
#define BOUND_RATE        (M_CLOCK/(16*115200))

#define DEBUG_IDR        0x0c
#define DEBUG_CR        0x00
#define DEBUG_BRGR        0x20
#define DEBUG_MR        0x04
#define DEBUG_SR        0x14
#define DEBUG_THR        0x1c
#define DEBUG_CIDR        0x40

        ldr r0,=AT921SAM926X_DEBUG_BASE        
        mvn r1,#0
        str r1,[r0,#DEBUG_IDR]
        
        mov r1,#0x10c
        str r1,[r0,#DEBUG_CR]
        
        mov r1,#0x50
        str r1,[r0,#DEBUG_CR]
        
        @set boudrate
        ldr r1,=BOUND_RATE
        str r1,[r0,#DEBUG_BRGR]
        
        mov r1,#0x0800
        str r1,[r0,#DEBUG_MR]

        
        ldr r2,.L2
        mov r3,#0
L3:
        ldr r1,[r0,#DEBUG_SR]
        tst r1,#2
        beq L3
        
        ldr r4,[r2,r3]
        @cmp r4,#0
        @beq Hang

        add r3,r3,#1
        cmp r3,#14
        beq Hang

        str r4,[r0,#DEBUG_THR]
        b L3

        @Read chip id
        
Hang:
        b Hang



.L2:
        .word        .L1


        .data
        .align 2
.L1:
        .asciz        "Hello Maxwit!"

[ 本帖最后由 tigermmx 于 2009-9-25 19:52 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-09-25 20:00 |只看该作者
great! 抛玉引玉,大家都来玩玩,把自己的“hello, world”贴上来!

论坛徽章:
0
3 [报告]
发表于 2009-09-25 21:04 |只看该作者

这个是我的上半部,请大家指正

#define AT91SAM926X_PA_WDTC        0xFFFFFD40
#define WDTC_WDCR                  0x00
#define WDTC_WDMR                  0x04
#define WDTC_WDSR                  0x08

#define AT91SAM926X_PA_PMC         0xFFFFFC00
#define PMC_SCER                   0x00
#define PMC_SCDR                   0x04
#define PMC_SCSR                   0x08
#define PMC_PCER                   0x10
#define PMC_PCDR                   0x14
#define PMC_PCSR                   0x18
#define PMC_MOR                    0x20
#define PMC_MCFR                   0x24
#define PMC_PLLAR                  0x28
#define PMC_PLLBR                  0x2c
#define PMC_MCKR                   0x30
#define PMC_PCKR                   0x40
#define PMC_IER                    0x60
#define PMC_IDR                    0x64
#define PMC_SR                     0x68
#define PMC_IMR                    0x6c

#define AT91SAM926X_PA_PIOA        0xFFFFF200
#define AT91SAM926X_PA_PIOB        0xFFFFF400
#define AT91SAM926X_PA_PIOC        0xFFFFF600
#define AT91SAM926X_PA_PIOD        0xFFFFF800
#define AT91SAM926X_PA_PIOE        0xFFFFFA00
#define PIO_PER                    0x000
#define PIO_PDR                    0x004
#define PIO_PSR                    0x008
#define PIO_OER                    0x010
#define PIO_ODR                    0x014
#define PIO_OSR                    0x018
#define PIO_IFER                   0x020
#define PIO_IFDR                   0x024
#define PIO_SODR                   0x030
#define PIO_CODR                   0x034
#define PIO_ODSR                   0x038
#define PIO_PDSR                   0x03c
#define PIO_IER                    0x040        
#define PIO_IDR                    0x044
#define PIO_IMR                    0x048
#define PIO_ISR                    0x04C        
#define PIO_MDDR                   0x054
#define PIO_PUDR                   0x060
#define PIO_PUER                   0x064
#define PIO_ASR                    0x070
#define PIO_BSR                    0x074

#define AT91SAM926X_PA_DBGU        0xFFFFEE00
#define US_CR                      0x000
#define US_MR                      0x004
#define US_IER                     0x008
#define US_IDR                     0x00c
#define US_IMR                     0x010
#define US_CSR                     0x014
#define US_RHR                     0x018
#define US_THR                     0x01c
#define US_BRGR                    0x020
#define US_RTOR                    0x024
#define US_TTGR                    0x028
#define US_FIDI                    0x040
#define US_NER                     0x044
#define US_IF                      0x04c
#define US_RPR                     0x100
#define US_RCR                     0x104
#define US_TPR                     0x108
#define US_TCR                     0x10c
#define US_RNPR                    0x110
#define US_RNCR                    0x114
#define US_TNPR                    0x118
#define US_TNCR                    0x11c
#define US_PTCR                    0x120
#define US_PTSR                    0x124


#define MAINCK             18432000
#define MULA               31
#define DIVA               3
#define OUTA               2
#define MDIV               2
#define PCK                (MAINCK * (MULA + 1) / DIVA)
#define MCK                (PCK / 2)
#define DBUG_BAUD_RATE     115200
#define DBUG_BAUD_RATE_CD  (MCK / (DBUG_BAUD_RATE * 16))

.global Start

Start:
        b DisableWD
        b DisableWD
        b DisableWD
        b DisableWD
        b DisableWD
        .word Startend - Start
        b DisableWD
        b DisableWD


DisableWD:
        @disable watchdog
        ldr r0, =AT91SAM926X_PA_WDTC
        mov r1, #(0x1 << 15)
        str r1, [r0, #WDTC_WDMR]


InitClock:
        ldr r0, =AT91SAM926X_PA_PMC

        ldr r1, =(1 << 29 | MULA << 16 | OUTA << 14 | 0x3f << 8 | DIVA)
        str r1, [r0, #PMC_PLLAR]
loop1:        
        ldr r1, [r0, #PMC_SR]        
        tst r1, #2
        beq loop1

        ldr r1, =(1 << 8 | 2)
        str r1, [r0, #PMC_MCKR]
loop2:        
        ldr r1, [r0, #PMC_SR]        
        tst r1, #8
        beq loop2


InitUart:
        ldr r0, =AT91SAM926X_PA_PIOC
        @pc31 and pc30
        mov r1, #0xC0000000   
        str r1, [r0, #PIO_PDR]
        str r1, [r0, #PIO_ASR]
        
        ldr r0, =AT91SAM926X_PA_DBGU
        mvn r1, #0
        str r1, [r0, #US_IDR]
        mov r1, #(0x4 << 9)
        str r1, [r0, #US_MR]
        mov r1, #DBUG_BAUD_RATE_CD
        str r1, [r0, #US_BRGR]
        
        mov r1, #66
loop3:        
        strb r1, [r0, #US_THR]
        b loop3
        
        @get the chip's id
        ldr r1, [r0, #US_FIDI]
        ldr r2, =0x000000E0
        and r1, r2
        cmp r1, #0x000000A0
        beq OnLed
loop4:
        b   loop4


OnLed:
        ldr r0, =AT91SAM926X_PA_PIOC
        @ ds1 & pc29
        mov r1, #0x20000000
        str r1, [r0]
        str r1, [r0,#PIO_OER]
        str r1, [r0,#PIO_CODR]

loop5:
        b        loop5

[ 本帖最后由 voidjackjiang 于 2009-9-25 22:14 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-09-25 21:09 |只看该作者
#include"atmel.h"

.global GTopHalfEntry
.global Hang

GTopHalfEntry:
        ldr   pc,vect_reset
    ldr   pc, vect_undef
    ldr   pc, vect_swi
    ldr   pc, vect_iabort
    ldr   pc, vect_dabort
    .word 512
    ldr   pc, vect_irq
    ldr   pc, vect_fiq

vect_reset:
    .word handle_reset
vect_undef:
    .word handle_undef
vect_swi:
    .word handle_swi
vect_iabort:
    .word handle_iabort
vect_dabort:
    .word handle_dabort
vect_irq:
    .word handle_irq
vect_fiq:
    .word handle_fiq

handle_fiq:
handle_irq:
handle_dabort:
handle_iabort:
handle_swi:
handle_undef:
handle_reset:
    msr   cpsr, #((ARM_MODE_SVC) | (ARM_INT_MASK))

    mov   r1,#(1<<15)
    ldr   r0,=WDT
    str   r1,[r0]

@set_clock
        ldr   r0, =PMC_BASE
        ldr   r1, =(0x20<<16)|(0x3f<<|(0x20000000)|0x3
        str   r1, [r0,#CKGR_PLLAR]

L1:
        ldr   r1, [r0,#PMC_SR]
        tst   r1, #0x2
        beq   L1

        ldr   r1, =0x102
        str   r1, [r0,#PMC_MCKR]

L2:
        ldr   r1, [r0,#PMC_SR]
        tst   r1, #0x8
        beq   L2

@init_uart
        ldr   r0, =GPIOA_BASE
        ldr   r1, =(1<<9)|(1<<10)
        str   r1, [r0,#PIO_PDR]

@peripheral a
        str   r1, [r0,#PIO_ASR]

@interrupt disable
        ldr   r0, =DBUG_BASE
        mvn   r1, #0
        str   r1, [r0,#DBGU_IDR]

@Debug Unit Control Register
        mov   r1, #0x15c
@        str   r1, [r0]

@Baud rate
        mov   r1, #55
        str   r1, [r0,#DBGU_BRGR]

        mov   r1, #0x800
        str   r1, [r0,#DBGU_MR]

L5:
        ldr   r1, [r0,#DBGU_CIDR]
        and   r1, #(0x5<<5)
        cmp   r1, #0xa0
@        beq   LED
@        bne   L5

L3:
        mov   r1, #72
        str   r1, [r0,#DBGU_THR]
        mov   r1, #69
        str   r1, [r0,#DBGU_THR]
        mov   r1, #76
        str   r1, [r0,#DBGU_THR]
        mov   r1, #76
        str   r1, [r0,#DBGU_THR]
        mov   r1, #79
        str   r1, [r0,#DBGU_THR]
        b     L3

LED:
    ldr   r0,=GPIOA_BASE
    ldr   r1, =(1<<14)|(1<<23)
    str   r1,[r0]
    str   r1,[r0,#PIO_OER]
    str   r1,[r0,#PIO_CODR]
       
Hang:
        b Hang

论坛徽章:
0
5 [报告]
发表于 2009-09-25 21:10 |只看该作者
#define ARM_MODE_SVC 0x13
#define ARM_INT_MASK  1<<7
#define WDT 0xfffffd40

@GPIO_Baseaddr and offset
#define GPIOA_BASE 0xfffff400
#define PIO_PER 0x0000
#define PIO_PDR 0x0004
#define PIO_PSR 0x0008
#define PIO_OER 0x0010
#define PIO_ODR 0x0014
#define PIO_OSR 0x0018
#define PIO_IFER 0x0020
#define PIO_IFDR 0x0024
#define PIO_IFSR 0x0028
#define PIO_SODR 0x0030
#define PIO_CODR 0x0034
#define PIO_ODSR 0x0038
#define PIO_PDSR 0x003c
#define PIO_IER 0x0040
#define PIO_IDR 0x0044
#define PIO_IMR 0x0048
#define PIO_ISR 0x004c
#define PIO_MDER 0x0050
#define PIO_MDDR 0x0054
#define PIO_MDSR 0x0058
#define PIO_PUDR 0x0060
#define PIO_PUER 0x0064
#define PIO_ASR 0x0070
#define PIO_BSR 0x0074
#define PIO_ABSR 0x0078
#define PIO_OWER 0x00a0
#define PIO_OWDR 0x00a4
#define PIO_OWSR 0x00a8

@PMC_Baseaddr and offset

#define PMC_BASE 0xfffffc00
#define PMC_SCER 0x0000
#define PMC_SCDR 0x0004
#define PMC_SCSR 0x0008
#define PMC_PCER 0x0010
#define PMC_PCDR 0x0014
#define PMC_PCSR 0x0018
#define CKGR_MOR 0x0020
#define CKGR_MCFR 0x0024
#define CKGR_PLLAR 0x0028
#define CKGR_PLLBR 0x002c
#define PMC_MCKR 0x0030
#define PMC_PCK0 0x0040
#define PMC_PCK1 0x0044
#define PMC_IER  0x0060
#define PMC_IDR  0x0064
#define PMC_SR  0x0068
#define PMC_IMR  0x006c
#define PMC_PLLICPR  0x0080

@DEBUG_Baseaddr and offset

#define DBUG_BASE 0xfffff200
#define DBGU_CR 0x0000
#define DBGU_MR 0x0004
#define DBGU_IER 0x0008
#define DBGU_IDR 0x000c
#define DBGU_IMR 0x00010
#define DBGU_SR 0x00014
#define DBGU_RHR 0x00018
#define DBGU_THR 0x0001c
#define DBGU_BRGR 0x00020
#define DBGU_CIDR 0x00040
#define DBGU_EXID 0x00044
#define DBGU_FNR 0x00048

论坛徽章:
0
6 [报告]
发表于 2009-09-25 21:26 |只看该作者

回复 #5 longxinhui 的帖子

longxinhui,你里面出现magic number太多,这样代码的可读性不好。

论坛徽章:
0
7 [报告]
发表于 2009-09-25 22:56 |只看该作者

to 3#

@ diff #3 with highlight

.text
.global Start

Start:
        b DisableWD
        b DisableWD
        b DisableWD
        b DisableWD
        b DisableWD
        .word End - Start
        b DisableWD
        b DisableWD


Reset:
@ DisableWD:
        @disable watchdog
        ldr r0, =AT91SAM926X_PA_WDTC
        mov r1, #(0x1 << 15)
        str r1, [r0, #WDTC_WDMR]


@ InitClock:
        ldr r0, =AT91SAM926X_PA_PMC

        ldr r1, =(1 << 29 | MULA << 16 | OUTA << 14 | 0x3f << 8 | DIVA)
        str r1, [r0, #PMC_PLLAR]
loop1:        
        ldr r1, [r0, #PMC_SR]        
        tst r1, #2
        beq loop1

        ldr r1, =(1 << 8 | 2)
        str r1, [r0, #PMC_MCKR]
loop2:        
        ldr r1, [r0, #PMC_SR]        
        tst r1, #8
        beq loop2


@ InitUart:
        ldr r0, =AT91SAM926X_PA_PIOC
        @pc31 and pc30
        mov r1, #0xC0000000   
        str r1, [r0, #PIO_PDR]
        str r1, [r0, #PIO_ASR]
        
        ldr r0, =AT91SAM926X_PA_DBGU
        mvn r1, #0
        str r1, [r0, #US_IDR]
        mov r1, #(0x4 << 9)
        str r1, [r0, #US_MR]
        mov r1, #DBUG_BAUD_RATE_CD
        str r1, [r0, #US_BRGR]
        
        mov r1, #66
loop3:        
        strb r1, [r0, #US_THR]
        b loop3
        
        @get the chip's id
        ldr r1, [r0, #US_FIDI]
       add r1, r1, #0xE0
        cmp r1, #0x000000A0
       bne   loop5


@ OnLed:
        ldr r0, =AT91SAM926X_PA_PIOC
        @ ds1 & pc29
        mov r1, #0x20000000
        str r1, [r0, #PIO_PER]
        str r1, [r0,#PIO_OER]
        str r1, [r0,#PIO_CODR]

loop5:
        b        loop5

论坛徽章:
0
8 [报告]
发表于 2009-09-26 00:11 |只看该作者
#include"atmel.h"

.global GTopHalfEntry

GTopHalfEntry:
        ldr   pc, atmel_reset
    ldr   pc, atmel_undef
    ldr   pc, atmel_swi
    ldr   pc, atmel_iabort
    ldr   pc, atmel_dabort
    .word GTopHalfEnd - GTopHalfEntry
    ldr   pc, atmel_irq
    ldr   pc, atmel_fiq

atmel_reset:
    .word handle_reset
atmel_undef:
    .word handle_undef
atmel_swi:
    .word handle_swi
atmel_iabort:
    .word handle_iabort
atmel_dabort:
    .word handle_dabort
atmel_irq:
    .word handle_irq
atmel_fiq:
    .word handle_fiq
handle_fiq:
handle_irq:
handle_dabort:
handle_iabort:
handle_swi:

handle_reset:
    msr   cpsr, #(ARM_MODE_SVC) | (ARM_INT_MASK)

@disable watchdog
    mov   r1, #WDDIS
    ldr   r0, =WDT_BASE
    str   r1, [r0,#WDT_MR]

@onled
    ldr   r0,=GPIOA_BASE
        ldr   r1, =PA14|PA23
    str   r1,[r0]
    str   r1,[r0,#PIO_OER]

@init_clock
        ldr   r0, =PMC_BASE
        ldr   r1, =PLLAR_MULA|PLLAR_COUNT|PLLAR_BIT29|PLLAR_DIVA
        str   r1, [r0,#CKGR_PLLAR]

L1:
        ldr   r1, [r0,#PMC_SR]
        tst   r1, #0x2
        beq   L1

        ldr   r1, =0x102
        str   r1, [r0,#PMC_MCKR]

L2:
        ldr   r1, [r0,#PMC_SR]
        tst   r1, #0x8
        beq   L2

@init_uart
        ldr   r0, =GPIOA_BASE
        mov   r1, #PA9|PA10
        str   r1, [r0,#PIO_PDR]

@peripheral a
        str   r1, [r0,#PIO_ASR]

@interrupt disable
        ldr   r0, =DBUG_BASE
        mvn   r1, #0
        str   r1, [r0,#DBGU_IDR]

@Baud rate
        mov   r1, #CD
        str   r1, [r0,#DBGU_BRGR]

        mov   r1, #0x8
        str   r1, [r0,#DBGU_MR]

L3:
        mov   r1, #H
        strb   r1, [r0,#DBGU_THR]
        mov   r1, #E
        strb   r1, [r0,#DBGU_THR]
        mov   r1, #L
        strb   r1, [r0,#DBGU_THR]
        mov   r1, #L
        strb   r1, [r0,#DBGU_THR]
        b     L3

论坛徽章:
0
9 [报告]
发表于 2009-09-26 11:25 |只看该作者
原帖由 longxinhui 于 2009-9-26 00:11 发表
#include"atmel.h"

.global GTopHalfEntry

GTopHalfEntry:
        ldr   pc, atmel_reset
                    ~~~~~~~~~~~ no business with atmel!
    ldr   pc, atmel_undef
    ldr   pc, atmel_swi
    ldr   pc, atmel_iabort
    ldr   pc, atmel_dabort
  ...


and, no need use "ldr pc, .." for near jump in such a simple case.

论坛徽章:
0
10 [报告]
发表于 2009-09-26 11:33 |只看该作者
I know how to do, thanks
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP