【入门】ARM开发板上的Hello World
搞了三天,终于出来了。虽然狂简单,但是这是我的一大步。发个帖子纪念一下。如果这些东西对你有用,请你留言让我知道。哪怕就是一个“顶”字,也是对我的鼓励。
谢谢。
说明:
硬件是一块以前的人开发后遗留下来的ARM开发板,芯片内部的rom支持xmodem协议,即:可以通过串口下载程序并执行。这个串口就是代码中用来打出Hello World的串口0,波特率为38400。
Start.s文件内容
-------------------------
/*
引导程序
通常引导程序需要初始化硬件等等。
但是当前的测试程序只需要输出Hello World,完全在内存里面运行,因此不需要初
始化硬件。唯一需要用到的外设UART0已经被芯片内部的程序初始化过了
amain和bmain都可以作为主入口(当然,输出的内容会不一样)
*/
.global _start
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.section ".text "
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
_start:
b ResetHandler
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
ResetHandler:
@bl to c function
ldr pc,=amain
-------------------------
HelloWorld.c文件内容
-------------------------
/*
0x20060000是UART0的地址
bmain函数中的asm内容和写在start.s中是同一个效果
*/
void uart_write_chr(unsigned char chr)
{
(*((volatile unsigned char *)(0x20060000))) = chr;
}
void bmain(void)
{
int i = 0;
intj;
asm( "ldr r0,=0x0D ");
asm( "ldr r1,=0x20060000 ");
asm( "str r0,[r1] ");
asm( "ldr r0,=0x0A ");
asm( "ldr r1,=0x20060000 ");
asm( "str r0,[r1] ");
for(i = 0;i < 100;i++)
{
for(j = 0;j < 500;j++)
;
asm( "ldr r0,=0x48 ");
asm( "ldr r1,=0x20060000 ");
asm( "str r0,[r1] ");
}
}
int amain(int argc,char* argv[])
{
char* str = "\nHello World!\n ";
char*pStr = str;
pStr = str;
bmain();
while(*pStr != '\0 ')
{
uart_write_chr(*pStr);
pStr++;
}
return 0;
}
-------------------------
MakeFile文件内容
-------------------------
#ram.ld是一个非常关键的文件,它制定了链接器的工作方式
#ram.ld的注释部分需要仔细阅读
CROSS = arm-elf-
AS = $(CROSS)as
LD = $(CROSS)ld
CC = $(CROSS)gcc
OBJCOPY = $(CROSS)objcopy
LDFLAGS= -T ram.ld
LIBS= /tools/H-i686-pc-cygwin/lib/gcc-lib/arm-elf/3.0/libgcc.a \
/tools/H-i686-pc-cygwin/arm-elf/lib/libc.a
all: start.bin
start.bin:start.o HelloWorld.o
$(LD) $(LDFLAGS) -o start.elf start.o HelloWorld.o $(LIBS)
$(OBJCOPY) -O binary \
--only-section=.rodata \
--only-section=.data \
--only-section=.bss start.elf start.data
$(OBJCOPY) -O binary --only-section=.text start.elf start.text
cat start.text start.data > start.bin
rm -f *.o
rm -f *.elf
rm -f *.data
rm -f *.text
start.o:Start.s
$(CC) -o start.o -c Start.s
HelloWorld.o:HelloWorld.c
$(CC) -fno-builtin -o HelloWorld.o -c HelloWorld.c
clean:
rm -f *.o
rm -f *.elf
rm -f *.data
rm -f *.text
rm -f *.bin
-------------------------
ram.ld文件内容
-------------------------
/*控制链接器的行为,程序的起始地址为0x30005000,因此,编译好
的程序通过xmodem下载到内存中时必须以0x30005000为起点,否则
执行会出错*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.text 0x30005000: { /* Real text segment*/
_text = .;/* Text and read-only data*/
*(.text)
. = ALIGN(4);
_etext = .;/* End of text section*/
}
.rodata : {
__rodata_start = .;
*(.rodata)
. = ALIGN(4);
_erodata = .;
}
.data : {
__data_start = .;
*(.data)
. = ALIGN(4);
_edata = .;
}
.bss : {
__bss_start = .;/* BSS*/
*(.bss)
. = ALIGN(4);
_end = .;
}
}
-------------------------
[解决办法]
呵呵,我也是新手,刚考上研,以后搞嵌入式这方面,什么都还不懂呢
[解决办法]
up,潜入式了解不多,支持一下!
[解决办法]
顶
[解决办法]
uart_write_chr(*pStr);
莫非是用UART与PC通信,然后显示字符串?
呵呵。我以前在ARC DSP上也做过。是ARC设备端与PC通过UART和COM进行通信。
我当时在PC端用得是MFC,将设备端传过来的字符串显示在指定控件上,如文本框,列表框等,并且保存到日志文件中。日志文件中还有两者进行通信的协议信息。
这个功能就像是PC上对设备端的Debug Monitor,这也是我进公司第一个所完成的比较完整的作品。
[解决办法]
强顶
[解决办法]
狂顶 非常不错哈
[解决办法]
我支持楼主
[解决办法]
汇编啊,强啊...
[解决办法]
厉害!强鼎!!!