1.调试原理 本调试是基于gdb+gdbserver的调试。在pc机上运行gdb,在开发板上运行gdbserver。Gdb调试的时候,pc机上的gdb向开发板上的gdbserver发出命令,而开发板上的gdbserver则会向应用程序发出信号,使应用程序停下来或者完成其他一些工作。
在本测试中,我们使用ubantu12.04作为宿主机,使用TQ3358做为开发板类型,利用USB转串口做为终端调试工具来实现嵌入式调试环境的搭建。
2工具软件的安装2.1root用户设置 Ubuntu默认不允许root登录,在登录窗口只能看到普通用户和访客登录。但我们的编译工作经常需要在root账户下完成操作,虽然我们可以通过终端命令sudo -s然后输入普通用户登录的密码获得root用户权限,但如果频繁需要操作的情况下又会有诸多不便。在这里我们可以通过修改配置文件的形式,在启动时选择root用户进行登录,这样可以大大减少我们的工作量,完善我们的工作环境。
我们首先需要创建root账户。可以在普通用户任意终端输入 sudo passwd root ,根据提示输入root账户密码(自己设定),并确认输入。
首先我们通过sudo –s的方式获得root用户权限,在终端执行
Vim /etc/lightdm/lightdm.conf //修改登录配置文件
在配置文件最后增加
greeter-show-manual-login=true //手工输入登录系统的用户名和密码
allow-guest=false//不允许guest登录
保存退出后,重启ubutu,登陆窗口会有“登录”,我们就可以通过手动输入root用户名,通过自己设定的密码登陆root用户。
在获得root用户权限之后我们可以通过在终端输入apt-get install <目标>的方式来进行在线安装应用。其中大部分的错误问题可以通过在网上查看相关的资料,通过apt-get install<目标>来进行错误处理操,这也是运用ubutu进行开发的一大优势。
2.2交叉编译器的安装 交叉编译工具是嵌入式开发的基础,我们在这里用arm-linux-gcc 进行交叉编译。
首先我们需要获得arm-linux-gcc的压缩包,解压到linux下/usr/local/arm(此目录可以自己设定,但必须保证已经存在,在这里我们假设已经存在以上目录,如果不存在目录的话我们可以自己创建),命令如下
tar-xvf arm-linux-gcc-****.tar.bz2 -C /usr/local/arm/(自己设定的压缩目录)
添加环境变量:
Vim ~/.bashrc
在最后添加:exportPATH=/usr/local/arm/<编译器版本号>/bin/:$PATH
如果提示缺少libz.so.1则在终端输入 apt-get install zlib.i686
保存退出,在终端执行 source~/.bashrc
通过在终端输入:arm-linux-gcc–v 查看版本号信息,看是否安装成功
安装中可能出现的问题:如果按照步骤安装并且添加环境变量正确的情况下,出现提示arm-linux-gcc:No such file ordirectory
可以在终端输入:sudo apt-get install ia32-libs 安装库文件编译
2.3串口终端minicom的安装配置 Minicom是一个串口通信工具,就像windows下的超级终端。可以用来和串口设备通信,在这里我们运用minicom超级终端和我们的开发板进行通讯。
首先在终端输入 apt-get install minicom 按提示来安装minicom。
安装完成后,在终端输入minicom–s 对终端进行配置。
在Serial portsetup 选项中设置串口号
进入串口配置界面,输入 A 配置串口驱动为/dev/ttyS0,输入E配置速率为1152008N1 输入 F 将 Hardware Flow Control 设为 NO,回车退出。
由于使用minicom作为超级终端控制路由器等设备,而不是控制modem,所以需要修改modem and dialing
将Modem and dialing配置单中的Initstring、 Reset string、Hang-up string 设置为空
设置完成后,选择Save setup asdfl 来保存配置信息,选择Exit退出配置界面或者选择Exit from Minicom来退出minicom界面。
如果使用虚拟机的话,需要首先在虚拟机中添添加串口设备,进行相关设置。
运行 lsmod | grepusbserial 如果有usbserial相关信息,则证明本虚拟机支持相关设备。如果没有则执行
apt-get install setserial
如果显示找不到相关设备文件则执行命令 mknod/dev/ttyUSB0 c 188 0
安装完成之后插上usb转串口,在终端输入dmesg| grep ttyUSB0如果出现连接成功的信息则证明ubutu系统已经识别该设备。同时要在虚拟机右下角把usb标识点亮,将串口标识灭掉。
在之后的运行过程之中可以直接在终端输入minicom进入终端调试模式。
注:minicom中有用的功能
命令帮助—“Ctrl A”后按“Z”
清屏 --“Ctrl A”后按“C”
设置 --“Ctrl A”后按“O”
发送文件--“CtrlA”后按“S”
退出 --“Ctrl A”后按“Q”
2.4 tftp服务器的构建 整个调试环境之中我们通过tftp服务器在主机和开发板之间传递数据文件。
首先我们在终端输入 apt-getinstall tftpd tftp openbsd-inetd 来安装相关端口文件。
在端口文件安装完成之后我们需要修改tftp的配置文件,在端口输入
Vim/etc/inetd.conf
#:BOOT:TFTP service is provided primarily for booting. Most sites
# run this onlyon machines acting as "boot servers."
#tftp dgram udpwait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd
/srv/tftp(/srv/tftp 为默认tftp目录)
#修改如下文件
tftp dgram udpwait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftproot
将最后一行中的默认修改为我们自己设定的文件路径。
创建设定的文件路径:在终端输入 mkdir /tftproot
修改文件属性: chmod777 /tftproot
关闭防火墙等的等设置:
serviceiptables stop//关闭防火墙
setenforce0//关闭selinux
通过69端口是否打开来判定tftp是否正常工作:netstat–an | more | grep udp
在安装完成后我们可以在本机上其他目录里对tftp服务器进行测试。
通过tftp <主机ip> 来登录服务器;
登录完成之后,通过 get <文件名> 获得文件,(当然在/tftproot文件夹下面要存在这个文件并且它的属性需要为 777 可以通过chmod 777 <文件名>来获得需要权限)
上传文件的时候需要在/tftproot中已经存在需要上传文件的同名文件,并且相关文件权限为777。
Tftp在主机和开发板之间传输的相关参数为:
-l FILE Local FILE
-r FILE Remote FILE
-g Getfile
-p Putfile
-b SIZE Transfer blocks of SIZEoctets
2.5 安装expat库 Gdb编译的时候需要对XML的解析库expat,我们需要在边编译的时候加入这个库。
首先下载expat的压缩包。
解压之后cd到解压的文件中执行以下几条命令:
./configure--prefix=$PWD/bin
mkdir bin
make && make install
2.5 安装gdb与gdbserver 2.5.1gdb的安装 解压完之后cd到已经解压过的文件夹中,
修改gdb/remote.c文件,屏蔽process_g_packet函数中的下列两行:
if (buf_len > 2 * rsa->sizeof_g_packet)
error (_(“Remote ‘g’ packet reply is too long:%s”), rs->buf);
在其后添加:
if (buf_len > 2 * rsa->sizeof_g_packet) {
rsa->sizeof_g_packet = buf_len ;
for (i = 0; i < gdbarch_num_regs (gdbarch);i++) {
if (rsa->regs.pnum == -1)
continue;
if (rsa->regs.offset >= rsa->sizeof_g_packet)
rsa->regs.in_g_packet = 0;
else
rsa->regs.in_g_packet = 1;
}
}
在终端输入 ./configure–target=arm-luinx --prefix=$PWD/bin --with-expat --includedir=/expat-2.1.0/bin/includelibdir=/home/steven/workspace/gdb/expat-2.1.0/bin/lib
编译:在终端输入 make
安装:首先创建目录 mkdir tmp;make installprefix=$PWD/tmp
通过arm-linux-gdb–v 查看版本信息,确保是我们编译的版本信息。
将arm-linux-gdb拷贝到我们的执行路径中去: cp tmp/bin/arm-linux-gdb /bin/
如果以后我们需要使用我们自己编译的gdb的话就可以指定绝对路径:/bin/arm-linux-gdb
2.5.2gdbserver的安装 我们需要在开发板上运行gdbserver。
Cd到相应目录中:cd /gdb/gdbserver
配置信息:./configure–target=arm-linux –host=arm-linux
编译:make CC=/usr/local/arm/<交叉编译器位置>/arm-linux-gcc
将gdbserver拷贝到tftp默认目录中:cp gdbserver /tftproot/
运用tftp服务器将gdbserver拷贝到开发板中的bin目录下(默认开发板已经成功链接)<详见3.1操作>
3调试3.1开发板的连接 将开发板(默认已经有uboot)连接到主机上,串口和网络都联通。
在修改ip使主机和板子的ip地址在同一网段的情况下,看板子和主机是否可以ping通,如果是虚拟机的话需要设置虚拟机的网络桥接方式。
可以在虚拟机上方菜单中对其进行设置。
编辑—虚拟机网络编辑器—选中VMnet0如下设置
应用之后,选择回复默认设置,重启虚拟机。
关闭机器的防火墙等各种设置,在保证主机和开发板可以相互ping通的情况下,在开发板终端中输入:
Tftp–g -r gdbserver <主机ip>
下载完成后,将gdbserver软件复制到bin目录下: mvgdbserver /bin/
3.2主机程序编译 用交叉编译器对已经存在的源码文件进行交叉编译:
Arm-linux-gcc -g <源码文件> -o <目标文件>
将生成的目标文件拷贝到tftp目录下,并设置其可读写权限。
3.3开发板操作 运用tftp将待编译目标文件
在开发板上运行gdbserver: gdbserver<本开发板ip>:<端口号> <待测试目标文件>
3.3主机启动gdb操作 在主机上启动gdb操作: /bin/arm-linux-gdb ./<目标文件>
设定公用库:
(gdb) set solib-absolute-prefixnonexistantpath;
set solib-search-path/usr/local/arm/opt/EmbedSky/4.4.6/arm-embedsky-linux-gnueabi/li
(gdb) target remote <开发板ip> :<约定好的端口号>
设置完成之后就可以正常调试了。下面列出几条常用的命令:
(1)l:列出所有源代码
(2)break main:在main处打断点
break test_debug.c:11:在test_debug.c的11行打断点
(3)c:运行到断点处
(4)step:单步执行
(5)next:单步执行,但是step会进入函数里面,但是next不会
(6)print a:打印a这个变量的值
(7)quit:退出,输入此命令则开发板上的gdbserver也退出
这样我们就能和gdb调试一下去对开发板上运行的程序进行调试。
4后记 期间遇到了很多问题。在本文中不能一一陈述,主要的解决途径还是把相关的错误信息放在网络上搜索,并且利用ubutu比较方便的apt-get install <目标文件> 来进行相关的修正。并且在很多情况下,问题是很简单的,也很直接只是因为没注意或者不在意而一直原地踏步。
对于环境搭建来说,最主要的还是要捋清各种编译器和应用程序之间的调用关系。修改配置文件和相应的路径以及编译过程需要很清楚,毕竟有的时候真的是触一发而动全身。有的时候只修改很简单的一个变量就可能需要重新编译一整套的编译过程。