手里一直有块友善之臂的mini2440,一直没用,最近拿来用用,先从裸机程序编写起,慢慢往上面一步一步折腾起。
环境是 win10上安装VM,VM中安装Ubuntu16.04。
交叉编译环境是 arm-linux-gcc 4.43版。
折腾的几天终于把裸板的Led灯点亮了,因为以前没接触过Makefile和lds,所以时间稍微长了些。
Makefile和lds及启动代码都是一个板子运行的基础。
下面给出我参考几方代码,编写的可以点亮led的程序。
led.c
#define GPIOBCON (*(volatile unsigned long *) 0x56000010)
#define GPIOBDAT (*(volatile unsigned long *) 0x56000014)
#define GPIOBBUP (*(volatile unsigned long *) 0x56000018)
int main()
{
GPIOBCON = 0x00004400;
GPIOBDAT = 0x00000000;
return 0;
}
led.c 代码教简单,仅仅查看数据手册查出寄存器地址,按要求操作就好。
crt0.S
.text
.global _start
_start:
ldr r0, =0x53000000 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop
.text 指定后续编译内容放入代码段。
.global 定义一个全局可见名字。
之后编译此程序可使程序跳入 main 中运行。
led.lds
SECTIONS {
. = 0x00000000;
. = ALIGN(4);
.text :
{
crt0.o(.text)
*(.text)
}
. = ALIGN(4);
.data :
{
*(.data)
}
. = ALIGN(4);
.bss :
{
*(.bss)
}
}
.lds 存放存储信息,
. = 0x00000000; 表示当前地址为 0,
. = ALIGN(4); 为 4 字节对齐。
.text 为代码段,最前存放 crt0.o 表示最先存储 crt0.S 编译代码。
Makefile
all : led.o crt0.o
arm-linux-ld -Tled.lds -o led.elf led.o crt0.o
arm-linux-objcopy -O binary led.elf led.bin
crt0.o : crt0.S
arm-linux-gcc -g -c -o $@ $^
led.o : led.c
arm-linux-gcc -g -c -o $@ $^
.PHONY: clean
clean:
rm *.o led.elf led.bin
Makefile 运用各编译命令,编译出. bin 文件,此文件即刻烧录 S3C2440 中验证结果。
烧录程序建议使用友善之臂开发的 miniTools,有 Win 及 Linux 客户端。