在ARM开发板上实现了 一个最简单的HelloWorld程序(参考了G-bios上半部分)
现在贴出来,与大家分享一下一个最简单的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 编辑 ]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
great! 抛玉引玉,大家都来玩玩,把自己的“hello, world”贴上来!
#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 编辑 ]
#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
#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
longxinhui,你里面出现magic number太多,这样代码的可读性不好。
@ 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
#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
and, no need use "ldr pc, .." for near jump in such a simple case.
I know how to do, thanks