Embeded linux Development with Eclipse -...
Transcript of Embeded linux Development with Eclipse -...
Copyright (C)2006 郭晨(george)
Embeded linux Development with Eclipse
作 者:郭 晨(george)
版本号:V1.0
E-mail: [email protected]
Copyright (C)2006 郭晨(george)
前 言
随着微处理&SoC&IP 技术的飞速发展,一个界限划分不是很明
显的行业--嵌入式也正高速的发展着。各大厂商也投入较大精力对其
研究,开发出了相应的集成开发环境(IDE),以及在此基础上开发
出的产品。但是这个行业也一直没有一枝独秀,开发的方法也多种多
样,选择很多,但是开发效率也参差不齐。
我写这边文档的初衷是因为公司希望在 ARM9&Linux 做好积
累,以便随后无论是单独 ARM9 还是 ARM9+DSP 的项目得到很快开
展。但是对于一个项目组而言,让每个人从原先熟悉的 Windows 开
发环境转移 Linux 下开发,并且使用 GCC,GDB 的命令行开发模式,
无疑需要一定的时间,所以就寻求折中的尝试!Eclipse 当然是个不
错的选择。那么接下的几天我就和他来了一次亲密接触,并把其中一
些心得记录下来,因为我和大家一样,经历了可参考资料匮乏的痛楚,
希望这边文档能给刚刚上手的新手一些指导,也希望一些玩的很转的
老手多多交流,也算是发扬开源精神吧!
闲话少讲!
Let's do it!
Copyright (C)2006 郭晨(george)
安装开发环境:
开发嵌入式 Linux 系统首选当然是在 Linux 环境下了,除了原汁原味外,更
重要的是为以后移植的代价作考虑,但是对于一个习惯于 Windows 环境下开发
的项目组而言,让每个项目成员全部熟悉 Linux 以及命令行的开发模式,在项目
进度上是不允许的,怎样找个折中的办法呢?在 Windows 下虚拟 Linux 开发环
境,听起来是个不错的选择;利用 Eclipse 的集成开发环境(IDE),更是一个不
错的选择,那就让我们开始吧!
我的实验是在 Windows2000 & S3C2510(ARM940T)开发板上做的,对于
嵌入式开发有其特殊性,需要搭建交叉编译调试环境,对于整套系统的开发,需
要安装软件如下:
系统环境:
1. SUN Java Runtime
2. CYGWIN for Windows
工程开发环境
3. Eclipse IDE
4. Eclipse CDT Plug-in for C++/C Development
5. GNUARM GNU C++/C Compiler for ARM Targets
仿真调试环境
6. GNUARM Insight Debugger
7. Macraigor OCDremote (Wiggler JTAG debug)
8.Multi-ICE Server for Windows & Multi-ICE –GDB-Server for Linux
(Multi-ICE JTAG debug)
为什么要选择 Eclipse,因为它是一个非常优秀的开源软件,国外热度已经很高,国内
也处于初步发展阶段,Eclipse 设计初衷是用来作 Java 开发的,但是可以利用 CDT
(C/C++ Development ToolKit)作 C/C++开发。Eclipse IDE 完全是由 Java 写成
的,所以要想在 Windows中运行需要先安装 SUN Java Runtime。
关于Eclipse更多的信息可在www.eclipse.org找到。
Copyright (C)2006 郭晨(george)
SUN Java Runtime可从www.sun.com免费下载。
首页“Downloads – Java 2 Standard Edition”找到 J2SE5.0 打开链接,
选择 JRE5.0 Upload 7 按照提示下载,然后安装。
安装成功如下:
Copyright (C)2006 郭晨(george)
CYGWIN for Windows 下载安装:
打开www.cygwin.com
打开下方 Install or upload now!
按提示选择运行,
Copyright (C)2006 郭晨(george)
->下一步
-〉Install from Internet(或选择 Download Without Installing,但需要把之
前第一步选择运行,改为选择保存)。
-〉下一步;选择安装路径,因为我的 C 盘空间不够,所以选择了 F 盘,但以后
Copyright (C)2006 郭晨(george)
要配置 PATH
-〉下一步
-〉下一步
Copyright (C)2006 郭晨(george)
-〉DirectConnetion 我没有连上,所以选择 Use IE5 Settings,下一步
会罗列出一些下载站点,选一个,下一步
如果你的空间不是问题可以所有 Default 改为 Install
如果想精简安装,需要将下列:
Archive Default Archive Default Install
Copyright (C)2006 郭晨(george)
Devel Default Devel Default Install
Libs Default Libs Default Install
Web Default Web Default Install
->下一步....等待数个小时的下载(我是晚上做的,到了这一部我就去睡觉了)
第二天醒来
-〉完成
接下来需要检查 PATH
控制面板-〉系统-〉高级->环境变量
Copyright (C)2006 郭晨(george)
Path 编辑
在变量加上 f:\cygwin\bin; f:\cygwin\usr\local\bin
这样在 Windouws 下虚拟 Linux 环境就已经完成了。
Copyright (C)2006 郭晨(george)
Eclipse IDE 安装:
打开www.eclipse.org,在安装Eclipse IDE直接我的建议是先下载CDT,因为
CDT的安装需要对应Eclipse IDE版本号的,我当时下载Eclipse IDE 3.2 还没有
对应的CDT,www.eclipse.org 上 新的CDT是 3.0 对应Eclipse IDE 3.1.x
选择 for windows 版本,下载完 org.eclipse.cdt-3.0.2-win32.x86.zip(11.7M)
回 到 www.eclipse.org 首 页 Downloads 找 到 对 应 的 Eclipse IDE 3.1.x
(windows版)下载eclipse-SDK-3.1.2-win32.zip(103M)
解压到安装路径直接运行就可以。
此时 Eclipse IDE 只能创建 Java 工程,所以我们要安装 CDT。
有两种安装方法:一种在线安装
Copyright (C)2006 郭晨(george)
Help->Software Uploads->Find and Install->
->Search for new features tio install->Next
Copyright (C)2006 郭晨(george)
->New Remote Site
URL:刚刚在 CDT 的下载页面公布的对应版本的 URL
->OK
第二种方法:对于在线安装不方便的,先前我们有了 CDT 的 zip 包,把对应的
文件解压到 eclipse 对应的目录下即可。
现在重新打开 eclipse,新建工程,你就可以看到有 C\C++的选项了。
如果没有看到,你在 eclipse 的快捷方式,属性
目标(T):D:\eclipse\eclipse.exe 中加上 –clean,重新打开 eclipse 就可
以了。
Copyright (C)2006 郭晨(george)
GNUARM 安装
为什么要安装GNUARM呢?做过嵌入式开发的都知道,比如ARM,DSP虽然都用C
代码写,但是都需要与对应的编译器生成对应芯片的运行代码,我们所用的GCC
只是通用编译器,所以我们需要安装GNUARM以至于我们能使用
arm-elf-gcc,arm-elf-ld ,arm-elf-ar,arm-elf-as,arm-elf-objcopy,
arm-elf-objdump…针对ARM的编译链接生成可执行文件的工具。
打开www.gnuarm.org 下载一个 新版本
bu-2.16.1_gcc-4.0.1-c-c++_nl-1.13.0_gi-6.1.exe(27M)
Copyright (C)2006 郭晨(george)
根据提示,逐步安装
后和刚刚安装 cygwin 一样在 PATH 中将 d:\program files\gunarm\bin
添加进去。
这样编译环境就配置成功了。
当然对于嵌入式开发还有一个非常重要的环节就是仿真调试。
仿真调试环境
通常嵌入式仿真调试两种基本类型,一种编译完代码,生成 bin/hex 文件下
载到 Flash/ROM 中运行验证,再使用串口或网口与其通讯;另一种,编译可执
行代码通过仿真器将代码下载到 RAM 中通过仿真器控制 ARM 核中
Embeded-ICE 模块完成在线调试,此方法比较方便迅速。
第一种方法比较简单,这里就不多作说明。
当然第二种方法,需要仿真器,目前主流仿真器 Multi-ICE 原厂比较昂贵,
国内出的一两千的各色品牌的大多是它的仿制品,另一种十分廉价的 Wiggler 仿
真器成本也就不足十元。
先说说使用 Wiggler 仿真器 & Macraigor OCDremote
关于如何制作 Wiggler 仿真器这里就不错说明,网上一搜连 pcb 图都有。
当然除了硬件也需要软件将 GDB 命令转换成 JTAG 命令,那就是 Macraigor
OCDremote
打开www.macraigor.com/full_gnu.htm.
找到 For Windows 选择 新版本 downloads windows OCDRemote
v2.17(3M)安装到 F:\cygwin\usr\local\bin 下。
Copyright (C)2006 郭晨(george)
然后启动 eclipse,因为 eclipse 会记忆当时环境,所以先创建一个 C\C++工程。
接下来配置仿真器:
Run->External Tools->External Tools
Copyright (C)2006 郭晨(george)
Program new
Copyright (C)2006 郭晨(george)
配置:
Name: OCDremote
Location: F:\cygwin\usr\local\bin\ocdremote.exe
Arguments: 这里是仿真链接 ARM 的一些配置。
-c/--cpu <CPU type>,
ARM 7/9/11 Families:
ARM7EJ-S | ARM7TDMI | ARM7TDMI-S | ARM9E-S | ARM9EJ-S|
ARM9TDMI | ARM11 | ARM720T | ARM920T | ARM922T |
ARM926EJ-S | ARM940T | ARM946E-S | LH7A40X | LH7952X|
NET+15 | NET+20M | NET+40 | NET+50 | NS7520 |
NS9360 | NS9750 | NS9775 | NSARM9 | OMAP310 |
OMAP710 | OMAP1510 | OMAP5910 | SharpARM7 | SharpARM9|
Copyright (C)2006 郭晨(george)
TI925T | iMX21 | iMX31 |
MIPS 32-bit Family:
Alchemy_AU1x00 | BCM7115 | MIPS32_4Kc | MIPS32_4Ke |
Vitesse_V3000 |
MIPS 64-bit Family:
MIPS64 | TX49 |
PowerPC Family:
AMCC440EP | AMCC440GP | AMCC440GX | MPC55X | MPC56X|
MPC603 | MPC740 | MPC745 | MPC750 | MPC755 |
MPC8XX | MPC5200B | MPC5554 | MPC8240 | MPC8245 |
MPC8247 | MPC8248 | MPC825X | MPC826X | MPC8270 |
MPC8271 | MPC8272 | MPC8275 | MPC8280 | MPC85X0 |
PPC403 | PPC405 | PPC603 | PPC740 | PPC750 |
PPC750FX | PPC750GX |
Intel Xscale Family:
80200 | 80219 | 80321 | 81341 | 81342 |
IOP303 | IOP315 | IOP321 | IOP331 | IOP332 |
IOP333 | IXC1100 | IXP42x | IXP46x | IXP23XX |
IXP2400 | IXP2800 | IXP2850 | PXA210 | PXA25x |
PXA26x | PXA27x | XSCALE-5IR |
XSCALE-5IRSLAVEXSCALE-7IR | XSCALE-CORE3 |
U:<ir bits>:<bypass bits>
-p/--port <port number>, ocdremote's tcp/ip port, default = 8888
-d/--device <device>,
RAVEN | MPDEMON_ETHERNET | WIGGLER | MPDEMON_PARALLEL |
MPDEMON_SERIAL | USB | ___, default = RAVEN
-a/--address <device address>, RAVEN,WIGGLER,MPDEMON_PARALLEL LPT: 1-4,
MPDEMON_SERIAL COM: 1-8
USB: 0-16
Copyright (C)2006 郭晨(george)
MPDEMON_ETHERNET: tcp/ip address xxx.xxx.xxx.xxx
-s/--speed <speed>, JTAG/BDM clock rate 1 - 8, default = 1
-b/--baud <baud>, mpDemonSerial baud rate 1200 - 115200, default = 115200
这样就配置成功了。
当然你可以将 OCDremote 加入 Favorites,这样使用起来就很方便。
Run->External Tools->Organize Favorites,将 OCDremote 加入即可。
Multi-ICE 仿真器 & Multi-ICE Server(for windows)
& multi-ice-gdb-server (for Linux)
首先在安装 Multi-ICE Server(for windows),相信在 windows 下用 ADS
做过 ARM 开发的这个一定很熟悉了,如果不知道,找个安装程序安装即可,没
什么特别要说的。
关于 multi-ice-gdb-server (for Linux),如果刚刚你安装 cygwin 时,版本
比较新,你应该可以发现在 cygwin 下有个 Mutl-ICE 的文件夹,那么接下来的
工作就省事多了,如果没有,也没什么可怕的,一步一步来。
我们需要:
GDB-sourses :http://sources.redhat.com/gdb/
RDI :可从ARM网站获得http://www.arm.com/support/downloads/info/5570
Multi-ice-gdb-server Sources : ftp://ecos.sourceware.org/pub/ecos/multi-ice-gdb.tar.gz
Copyright (C)2006 郭晨(george)
在 DOS 下输入 bash
这是因为你的 cygwin 起作用了。
接下来得到 gdb,RDI,multi-ice-gdb-server 源码后,就要重编译了
新建路径,释放源码
bash-3.1$ mkdir /tmp/gdb
bash-3.1$ cd /tmp/gdb
bash-3.1$ cd gdb-6.4/gdb
bash-3.1$ mkdir multi-ice
bash-3.1$ cd multi-ice
bash-3.1$ tar -zxvf /cygdrive/multi-ice-gdb.tar.gz
新建编译文件生成路径
bash-3.1$ mkdir /tmp/gdb/build
bash-3.1$ cd /tmp/gdb/build
Build multi-ice-gdb-server:
Copyright (C)2006 郭晨(george)
bash-3.1$ /tmp/gdb/gdb-6.4/configure -v --target arm-elf
--enable-multi-ice 2>&1 | tee configure.out
如果我们想连 gdb 一起 make
bash-3.1$ make -W all install 2>&1 | tee make.out
如果我们只想为 multi-ice-gdb-server make
bash-3.1$ make -w all-libiberty all-bfd 2>&1 | tee make.out
make
bash-3.1$ cd gdb/multi-ice
bash-3.1$ make -W MULTI_ICE_INCLUDES="-I/cygdrive/Rdi/Headers" \
MULTI_ICE_LIBS="-L/cygdrive/Multi-ICE
-L/tmp/gdb/gdb-6.4/gdb/multi-ice -ltoolconf" 2>&1 | tee make.out
上面""为我们需要的一些文件路径。
你会发现生成了 multi-ice-gdb-server.exe 和一些.dll 文件,那么你成功了!
bash-3.1$ cp -i multi-ice-gdb-server.exe /cygdrive/Multi-ICE
bash-3.1$ cp -i /tmp/migdb/gdb-5.1.1/gdb/multi-ice/*.dll
/cygdrive/Multi-ICE
将他们 COPY 到对应文件下,大功告成。
接着就是配置 Eclipse
与配置 OCDromte 类似
Copyright (C)2006 郭晨(george)
Run->External Tools->External Tools
Program new
Copyright (C)2006 郭晨(george)
注意参数,如果你以前 windows 用 Multi-ICE 加 AXD 调试过,添上如上参数
重现配置一下环境才能连接上。
你也可以将它加入 Favorites。
Copyright (C)2006 郭晨(george)
要想 RAM 下载调试,怎么下载呢?怎么调试呢?这是就要要到 arm-elf-insight
先前安装 GUNARM 的时候已经安装上了
需要加到 Eclpise 中,步骤与上面一样:
Run->External Tools->External Tools
Copyright (C)2006 郭晨(george)
Program new
Copyright (C)2006 郭晨(george)
Argument :你以后工程编译后的执行文件。
OK! RUN!!
如果你要用 Wiggler 仿真器连接,先运行 OCDremote.
Run->External Tools->OCDremote
然后运行 insight
Run->External Tools->insight
Copyright (C)2006 郭晨(george)
File->Target Settings
设置如上
Hostname :如果是本及调试就设 localhost 或你的主机名或 IP
Port :还记得前面配置 OCDremote 提到的-p 参数吗?它们必须一致。
OK!
下载程序到 RAM,
Copyright (C)2006 郭晨(george)
Copyright (C)2006 郭晨(george)
如果你使用的是 Mutli-ICE 仿真器,
首先,windows 下启动 Multi-ICE server,配置成功
启动 multi-ice-gdb-server
Run->External Tools->multi-ice
Copyright (C)2006 郭晨(george)
认出 ARM940T 核,说明 multi-ice 已经配置成功
启动 insight
Run->External Tools->insight
注意端口号一致!
下面与使用 Wiggler 没有什么区别!
接下来你如果还需要做什么,那就是放纵得写你的代码去吧!
GO!GO!GO!
Nothing is impossible!
愿与:
朝着技术前沿挺进的勇士
& 奋斗在开源世界的战士共勉!
郭 晨(george) 2006.7 [email protected]
Copyright (C)2006 郭晨(george)
附录:一个简单的开始
我就介绍一个简单的工程,供大家参考,敲开嵌入式 Linux 或 ARM 开发的大门
工程 LED---start.s 启动程序,汇编部分
|---main.c C 代码部分
|---libc.a C 库
|---MakeFile
|---simple.cmd 生成.map,代码,数据,堆栈…在存储设备中的
定位
汇编部分
简单所以想,汇编两大派 Intel 型和 AT&T 型
ARM 采用的是 Intel 型,所以 ARM 公司自己出的 IDE,ADS 采用的就是 Intel 型
而 GNU 的开发工具采用的是 AT&T 型,所以从 ADS 准到 GNU 上开发,这一点
需要注意,但是编译器主要影响的是宏指令集和伪指令集,大家也无须担心。
一些更改:
1、注释行以“#”或“/* ... */”代替“;”
2、伪操作符替换:
INCLUDE 替换成 .INCLUDE
TCLK2 EQU PB25 替换成 .equ TCLK2, PB25
EXPORT 替换成 .global
IMPORT 替换成 .extern
DCD 替换成 .long
IF :DEF: 替换成 .IFDEF
ELSE 替换成 .ELSE
ENDIF 替换成 .ENDIF
:OR: 替换成 |
:SHL: 替换成 <<
Copyright (C)2006 郭晨(george)
END 替换成 .end
符号定义加":"号
AREA Word, CODE, READONLY 替换成 .text
AREA Block, DATA, READWRITE 替换成 .data
CODE32 替换成 .arm
CODE16 替换成 .thumb
LTORG 替换成 .ltorg
% 替换成 .fill
3、操作数及运算符号替换
ldr pc, [pc, #&18] 替换成 ldr pc, [pc, #+0x18]
“&”以“+0x”号替换
Start.s @*************TEST FOR Eclipse by george***********
@ *************************************************
@ Assembler startup
@ *************************************************
/*stack size*/
.set UND_STACK_SIZE, 0x4
.set ABT_STACK_SIZE, 0x4
.set IRQ_STACK_SIZE, 0x4
.set FIQ_STACK_SIZE, 0x4
.set SVC_STACK_SIZE, 0x400
/*ARM MODE*/
.set MODE_USR, 0x10
.set MODE_FIQ, 0x11
.set MODE_IRQ, 0x12
.set MODE_SVC, 0x13
.set MODE_ABT, 0x17
.set MODE_UND, 0x1B
.set MODE_SYS, 0x1F
/* DISABLE I/F INTERRUPT */
Copyright (C)2006 郭晨(george)
.set I_BIT, 0x80
.set F_BIT, 0x40
.text @ New Code section
.arm @ ARM code
.global Reset_Handler
.global _startup
.func _startup
@ *****************************************************
_startup: @ Defines entry point
@ ****************************************************
_vector: @ interrupt vector
@******************************************************
LDR PC, Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
NOP @ for code to be
LDR PC, [PC, #-0xFF0] @ load irq vector from vic
LDR PC, FIQ_Addr
Reset_Addr: .word Reset_Handler
Undefined_Addr: .word Undefined_Handler
SWI_Addr: .word SWI_Handler
Prefetch_Addr: .word Prefetch_Handler
Abort_Addr: .word Abort_Handler
FIQ_Addr: .word FIQ_Handler
.word 0
@ ********************************************************
@ Exception Handlers
@ *********************************************************
Undefined_Handler:
B Undefined_Handler
SWI_Handler:
中断向量表 B SWI_Handler
Prefetch_Handler:
B Prefetch_Handler
Abort_Handler:
B Abort_Handler
FIQ_Handler:
B FIQ_Handler
Copyright (C)2006 郭晨(george)
Reset_Handler:
ldr r0, =0x40001000 @ stack end
msr cpsr_c, #MODE_UND|I_BIT|F_BIT @Undefined mode
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr cpsr_c, #MODE_ABT|I_BIT|F_BIT @Abort mode
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT @FIQ mode
设置堆栈
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT @IRQ mode
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr cpsr_c, #MODE_SVC|I_BIT|F_BIT @SVC mode
mov sp, r0
/*clear .bss section (Zero init)*/
mov r0, #0
ldr r1, =_bss_start
ldr r2, =_bss_end
1: cmp r1, r2
strlo r0, [r1], #4
blo 1b
/* Jump to C code */
跳入 main.c LDR lr, =main
MOV pc, lr
.endfunc
.end
Main.c
#define rIOPMODE1 *( int *)0xF0030000
#define rIOPCON1 *( int *)0xF0030008
#define rIOPDATA1 *( int *)0xF003001C
Copyright (C)2006 郭晨(george)
int main ()
{
int i,j;
i=0;
j=0;
while(1)
{
for(i=0;i<8;i++)
{
*( int *)0xF0030000 = 0x0;
*( int *)0xF0030008 = 0xFFFFFF00;
*( int *)0xF003001C = ~(0x1 << i);
简单闪灯程序
for(j=0;j<0xFFFFF;j++);
}
}
}
MakeFile
NAME = test led
CC = arm-elf-gcc
LD = arm-elf-ld -v
AR = arm-elf-ar
AS = arm-elf-as
CP = arm-elf-objcopy
OD = arm-elf-objdump
CFLAGS = -T./ -c -fno-common -O0 -g
AFLAGS = -ahls -mapcs-32
CAFLAGS = $(CFLAGS) -Wa,-ahls,-mapcs-32
LFLAGS = -Map main.map -T simple.cmd
CPFLAGS = -O binary
ODFLAGS = -x --syms
all: test
clean:
-rm start.lst main.lst ivt.lst start.o main.o main.out main.bin
main.map main.dmp
Copyright (C)2006 郭晨(george)
test: main.out
@ echo "...copying"
$(CP) $(CPFLAGS) main.out main.bin
$(OD) $(ODFLAGS) main.out > main.dmp
main.out: start.o main.o simple.cmd
@ echo "...linking"
$(LD) $(LFLAGS) -o main.out start.o main.o
start.o: start.s
@ echo ".assembling"
$(AS) $(AFLAGS) -o start.o start.s > start.lst
main.o: main.c
@ echo ".compling"
$(CC) $(CFLAGS) main.c
Simple.cmd INPUT(libc.a)
ENTRY(_startup)
MEMORY
{
ram : o = 0x40000000, l = 32M
flash : o = 0x00000000, l = 8M
}
SECTIONS
{
startup :
{
*(.startup);
} > ram
.text :
{
_text_start = .;
*(.text)
Copyright (C)2006 郭晨(george)
*(lodata)
*(lodata*)
*(.glue_7)
*(.glue_7t)
_text_end = .;
} > ram
.data :
{
_data_start = .;
*(.data)
_data_end = .;
} > ram
.bss :
{
_bss_start = .;
*(.bss)
_bss_end = .;
} > ram
.stack :
{
__stack_start = .;
*(.stack)
__stack_end = .;
} > ram
_end = .;
}
参考资料:
1)www.eclipse.org
2)www.redhat.com
3)James P. Lynch <<arm_dev_eclipse>>