又重新做回了嵌入式,想把以前学到的东西从头复习一下。首先从裸机编程开始。
本系列使用的硬件环境是友善之臂的 mini2440,百问网的OpenJtag,所有程序在 linux gcc下编译, 具体硬件设置 软件环境搭建可见openjtag 文档:
编译器使用友善之臂的 4.4.3 。编译器配置 /etc/profile:
PATH="$PATH:/opt/FriendlyARM/toolschain/4.4.3/bin" export PATH注意如果在 /etc/provile 里面修改了编译器 之后,只是 source /etc/profile 还是不够的,无法调整所用编译器路径。 正确做法是 先 source /etc/environment 然后再 source /etc/profile
第一个程序是 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; }
链接脚本把两个文件链接成一个独立的二进制文件: ( 使用开始的 4K 字节内存)
SECTIONS { . = 0x00000000; .text : { *(.text) } .rodata ALIGN(4) : {*(.rodata)} .data ALIGN(4) : { *(.data) } .bss ALIGN(4) : { *(.bss) *(COMMON) } }
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指针到未知的位置!!。