返回信息流开发环境的建立:
手里几块开发板,arm7,arm9,Intel IXP-425,还有过几天就会寄来的Cortex-M0,真不知道用哪块好,决定采用QQ2440V3作为开发学习平台,原因很简单,附带的光盘里资料收集的很全,不用自己费那么大的力气到网上一点一点的找.
本来是打算到http://www.kegel.com/crosstool/上下载配置文件自己重新编译交叉编译工具链,但是想到最近unixcenter挂了,找不着合适的socket代理下那么多的源码,暂时作罢.
编译器暂时采用光盘自带的三个版本3.4.1,3.3.2,2.95.3,真不知道为什么要弄这么多版本.
3.3.2版本是用来编译Qtopia/Embedded的,2.95.3版本是用来编译VIVI的,3.4.1版本是用来编译内核的.
就采用3.4.1版本来编译应用程序吧.
没有把编译器放在系统目录下,统统放在了/home/$USER/arm/crosstool/里,需要设置的时候,用以下命令导入环境变量:
export PATH=$PATH:/home/$USER/arm/crosstool/3.4.1/bin
如果需要用其它两个版本,就把3.4.1改为其它两个版本号就行.
再设置一下调试和下载平台:
本来自己画了一块USB-prog的板子,打算用这个调ARM,但是不舍得花加急费,等到现在还没来,估计下周一会到.所以前几天到淘宝上买了一块Open-jtag,花了170人民币.现在正在熟悉linux下的使用,有感兴趣的同学可以站内我,我给推荐.
调试软件采用的是openocd,现在用的openocd版本是买jtag时里面附带的,有时间我会编译一个适合自己使用的.
我的工作空间设置为/home/$USER/arm/qq2440v3
把openocd权限设置为可执行,放在系统路径里,然后openocd.cfg复制到工作空间里,打开终端,进入这个目录.
然后开始设置硬件,把QQ2440V3开发板接上电源,插上JTAG线,并把JTAG插入电脑USB接口,执行命令lsusb,可以看到一项:
Bus 004 Device 006: ID 1457:5118 First International Computer, Inc. OpenMoko Neo1973 Debug board (V2+)
表明JTAG已经被系统识别.
把QQ2440V3开发板系统启动跳线调到NAND一边,然后打开开关,因为在调试中发现如果跳线在NOR一端不能得到预期的结果.
然后在工作目录下输入sudo openocd,在弹出来的信息中能看到JTAG已经能够识别出目标板:
JTAG device found: 0x07fd047d (Manufacturer: 0x23e, Part: 0x7fd0, Version: 0x0)
0x07fd047d就是ARM9TDMI的标识码.
然后在工作目录打开一个新终端,查看openocd.cfg内的信息:
第一行telnet_port 4444,说明我们能够通过telnet进入openocd命令界面:
telnet 127.0.0.1 444
输入命令poll来查看系统的状况:
> poll
target state: running
通过halt来暂停板子的执行:
> halt
waiting for target halted...
target state: halted
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x20000093 pc: 0xc002ea0c
MMU: enabled, D-Cache: enabled, I-Cache: enabled
从上面可以看到板子的MMU和D-cache已经使能,可以通过下面的命令来禁止MMU和D-cache:
> arm920t cp15 2 0
2: 00000000
然后加载程序:
> load_image /home/mybays/arm/qq2440v3/leds/leds_elf
168 byte written at address 0x00000000
downloaded 168 byte in 0.012190s
让我郁闷的是竟然不支持相对路径,每次都要输入绝对路径,这程序写的真伤感情.
然后开始执行:
> resume 0x0
就能够看到板子上的4个led灯飞快的跑个不停.
然后停止执行:
> halt
target state: halted
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x20000093 pc: 0x00000028
MMU: disabled, D-Cache: disabled, I-Cache: disabled
可以看到MMU和D-Cache已经被禁止了.
下面我们来看看leds程序部分:
先看看编译部分吧:
mybays@spaceship:~/arm/qq2440v3/leds$ make
arm-linux-gcc -Wall -Wstrict-prototypes -g -fomit-frame-pointer -ffreestanding -c -o crt0.o crt0.S
arm-linux-gcc -Wall -Wstrict-prototypes -g -fomit-frame-pointer -ffreestanding -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
然后就是源码部分:
@crt0.S开始部分
@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************
.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
@crt0.S结束部分
//leds.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(unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while(1){
wait(300000);
GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4
if(++i == 16)
i = 0;
}
return 0;
}
//leds.c结束部分
//leds.lds开始部分
SECTIONS {
. = 0x00;
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata)}
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
//leds.lds结束部分
#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
#Makefile结束部分
要记得在编译前导入环境变量,否则系统会提示找不到arm-linux-gcc
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #8376同步于 2010/4/22
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖
arm学习笔记(1)
mybays
2010/4/22镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
大赞~ 会自己写链接脚本的都是牛人啊
有几个问题请教下啊
1)
> halt
waiting for target halted...
target state: halted
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x20000093 pc: 0xc002ea0c
MMU: enabled, D-Cache: enabled, I-Cache: enabled
从上面可以看到板子的MMU和D-cache已经使能,可以通过下面的命令来禁止MMU和D-cache:
PC指针0xc002ea0c貌似是内核的地址啊 你板子里面是不是已经有程序在跑了?
open-jtag这个仿真器可以支持Linux内核调试么?
2)
> load_image /home/mybays/arm/qq2440v3/leds/leds_elf
168 byte written at address 0x00000000
从上述指令看 哪个地方指定了将leds_elf加载到0地址了呢
load_image加载的必须是elf格式的映像么
对于2440来说 0地址是内部SRAM么 什么时候SRAM会映射到0地址呢
或者是SDRAM重映射到这了?
3)
//leds.lds开始部分
SECTIONS {
. = 0x00;
.text : { *(.text) }
.rodata ALIGN(4) : {*(.rodata)}
.data ALIGN(4) : { *(.data) }
.bss ALIGN(4) : { *(.bss) *(COMMON) }
}
程序链接的基地址是0 一部来说你的程序必须加载到0位置的
但是你目前程序里面没有任何全局变量的访问 汇编代码和C代码都是相对寻址
你能试试把程序加载到其他非0的RAM地址上 看看能不能跑?
再加上全局变量 然后再试试把程序加载到其他非0的RAM地址上 还能不能正常运转
早就给三楼站内了,在这发一下吧:
: 1.能调内核的可能性很大,但是具体我没有验证,你可以google一下,或看openocd的手册
: 2.可以是bin格式的,openocd会自动识别.
: 关于地址映射问题,我也想搞明白,不过最近事情比较杂,没时间深究,大家可以交流.
【 在 mybays 的大作中提到: 】
: 开发环境的建立:
: 手里几块开发板,arm7,arm9,Intel IXP-425,还有过几天就会寄来的Cortex-M0,真不知道用哪块好,决定采用QQ2440V3作为开发学习平台,原因很简单,附带的光盘里资料收集的很全,不用自己费那么大的力气到网上一点一点的找.
: 本来是打算到http://www.kegel.com/crosstool/上下载配置文件自己重新编译交叉编译工具链,但是想到最近unixcenter挂了,找不着合适的socket代理下那么多的源码,暂时作罢.
: ...................
好东西 刚安装完crosstool就看这个帖子 真是幸福 可以练练了!