用openjtag调试s3c2440裸机程序

  本系列使用的硬件环境是友善之臂的 mini2440,百问网的OpenJtag,所有程序在 linux gcc下编译, 具体硬件设置 软件环境搭建可见openjtag 文档:
  编译器使用友善之臂的 4.4.3 :

$ arm-linux-gcc -v
Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: /opt/FriendlyARM/mini2440/build-toolschain/working/src/gcc-4.4.3/configure --build=i386-build_redhat-linux-gnu --host=i386-build_redhat-linux-gnu --target=arm-none-linux-gnueabi --prefix=/opt/FriendlyARM/toolschain/4.4.3 --with-sysroot=/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi//sys-root --enable-languages=c,c++ --disable-multilib --with-arch=armv4t --with-cpu=arm920t --with-tune=arm920t --with-float=soft --with-pkgversion=ctng-1.6.1 --disable-sjlj-exceptions --enable-__cxa_atexit --with-gmp=/opt/FriendlyARM/toolschain/4.4.3 --with-mpfr=/opt/FriendlyARM/toolschain/4.4.3 --with-ppl=/opt/FriendlyARM/toolschain/4.4.3 --with-cloog=/opt/FriendlyARM/toolschain/4.4.3 --with-mpc=/opt/FriendlyARM/toolschain/4.4.3 --with-local-prefix=/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi//sys-root --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-c99 --enable-long-long --enable-target-optspace
Thread model: posix
gcc version 4.4.3 (ctng-1.6.1) 

  路径

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;
}

  这个程序实现的功能是点亮led 灯,并实现流水效果。其中高电平熄灭 led 灯。

  链接脚本把两个文件链接成一个独立的二进制文件: ( 使用开始的 4K 字节内存)

SECTIONS {
    . = 0x00;
    .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

  这里选择openjtag,OpenJTag是一个开源项目(包含软件和硬件),采用GNU GPL license: http://www.openjtag.org/。
  首先编译leds程序,输入make即可:

  然后按照百问网的教程配置openjtag ,配置完毕之后执行如下命令打开openocd:

openocd -f /etc/openocd/interface/openjtag.cfg -f /etc/openocd/target/samsung_s3c2440.cfg

  并且保持运行不退出状态。
  在 telnet 界面,先执行“load_image leds/leds_elf”加程序,它会根据 leds_elf 里面的信息 把可执行代码加载到地址为 0 的内存处,“load_image leds/leds.bin 0x0”可以达到同样的效 果;然后执行“resume 0x0”命令执行程序。如:
用openjtag调试s3c2440裸机程序_第1张图片

  这里有些情况需要注意:
* 要把 mini2440 开关打到从 nandflash 启动,并且最好把 nandflash 内容擦除(用supervivi ),防止 nandflash 里面有东西影响。
* 因为从 nandflash 启动所以程序跑在开始的4K SRAM内存里面。
* 汇编语言文件开头的位置标号必须是 _start: 如果是其它的则会导致 OpenJtag 无法识别,load 之后 用si指令执行导致 PC指针到未知的位置
* 如果要单步调试就要读懂生成的 leds.dis 汇编文件。这个应该算是嵌入式基本技能吧。

这里放上教程中的调试过程:
用openjtag调试s3c2440裸机程序_第2张图片

工程文件地址:
https://www.dropbox.com/sh/dx7xuffxoorg1l3/AAD9dnYzkcANDRzQ8K6SC_vta?dl=0
还是用国外的网盘比较靠谱,不会时不时的倒闭,或者屏蔽。~~

你可能感兴趣的:(嵌入式,openJTag,led流水,反汇编调试)