LED对应的引脚是GPF4、GPF5、GPF6。
使用的编译器为arm-linux-gcc-4.5.1。
包括四个文件head.S main.c main.lds Makefile。
实验目的:将main.c中点灯程序从存放地址0x400重新加载到0x800,并跳到0x800执行。
涉及到地址无关码、伪指令等概念。还有编译器链接脚本中存放地址、运行地址等概念。
对于2440,有两种存放数据的介质,NOR、NAND。其中NOR是内存接口,可以执行代码,但只读不能写入。NAND只能读,如果开关拨到NAND启动,2440会硬件把NAND开头的4K搬运到可执行、可读写的SRAM中。我们利用这4K的来做重定位的实验。对于不同启动方式时,内存是如何分布的可以看2440用户手册。
head.S
.text
.global _start
_start:
ldr r0, =0x53000000 @Close WATCHDOG
mov r1, #0x0
str r1, [r0]
mov r1,#0x400 @relacate
mov r2,#0x800
mov r3,#0x600
1:
ldr r4,[r1],#4
str r4,[r2],#4
cmp r1,r3
bne 1b
ldr sp, =1024*4 @Call C
ldr lr,=loop
bl main
@ldr pc,=main @0x800
loop:
b loop
main.c
#define GPFCON (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054)
#define GPF4_out (1<
#define GPF5_out (1<
#define GPF6_out (1<
#define GPF7_out (1<
void wait(volatile unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
GPFCON = GPF4_out|GPF5_out|GPF6_out; //Configure the gpio of led
while(1){
wait(30000);
GPFDAT = (~(i<<4)); //Turn
if(++i == 8)
i = 0;
}
return 0;
}
main.lds
SECTIONS {
. = 0x0;
first 0x00000000 : { head.o }
second 0x800 : AT(0x400){ main.o }
}
PS:
0x800是运行地址,程序链接时会假定为这个地址。
0x400是程序实际存放地址,我们需要把main.o从0x400搬运到0x800才能执行。
Makefile
objs = head.o main.o
all: $(objs)
arm-linux-ld -T main.lds $^ -o main.elf
arm-linux-objcopy -O binary -S main.elf main.bin
arm-linux-objdump -D main.elf > main.dis
clean:
rm -f *.bin $(objs) *.elf *.dis
%.o : %.c
arm-linux-gcc -march=armv4 -c -o $@ $<
%.o : %.S
arm-linux-gcc -march=armv4 -c -o $@ $<
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』