又重新做回了嵌入式,想把以前学到的东西从头复习一下。首先从裸机编程开始。
本系列使用的硬件环境是友善之臂的 mini2440,百问网的OpenJtag,所有程序在 linux gcc下编译, 具体硬件设置 软件环境搭建可见openjtag 文档:
编译器使用友善之臂的 4.4.3 。编译器配置 /etc/profile:
- PATH="$PATH:/opt/FriendlyARM/toolschain/4.4.3/bin"
- export PATH
第一个程序是 led 灯控制:
开头 汇编 文件:
- @******************************************************************************
- @ File£ºcrt0.S
- @ ¹¦ÄÜ£ºÍ¨¹ýËüתÈëC³ÌÐò
- @******************************************************************************
- #define PXT 0x12
- .text
- .global _start
- _start:
- ldr r0, =0x53000000 @ disable WATCHDOG
- mov r1, #0x0
- str r1, [r0] @
- ldr sp, =1024*4 @ stack pointer point to 4K
- bl main
- halt_loop:
- b halt_loop
主函数文件:
- #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(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(100000);
- GPBDAT = (1<< ( (i%4) + 5) );
- if(++i == 16)
- i = 0;
- }
- return 0;
- }
这个程序实现的功能是点亮led 灯,并实现流水效果。其中高电平熄灭 led 灯。
链接脚本把两个文件链接成一个独立的二进制文件: ( 使用开始的 4K 字节内存)
- SECTIONS {
- . = 0x00000000;
- .text : { *(.text) }
- .rodata ALIGN(4) : {*(.rodata)}
- .data ALIGN(4) : { *(.data) }
- .bss ALIGN(4) : { *(.bss) *(COMMON) }
- }
Makefile 脚本
- CFLAGS := -Wall -Wstrict-prototypes -g -fomit-frame-pointer -ffreestanding
- all : crt0.S leds.c
- arm-linux-gcc $(CFLAGS) -c -o crt0.o crt0.S
- arm-linux-gcc $(CFLAGS) -c -o leds.o leds.c
- arm-linux-ld -Tleds.lds crt0.o leds.o -o leds_elf
- arm-linux-objcopy -O binary -S leds_elf leds.bin
- arm-linux-objdump -D -m arm leds_elf > leds.dis
- clean:
- rm -f leds.dis leds.bin leds_elf *.o
首先运行脚本openocd.sh
- openocd -f /etc/openocd/interface/openjtag.cfg -f /etc/openocd/target/samsung_s3c2440.cfg
然后另开启一个终端启动 elf 文件调试
- arm-linux-gdb -x gdb.init leds_elf
其中 gdb.init 文件内容:
- target remote 127.0.0.1:3333
- monitor halt
- monitor arm920t cp15 2 0
- monitor step
- load
此时就可以像调试普通程序一样调试这个裸机程序。
工程文件地址:
有一点特别需要注意:
汇编语言文件开头的位置标号必须是 _start: 如果是其它的则会导致 OpenJtag 无法识别,load 之后 用si指令执行导致 PC指针到未知的位置!!。