使用eclipse进行调试嵌入式Linux程序
早年写的笔记,压箱底了,翻出来晒晒
目 录
3.1. 设置GCCC compiler和miscellaneous10
3.2. 设置GCClinker和miscellaneous11
3. console窗口和problem窗口的输出信息对比...16
实验环境
u FC6 (2.6.18-1.2798.fc6)
安装配置eclipse
eclipse是著名的跨平台的集成开发环境(IDE),最初是由IBM公司开发的替代商业软件Visual Age For Jave的下一代开发环境。eclipse本身只是一个框架平台,最初主要用于java语言的开发。但是众多插件的支持使得eclipse同样可以 用来开发其他的语言,如c/c++、c#、perl、cobol的等等。cdt(c/c++development toolkit)就是支持c/c++开发的插件。
在http://www.eclipse.org/ 上找到的目前最新版支持C的eclipse已经集成好的插件,直接下载就可以使用了。
由于eclipse平台用java实现,所以运行时需要jre(javaruntime environment)的支持。
1. 安装jre
下载地址http://java.sun.com/javase/downloads/index.jsp。
现在最新版的为jre-6u14-linux-i586.bin。复制到/home/linuxuser/eclipse。执行如下命令:
#cd/home/linuxuser/eclipse
#mkdir -p/opt/java
#./jre-6u14-linux-i586.bin
#mv jre1.6.0_14/opt/java
#cd /opt/java
#ln -s jre1.6.0_14jre
#mv/etc/alternatives/java /etc/alternatives/java.gnu
#ln -s/opt/java/jre/bin/java /etc/alternatives/java
2. 安装eclipse
下载eclipse-cpp-galileo-linux-gtk.tar.gz,解压到/home/linuxuser/eclipse/eclipse。
创建PC上运行的c工程
建立一个多文件的C应用程序。
1. 启动eclipse,设置工作目录
2. 新建C project
3. 输入project name。
这次起名为hello-multiple,意思是多文件的hellow world程序。
点击finish之后关闭welcome的页面,就可以看到工程的界面。
4. 加入代码文件
点击file->new->source file,输入hello_main.c, 然后点击finish。
将内容全部替换为如下:
#include<stdio.h>
#include"hello_lib.h"
int main(void)
{
helloworld();
return 0;
}
再按照同样的方法建立hello_lib.c文件,内容如下:
#include<stdio.h>
void helloworld(void)
{
int i =0;
i += 9;
printf("helloworld, i = %d\n",i);
}
然后加入头文件hello_lib.h,不同的是这次要加入file->new->headerfile。内容如下:
void helloworld(void);
5. 编译,调试
点击project->build all,这样就能编译完成了。点击run->debugas->local c/c++ applications.
按F5是step in,F6是step over。调试截图如下:
使用交叉编译器调试嵌入式程序
源码不需要改变,修改一些设置就可以改为编译嵌入式程序。另外需要重新编译uclinux,加入gdbserver才可以。
1. 编译arm-linux-gdb
在http://www.gnu.org/software/gdb/下载gdb-6.8.tar.gz,解压到/home/linuxuser/eclipse/gdb-6.8。目前的交叉编译工具目录为/home/linuxuser/usr/local/arm-linux/
执行如下命令:
#./configure --target=arm-linux--prefix=/home/linuxuser/usr/local/arm-linux/gdb
#make
#make install
编译成功之后会生成/home/linuxuser/usr/local/arm-linux/gdb目录,在/home/linuxuser/usr/local/arm-linux/gdb/bin下有arm-linux-gdb。
2. 在uclinux上加入gdb server
Snapgear的安装包里面带gdbserver。执行make menuconfig,在customize vendor/user settingsàMiscellaneous Applications可以找到gdbserver,如下图。
选中之后编译,ramdisk里面/bin目录下就包含了gdb server。
3. 设置项目属性
点击project->properties,弹出一个窗口,选择settings。设置GCC C compiler和GCC C linker为/home/linuxuser/snapgear/tools/ucfront-gcc arm-linux-gcc,GCC assembler为arm-linux-as。另外要在miscellaneous设置endian。
arm-linux-gcc等工具的路径需要能找到。实验中这些工具都在/home/linuxuser/usr/,需要做个链接。输入命令
#ln -s /home/linuxuser/usr/local/arm-linux/usr/local/arm-linux
3.1. 设置GCC C compiler和miscellaneous
3.2. 设置GCC linker和miscellaneous
设置完成之后就可以编译源码,在c project的目录下有debug目录,里面有编译好的hello-multiple。
4. 进行远程调试
4.1运行gdbserver
将eclipse编译编译将hello-multiple整合进ramdisk,下载到板子上运行。先启动以太网卡,然后执行如下命令:
#cd /bin/
#./gdbserver 192.168.1.111:10000 /home/hello-multiple
正常启动后会有如下信息:
#Process /home/hello-multiple created; pid = 39
#Listening on port 10000
gdbserver是交叉调试辅助程序;192.168.1.111是主机的ip地址;10000是调试端口号,和eclipse调试选项里设定的端口号要一致。
4.2 启动eclipse的debug功能
配置eclipse,选择run->debug configurations. 在ugger选项页修改debugger为gdbserver debugger,设置GDB debugger为arm-linux-gdb
切换到connection选项页,设置连接类型为TCP,目标板的ip地址(本实验中为192.168.1.211)和调试端口号。端口号任意指定,通常大于1024(避免和系统所用端口号冲突)。在此设定为10000。
点击debug按钮就可以开始debug了,使用起来比较方便,截图如下:
可能遇到的问题
1. 在uclinux上加入gdb server
Snapgear的安装包里面带gdbserver,目录为/home/linuxuser/snapgear/user/gdbserver,说明应该是可以在编译选项里面找得到的。但是makemenuconfig在CustomizeVendor/User Settings--->Debug Builds里并没有发现gdbserver的选项。截图如下:
因为gdbserver的目录,所以归于Customize Vendor/UserSettings--->Debug Builds选项,配置文件是/home/linuxuser/snapgear/config/.config,看看是不是因为前置条件不够隐藏了。果然找到#Miscellaneous Applications下属的# CONFIG_USER_GDB_GDBSERVER is not set。再到make menuconfig里面果然有选项
选中之后编译。
另外看到gdb target和gdb host,这个也许用的着。选中这个两个会编译失败。单独选中gdb target也会编译失败。
2. Eclipse编译工具的路径设置问题
不像手工写的makefile,eclipse对路径的识别没那么好,设置gcc和linker之后编译失败,在console窗口里发现如下错误:
arm-linux-gcc -o hello hello.c
/home/linuxuser/usr/local/bin/../lib/gcc/arm-linux/3.4.4/../../../../arm-linux/bin/ld:cannot find /usr/local/arm-linux/lib/libc.so.6
collect2: ld returned 1 exit status.
检查发现/home/linuxuser/usr/local目录基本上是空的,其实这个时候使用env命令查看路径应该是已经包含的,但是eclipse似乎不识别
执行命令
#ln -s /home/linuxuser/usr/local/arm-linux/usr/local/arm-linux
可以解决问题,可以正常编译。
使用file hello,参看到编译完的属性
#file hello-multiple
hello-multiple: ELF 32-bit LSB executable, ARM,version 1 (ARM), for GNU/Linux 2.0.0,dynamically linked (uses shared libs), for GNU/Linux 2.0.0, not stripped
这样说明编译等设置是正确的。但是endian没有解决,而且应该使用uclibc库
3. console窗口和problem窗口的输出信息对比
剩下big-endian的问题了,eclipse设置如下
编译的时候提示错误:
Problem页里面显示如下错误
Description Resource Path Location Type
./hello_lib.o: compiled for a big endian system andtarget is little endian hello-multiple line 0 C/C++ Problem
在console页里面显示如下:
arm-linux-gcc -o"hello-multiple" ./hello_lib.o ./hello_main.o
/home/linuxuser/usr/local/bin/../lib/gcc/arm-linux/3.4.4/../../../../arm-linux/bin/ld:./hello_lib.o: compiled for a big endian system and target is little endian
经过以前也出现的几次信息对比,Problem页显示的信息总是不全,建议尽量看console页里面的信息,接近手工编译的信息。
这个看起来就是在第二阶段的编译过程中没有使用-mbig-endian了。按如下如加入-mbig-endian,编译成功。
在尝试的过程中,走了一段弯路:先尝试单独写makefile编译,makefile如下
C_FLAGS = -mbig-endian
CC=arm-linux-gcc
CC+=$(C_FLAGS)
OBJ=hello_main.o hello_lib.o
hello:$(OBJ)
$(CC)$(C_FLAGS) -o $@ $?
$(OBJ):hello_lib.h
clean:
rm -f *.o
rm hello
这样能够正常编译程序。
以前见过compiled for abig endian system and target is little endian
的错误,是LD造成的。这里试一下。猜想也许是linker应该设置成arm-linux-ld –EB才可以,如下图:
但是出现奇怪的错误,连printf的语句都标出红色的错误。最后吧gcc linker改成了arm-linux-gcc和-mbig-endian后问题解决了。
3. 编译arm-linux-gdb
Eclipse设置完以后,点击debug按钮,报错:
应该是找不到arm-linux-gdb了。编译器里面并没有自带调试工具, 按照前面讲的方法编译arm-linux-gdb就可以了。
4. 单独试验arm-linux-gdb
为了防止eclipse的设置问题,先单独使用arm-linux-gdb测试一下效果。盒子上gdbserver正常启动以后,在host的命令行下输入命令:
#cd /home/linuxuser/usr/local/arm-linux/gdb/bin
#./arm-linux-gdb /home/linuxuser/eclipse/code/hello-multiple/Debug/hello-multiple
然后可以使用list, b 3,c等命令。显示如下:
# ./arm-linux-gdb/home/linuxuser/eclipse/code/hello-multiple/Debug/hello-multiple
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change andredistribute it.
There is NO WARRANTY, to the extent permitted bylaw. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu--target=arm-linux"...
(gdb) target remote 192.168.1.211:10000
Remote debugging using 192.168.1.211:10000
0x400009f0 in _start () from /lib/ld-linux.so.2
(gdb) list
1 #include<stdio.h>
2 #include "hello_lib.h"
3 intmain(void)
4 {
5 helloworld();
6 return 0;
7 }
(gdb) b 5
Breakpoint 1 at 0x8490: file ../hello_main.c, line 5.
(gdb) c
Continuing.
Breakpoint 1, main () at ../hello_main.c:5
5 helloworld();
(gdb) step
helloworld () at ../hello_lib.c:5
5 int i =0;
(gdb) next
6 i += 9;
(gdb) print i
$1 = 0
(gdb) next
7 printf("hello world, i = %d\n",i);
(gdb) print i
$2 = 9
串口显示
# ./gdbserver 192.168.1.111:10000/home/hello-multiple
Process /home/hello-multiple created; pid = 39
Listening on port 10000
Remote debugging from host 192.168.1.111
至此,说明arm-linux-gdb完全可以正常工作。