ARM开发板上的Hello World

来源:互联网 发布:js重新加载指定div 编辑:程序博客网 时间:2024/05/17 04:02
 说明:
硬件是一块以前的人开发后遗留下来的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   =   .;
}

}
-------------------------------------------------------------

编译环境为   cygwin+ARM   的交叉编译器。这是在windows下面完成的。linux还没有试过。暂时也不打算试。
ram.ld中的内容我自己也还没有完全搞懂,有懂的人不妨贴出心得来。


arm-elf-gcc系列工具网上可以找到现成的安装包,给linux用的,一步到位解决问题,地址在:
http://www.uclinux.org/pub/uClinux/arm-elf-tools/arm-elf-tools-20030314.sh
也可以用arm-linux-gcc工具集,下载地址在
ftp://ftp.arm.linux.org.uk/pub/armlinux/toolchain/cross-3.2.tar.gz
这个需要手动设置路径的

曾尝试自己编译arm-linux-gcc工具集,悲惨地失败鸟……GNU的东西真是博大精深



这个程序用arm-gcc编译后,用linux下的下载工具下载,也可以执行