分类: 嵌入式
2014-01-07 20:20:09
一 head.s分析
.equ MEM_CTL_BASE, 0x48000000 //存储控制器寄存器的首地址
.equ SDRAM_BASE, 0x30000000
.text
.global _start
_start:
bl disable_watch_dog //关看门狗
bl memsetup //设置寄存器
bl copy_steppingstone_to_sdram //拷贝4k程序
ldr pc, =on_sdram //设置栈
on_sdram:
ldr sp, =0x34000000 //指向内存的最大地址,64M sdram对应0x30000000-0x34000000
bl main
halt_loop:
b halt_loop
disable_watch_dog:
mov r1, #0x53000000
mov r2, #0x0
str r2, [r1]
mov pc, lr
copy_steppingstone_to_sdram:
mov r1, #0
ldr r2, =SDRAM_BASE
mov r3, #4*1024
1:
ldr r4, [r1],#4
str r4, [r2],#4
cmp r1, r3
bne 1b
mov pc, lr
memsetup:
mov r1, #MEM_CTL_BASE
adrl r2, mem_cfg_val
add r3, r1, #52
1:
ldr r4, [r2], #4
str r4, [r1], #4
cmp r1, r3
bne 1b
mov pc, lr
.align 4
mem_cfg_val:
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7
二 led.c分析
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(volatile unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out;
while(1){
wait(30000);
GPBDAT = (~(i<<5));
if(++i == 16)
i = 0;
}
return 0;
}
1:volatile语法
关键字volatile确保本条指令不会因C编译器的优化而被省略,且要求每次直接读值。程序就会在每次需要该值的时候都读取一次内存。这是为了防止某些原因硬件会改变其值。
(volatile unsigned long *)即为强制类型转换;(volatile unsigned long *)0x56000010的意思就是把0x56000010强制转换为unsigned long类型的指针。这时(volatile unsigned long *)0x56000010就可以看做是一个指针p了。*(volatile unsigned long*)0x56000010等价于*p,也
就是取指针p的地址。
2:delay函数的写法
void wait (volatile unsigned long dly)
{
for(; dly > 0; dly--);
}
三 makefile分析
sdram.bin : head.S leds.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o leds.o leds.c
arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
arm-linux-objcopy -O binary -S sdram_elf sdram.bin
arm-linux-objdump -D -m arm sdram_elf > sdram.dis
clean:
rm -f sdram.dis sdram.bin sdram_elf *.o
1:arm-linux-gcc -c -o head.o head.c
-c 代表预处理,编译,汇编源文件,不作连接
-o 代表指定输出文件名,如果不加,输出a.out
2: arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
Arm-linux-ld 用于将多个目标文件,库文件连接成可执行文件
-T 直接用它来指定代码段,数据段等的起始地址,也可以用来指定一个连接脚本。
3: arm-linux-objcopy -O binary -S sdram_elf sdram.bin
Arm-linux-objcopy 用于复制一个目标文件到另外一个目标文件,可以进行格式转换。用此命令将elf格式转化为bin格式
-o 代表转换的格式名binary
-s 代表不从文件中复制重定位信息和符号信息到目标文件中
4:arm-linux-objdump -D -m arm sdram_elf > sdram.dis
Arm-linux-objdump 用于显示二进制信息,用来查看反汇编代码
-D 代表反汇编所有段
-m 后跟cpu框架
> 将elf文件转化为dis文件
5:rm -f sdram.dis sdram.bin sdram_elf *.o
用于删除所有被make创建的文件,当执行make clean时删除文件
-f 代表强制删除
*.o 代表所有.o文件