目录
- 开发板 FTP 服务器移植与搭建
- vsftpd 源码下载
- vsftpd 移植
- vsftpd 服务器测试
- 配置vsftpd
- 添加新用户
- Filezilla 连接测试
- 开发板 OpenSSH 移植与使用
- OpenSSH 简介
- OpenSSH 移植
- OpenSSH 源码获取
- 移植zlib 库
- 移植openssl 库
- 移植openssh 库
- openssh 设置
- openssh 使用
- ssh 登录
- scp 命令拷贝文件
- 嵌入式GDB 调试搭建与使用
- GDB 简介
- GDB 移植
- 获取gdb 和gdbserver 源码
- 编译gdb
- 移植gdbserver
- 使用GDB 进行嵌入式程序调试
- 编写一个测试应用
- GDB 调试程序
- VSCode+gdbserver 图形化调试
- VSCode 设置
- VSCode 调试方法
开发板 FTP 服务器移植与搭建
我们可以将ALPHA 开发板作为一个小型的FTP 服务器,这样我们就可以通过FileZilla 软
件直接在开发板和windows 之间通过网络进行文件互传。这个需求也是个别客户提出来的,我
们觉得很不错,所以就专门写了这章教程。在开发板上搭建FTP 服务器很简单,就是vsftpd 的
移植,本章我们就来学习一下如何在ALPHA 开发板上移植vsftpd,搭建一个FTP 服务器。
vsftpd 源码下载
vsftpd 是一个在UNIX 类操作系统上运行的FTP 服务器名字,全称是“very secure FTP
daemon”,vsftpd 是一个完全免费、开源的FTP 服务器软件,vsftpd 在linux 发行版中非常流行。
我们在《第四章开发环境搭建》中已经给大家讲解了如何在ubuntu 下安装vsfptd,ubuntu
下安装vsfptd 很简单,直接使用apt 命令安装即可。现在我们需要在自己制作的根文件系统中
安装vsftpd,所以就需要我们自己移植vsfpd。首先需要到vsftpd 官网下载vsftpd 源码,网址为
https://security.appspot.com/vsftpd.html。注意!此网站为国外网站,因此大家可能打不开。打不
开的话也不用担心,我们已经将vsftpd 源码放到了开发板光盘中,路径为:开发板光盘A-基础
资料-》1、例程源码-》7、第三方库源码-》vsftpd-3.0.3.tar.gz。vsftpd 官网打开以后如图B1.1.1
所示:
图B1.1.1 vsftpd 官网
点击图B1.1.1 中的“Online source/docs”,跳转到vsftpd 源码下载页面,如图B1.1.2 所示:
图B1.1.2 下载vsftpd
从图B1.1.2 可以看出目前最新的版本为3.0.3 ,点击
https://security.appspot.com/downloads/vsftpd-3.0.3.tar.gz 即可下载。
vsftpd 移植
vsftpd 源码获取到以后就是移植工作了,将vsftpd-3.0.3.tar.gz 发送到ubuntu 中,然后使用
如下命令进行解压:
tar -vxzf vsftpd-3.0.3.tar.gz //解压缩
解压缩完成以后会得到一个名为“vsftpd-3.0.3”的文件夹,输入如下命令进入到此文件夹:
cd cd vsftpd-3.0.3 //进入到vsftpd 源码目录
打开Makefile,我们需要配置一下,修改Makefile 中的CC 变量为我们所使用的交叉编译
器:
CC = arm-linux-gnueabihf-gcc //CC 为交叉编译器
Makefile 修改完成以后就可以编译:
make //编译vsftpd
等待编译完成,会得到两个文件:vsftpd 和vsftpd.conf,我们需要这两个文件。将vsftpd 拷
贝到开发板根文件系统下的/usr/sbin 目录下,将vsftpd.conf 拷贝到开发板根文件系统的/etc 目录
下,命令如下:
sudo cp vsftpd /home/zuozhongkai/linux/nfs/rootfs/usr/sbin/ //拷贝vsftpd
sudo cp vsftpd.conf /home/zuozhongkai/linux/nfs/rootfs/etc/ //拷贝vsftpd.conf
拷贝完成以后给予vsftpd 可执行权限,并且修改vsfptd.conf 所属用户为root,命令如下:
chmod +x /usr/sbin/vsftpd
chown root:root /etc/vsftpd.conf
至此,vsftpd 就已经移植成功了,接下来就是测试一下。
vsftpd 服务器测试
配置vsftpd
我们要先配置一下vsftpd,打开vsftpd.conf,然后将下面两行配置前面的“#”删除掉:
local_enable=YES //取消前面的“#”
write_enable=YES //取消前面的“#”
配置完成以后如图B1.3.1.2 所示:
图B1.3.1.2 修改后的vsftpd.conf
添加新用户
如果第一次添加用户的话要先将ubuntu 下的/etc/passwd 和/etc/group 这两个文件复制到开
发板根文件系统的对应目录,命令如下:
sudo cp /etc/passwd /home/zuozhongkai/linux/nfs/rootfs/etc/ -f
sudo cp /etc/group /home/zuozhongkai/linux/nfs/rootfs/etc/ -f
然后修改开发板根文件系统中的/etc/passwd 和/etc/group 这两个文件,只保留“root”这一
项。passwd 文件“root”行最后改为“/bin/sh”,修改后的passwd 和group 文件内容如图B1.3.2.1
和B1.3.2.2 所示:
图B1.3.2.2 修改后的passwd 文件
图B1.3.2.3 修改后的group 文件
vsftpd 默认需要两个用户,这两个用户名分别为:“ftp”和“nobody”。在创建这两个用户
之前先检查一下下面几个文件和目录是否存在,如果不存在的话需要先创建下面这些文件和目
录:
/home //目录,不存在的话自行创建
/usr/share/empty //目录,不存在的话自行创建
/var/log //目录,不存在的话自行创建
/var/log/vsftpd.log //文件,不存在的话自行创建
创建命令如下:
mkdir /home
mkdir /usr/share/empty -p
mkdir /var/log -p
touch /var/log/vsftpd.log
准备好以后就可以使用“adduser”命令创建“ftp”和“nobody”这两个用户,命令如下:
adduser ftp //创建ftp 用户
adduser nobody //创建nobody 用户
创建过程如图B1.3.2.3 所示:
图B1.3.2.3 ftp 和nobody 用户创建过程
最后我们还需要创建一个登录用户,Filezilla 连接FTP 服务器的时候一般需要输入用户名
和密码,当然了,Filezilla 也支持匿名登录。如果要使用用户名加密码登录的话就要创建一个用
户,用户名自己定义,这里我创建一个名为“zuozhogkai”的用户,命令如下:
adduser zuozhongkai //创建登录要用户
最终会在/home 目录下存在三个用户目录,分别对应“ftp”、“nobody”和“zuozhongkai”,
如图B1.3.2.4 所示:
图B1.3.2.4 三个用户目录
Filezilla 连接测试
测试之前确保直接开发板网络连接正常,电脑可以ping 通开发板!
输入如下命令,启动vsftpd 服务器:
vsftpd & //启动vsftpd
vsftpd 启动以后就可以使用filezilla 进行连接测试了,新建站点,站点设置如图B1.3.3.1 所
示:
设置好以后就可以连接了,连接成功以后如图B1.3.3.2 所示:
图B1.3.3.2 Filezilla 连接成功
连接成功以后重新打包根文件系统,然后通过Mfgtool 将根文件系统烧写到开发板的
EMMC 或者NAND 中。根文件系统烧写完成以后重启开发板,然后启动vsftpd 服务,Filezilla
连接到开发板的FTP 服务器上。连接成功以后我们就可以通过拖拽的方式从windows 向开发板,或者从开发板向windows 下传输文件了。
注意,只能向用户目录下传输文件!比如我使用“zuozhongkai”这个用户登录的FTP 服务
器,因此只能与开发板的/home/zuozhongkai 目录进行文件互传。
我这里向开发板的/home/zuozhongkai 目录发送了一个视频文件,传输速度如图B1.3.3.3 所
示:
图B1.3.3.3 FTP 文件传输过程
从图B1.3.3.3 可以看出,Windows 向开发板发送文件的速度基本在11~12MB/S 之间,换算
成网速就是88~96Mbps/S,I.MX6ULL 的网口是100Mbps,可以看出FTP 传输的速度还是不错
的。当然了也与你所使用的存储设备速度有关,笔者采用EMMC 核心板进行测试,EMMC 的
读写速度要比NAND 快很多,如果使用NAND 核心板的话速度可能会下降。
我们可以设置vsftpd 开机自启动,在/etc/init.d/rcS 里面启动vsftpd 服务,在rcS 文件里面添
加如下内容即可:
vsftpd &
这样我们每次开机以后就会自动启动vsftpd 了。
开发板 OpenSSH 移植与使用
有时候我们需要远程登录到开发板上对系统进行一些操作,这个时候就要使用到SSH 服
务。SSH 是较可靠、专为远程登录会话和其他网络服务提供安全性的协议,OpenSSH 是SSH 协
议的免费开源版本,本章我们就来学习一下如何在开发板中移植OpenSSH,实现SSH 服务。
OpenSSH 简介
SSH 全称为Secure Shell(安全外壳协议,简称SSH),是一种加密的网络传输协议,用于在
不安全的网络中为网络服务提供安全的传输环境。SSH 功能很强大,但是最常用的还是用于远
程登录。OpenSSH 是SSH 协议的具体实现,OpenSSH 是一款开源、免费的SSH 软件,提供了
服务器端后台程序和客户端工具,OpenSSH 提供了很多程序,常用有以下几个:
1、ssh
ssh 软件用于替换rlogin 与Telnet。
2、scp 和sftp
将文件复制到其他主机上,用于替换rcp。
3、sshd
SSH 服务器。
OpenSSH 移植
OpenSSH 源码获取
这里我们一共需要移植三个软件包:zlib、openssl 和openssh。依次到这三个软件的官网下
载对应的源码,官网如下:
zlib 官网:http://www.zlib.net/。
openssl 官网:https://www.openssl.org/source/。
openssh 官网:http://www.openssh.com/。
这三个软件的源码我们已经放到了开发板光盘中,路径为:1、例程源码->7、第三方库源
码->zlib-1.2.11.tar.gz、openssl-1.1.1d.tar.gz 和openssh-8.2p1.tar.gz。接下来就依次编译、移植这三
个软件。
移植zlib 库
参考65.7.1 章节: Linux 音频驱动实验
移植openssl 库
参考70.3.1 章节:Linux WIFI驱动实验
移植openssh 库
1、交叉编译openssh 库
先解压openssh 源码,命令如下:
tar -vxzf openssh-8.2p1.tar.gz
解压完成以后就会生成一个名为“openssh-8.2p1”的文件夹,进入此文件夹里面,然后配置
并编译openssh,命令如下:
cd openssh-8.2p1/
./configure --host=arm-linux-gnueabihf --with-libs --with-zlib=/home/zuozhongkai/linux/IMX6ULL/tool/zlib --with-ssl-dir=/home/zuozhongkai/linux/IMX6ULL/tool/openssl --disable-etc-default-login CC=arm-linux-gnueabihf-gcc AR=arm-linux-gnueabihf-ar //配置
make //编译
在配置openssh 的过程中,“–with-zlib”参数用于指定zlib 库所在的目录,“–with-ssl-dir”
参数用于指定openssl 库所在的目录,编译openssh 的时候不用“make install”。
2、将openssh 相关文件拷贝到开发板中
openssh 交叉编译完成以后在开发板中创建如下所示目录(如果存在的话就不需要创建):
/usr/local/bin
/usr/local/sbin
/usr/local/libexec
/usr/local/etc
/var/run
/var/empty
创建命令如下:
mkdir /usr/local/bin -p
mkdir /usr/local/sbin -p
mkdir /usr/local/libexec/ -p
mkdir /usr/local/etc -p
mkdir /var/run -p
mkdir /var/empty/ -p
上述目录创建好以后将如下文件拷贝到开发板的/usr/local/bin 目录下:
scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan
将如下文件拷贝到开发板的/usr/local/sbin 目录下:
sshd
将如下文件拷贝到开发板的/usr/local/etc 目录下:
moduli ssh_config sshd_config
将如下文件拷贝到开发板的/usr/local/libexec 目录下:
sftp-server ssh-keysign
创建软连接,进入开发板中的/bin 目录下,输入如下命令创建软连接:
cd /bin/
ln -s /usr/local/bin/scp
ln -s /usr/local/bin/sftp
ln -s /usr/local/bin/ssh
ln -s /usr/local/bin/ssh-add
ln -s /usr/local/bin/ssh-agent
ln -s /usr/local/bin/ssh-keygen
ln -s /usr/local/bin/ssh-keyscan
再进入开发板的/sbin 目录下,输入如下命令创建软连接:
cd /sbin/
ln -s /usr/local/sbin/sshd
软连接创建完成以后就可以直接调用上面ssh 相关命令了。
打开/usr/local/etc/sshd_config 文件,找到“#PermitRootLogin”所在行,将其改为“
PermitRootLogin yes”。
openssh 设置
1、添加sshd 用户
首先添加“sshd”用户,在使用adduser 命令添加sshd 用户的时候需要检查一些文件或目
录是否存在,具体参考B1.3.2 章节。当所需的文件都存在以后就可以使用adduser 创建名为“sshd”
的用户了,创建sshd 用户的时候需要设置密码,大家一定要记得这个密码,这里我设置简单一
点,为“123456”,创建过程如图B2.3.1 所示:
图B2.3.1 sshd 用户添加过程
2、在开发板上生成秘钥文件
一切准备好以后我们还需要在开发板中生成秘钥文件,使用我们上面移植openssh 所编译
出来的ssh-keygen 软件即可。进入到开发板的/usr/local/etc 目录下,输入如下所示命令生成秘钥
文件,由于6ULL 性能比较差,有些秘钥文件生成过程可以会有点耗时,打开几十秒:
ssh-keygen -t rsa -f ssh_host_rsa_key -N ""
ssh-keygen -t dsa -f ssh_host_dsa_key -N ""
ssh-keygen -t ecdsa -f ssh_host_ecdsa_key -N ""
ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N ""
完成以后就会在/usr/local/etc 目录下产生8 个以“ssh_host_”开头的秘钥文件,如图B2.3.1
所示:
图B2.3.1 生成的秘钥文件
openssh 使用
openssh 移植已经移植到了开发板中,我们可以通过sshd 软件在开发板上搭建openssh 服
务器,然后在其他的主机上通过ssh 来登录开发板。我们可以同样使用scp 命令来向开发板传
输文件。首先要在开发板上启动ssh 服务,sshd 软件用于启动ssh 服务,注意要输入全路径!输
入如下命令:
/sbin/sshd //启动sshd 服务
也可以在/etc/init.d/rcS 文件中加入如下命令,实现ssh 服务开机自启动:
/sbin/sshd &
ssh 登录
启动以后我们就可以使用XobaXterm、SecureCRT 等终端软件通过SSH 服务登录开发板,这里以XobaXterm 为例讲解一下。打开XobaXterm 软件,点击“Session”按钮,在弹出的
“Session settings”界面上选择“SSH”。在“Remote host”栏输入开发板IP 地址,在“Specify
username”栏输入登录用户名,比如我们上面创建的“sshd”用户,配置完成以后如图B2.4.1.1
所示:
图B2.4.1.1 SSH 配置
配置完成以后点击“OK”按钮,此时就会打开ssh 会话框,如图B2.4.1.2 所示:
图B2.4.1.2 SSH 登录
输入sshd 用户密码,可能会弹出是否保存密码对话框,选择保存即可。如果密码正确的话
就会登录到开发板上,如图B2.4.1.3 所示:
图B2.4.1.3 SSH 登录成功
SSH 登录成功以后我们就可以直接对开发板进行各种操作了。
同样的,我们也可以在ubuntu 下通过ssh 命令登录开发板,输入如下命令:
ssh sshd@192.168.1.251
其中“sshd”为登录账户名字,192.168.1.251 是开发板的IP 地址。用户名和开发板IP 地址
之间用“@”符号链接起来。第一次与开发板建立连接的时候会让你进行确认,输入“yes”就
行了,如图B2.4.1.4 所示:
图B2.4.1.4 确认建立连接
输入“yes”以后就会让你输入“sshd”用户密码,如图B2.4.1.5 所示:
图B2.4.1.5 输入sshd 用户密码
如果密码正确的话就会登录进开发板,可以对开发板进行各种操作,如图B2.4.1.6 所示:
图B2.4.1.6 通过SSH 对开发板进行操作
输入“exit”命令即可退出SSH 会话。
scp 命令拷贝文件
如果我们要向开发板发送一个文件,我们可以通过TF 卡或者U 盘来中转,或者通过我们
上一章讲的tftp 来发送。本章我们移植openssh 的时候也编译出来了一个名为“scp”的命令,
所以我们可以在开发板中使用scp 命令向其他主机发送文件,同样的其他主机也可以使用scp命令向开发板发送文件。比如我们要把ubuntu 中的一个文件发送到开发板中,输入如下命令即
可:
scp seriaApp sshd@192.168.1.251
将seriaApp 文件发送到开发板中,发送完成以后就会在开发板的根目录下看到此文件,如
图B2.4.2.1 所示:
图B2.4.2.1 scp 命令拷贝结果
关于openssh 就讲解到这里,通过ssh 大家就可以远程登录开发板了。
嵌入式GDB 调试搭建与使用
在学习单片机的时候我们可以通过集成式IDE 来进行调试,比如MDK、IAR 等。在嵌入
式linux 领域是否也可以进行调试呢?答案肯定是可以的,在嵌入式linux 领域我们最常用的就
是GDB 调试工具,通过GDB 来调试嵌入式C 程序。本章我们首先学习如何搭建嵌入式Linux
的GDB 调试环境,然后讲解如何使用GDB 工具调试C 程序。
GDB 简介
gdb 工具是GNU 项目调试器,基于命令行。和其他的调试器一样,我们可以使用gdb 来一
行行的运行程序、单步执行、跳入/跳出函数、设置断点、查看变量等等,它是UNIX/LINUX 操
作系统下强大的程序调试工具。gdb 支持多种语言,包括Ada、汇编、C/C++、D、Fortran、GO、
Objective-C、OpenCL、Modula-2、Pascal 和Rust。关于gdb 更多详细的信息请到gdb 官网查阅,
gdb 官网地址为:www.gnu.org。
一般的桌面Linux 系统,比如ubuntu、centos 等,我们可以直接运行gdb 来调试程序。但
是嵌入式中芯片性能一般比较弱,所以直接在嵌入式系统中运行gdb 不太现实(性能强大的嵌入
式芯片可以这么做)。嵌入式系统中一般在PC 端运行gdb 工具,源码也是在PC 端,源码对应
的可执行文件放到开发板中运行。为此我们需要在开发板中运行gdbserver,通过网络与PC 端
的gdb 进行通信。因此要想在PC 上通过gdb 调试嵌入式程序,那么需要两个东西:gdb 和
gdbserver,其中gdb 是运行在PC 上的,gdbserver 需要我们移植到开发板上。
GDB 移植
一般交叉编译已经自带了gdb 和gdbserver,因此可以不用移植,直接使用交叉编译器自带
的即可。比如本教程所使用的arm-linux-gnueabihf-gcc 就自带了主机使用的arm-linux-gnueabihf-gdb 和开发板所使用的gdbserver。进入ubuntu 中交叉编译器安装目录中的bin 文件夹下,比如
笔者的就是/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin,此目录中就包
含了arm-linux-gnueabihf-gdb 和gdbserver,如图B3.2.1 所示:
图B3.2.1 交叉编译自带的gdb 和gdbserver
如果交叉编译器自带了gdb 和gdbserver 的话只需要将gdbserver 拷贝到开发板根文件系统
的/bin 目录下,然后直接看B3.3 章节。
如果交叉编译器没有自带gdb 和gdbserver 那就需要自己手动编译了,继续看本节即可。
获取gdb 和gdbserver 源码
首先到gdb 官网上获取源码,地址为http://www.gnu.org/software/gdb/download/,在笔者写
本教程的时候,最新的gdb 源码版本为9.1。已经放到了开发板光盘中,路径为:1、例程源码
->7、第三方库源码-> gdb-9.1.tar.gz。将gdb 源码发送到ubuntu 中中并解压,命令如下:
tar -vxzf gdb-9.1.tar.gz //加压gdb 源码
解压完成以后就会得到一个名为gdb-9.1 的文件夹,此文件夹就是gdb 和gdbserver 源码,
其中gdb-9.1/gdb/gdbserver 目录就是gdbserver 源码。
编译gdb
1、编译gdb
首先编译gdb,gdb 是运行在PC 端的程序,gdb 编译的时候需要进行配置,配置项如下:
–target:目标机交叉编译器前缀,也就是你所使用的交叉编译器前缀,比如在本教程中就
设置为arm-linux-gnueabihf。
–host:指定编译后的程序在哪里运行,编译gdb 的时候就需用设置,因为我们是需要在PC
上运行的,编译gdbserver 的时候就要设置为arm-linux。
–prefix:指定安装目录。
创建一个名为“gdb”的文件夹,用来保存编译后的gdb 和gdbserver,路径自行选择。gdb
编译比较奇葩!使用如下命令配置并编译gdb:
cd gdb-9.1/ //进入gdb 源码目录
mkdir build //在gdb 源码下新建build 目录,gdb 编译比较奇葩!不能直接在gdb 源
//码目录下进行配置和编译,必须新建一个文件夹,然后在此文件夹下配
//置和编译,切记!
cd build //进入到刚刚创建的build 目录下
../configure --target=arm-linux-gnueabihf --prefix=/home/zuozhongkai/linux/IMX6ULL/tool/gdb
//配置gdb。配置完成以后会在build 目录下生成Makefile 文件。
make //编译
make install //安装
编译完成以后PC 端运行的gdb 工具就会安装到gdb/bin 目录下,名字为arm-linux-gnueabihf-
gdb,如图B3.2.2.1 所示:
图B3.2.2.1 编译后的gdb 工具
图B3.2.2.1 中的arm-linux-gnueabihf-gdb 就会我们编译得到的gdb 工具,输入如下命令运
行此gdb:
cd gdb/bin //进入到bin 目录下
./arm-linux-gnueabihf-gdb //运行此gdb
结果如图B2.2.2.2 所示:
图B3.2.2.2 gdb 运行结果
从图B3.2.2.2 可以看出,arm-linux-gnueabihf-gdb 版本号为9.1,说明编译安装成功,输入
“q”可以退出gdb 工具。
2、关闭交叉编译器自带的gdb
我们安装的arm-linux-gnueabihf 交叉编译器已经默认自带了一个名为“arm-linux-gnueabihf-gdb”的gdb 工具!大家可以到自己的交叉编译器安装目录看一下,相对路径为:gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin,如图B3.2.2.3 所示:
图B3.2.2.3 交叉编译器自带的gdb 工具
从图B3.2.2.3 可以看出,编译器自带的gdb 工具和我们编译出来的gdb 名字一样,这两个
都可以使用,也就是说我们可以不用自行编译gdb,直接使用交叉编译器里面的也是可以的!
只是这两个gdb 的版本号可能不一样,可以查看一下交叉编译器自带的gdb 工具版本号,我这
里如图B3.2.2.4 所示:
图B3.2.2.4 交叉编译器自带gdb 工具版本号
从图B3.2.2.4 可以看出,交叉编译器自带的gdb 工具版本号为7.10。现在有个问题,一山
不能容二虎,9.1 版本和7.10 版本只能留一个,我测试过,这两个任意哪一个都可以。这里我
们使用自己编译的9.1 版本的gdb 工具,因此需要对交叉编译器自带的7.10 版本的gdb 工具重
命名,这里笔者将其重命名为“arm-linux-gdb”。
最后打开ubuntu 的/etc/profile 文件,修改PATH 环境变量值,将我们编译出来的9.1 版本
的“arm-linux-gnueabihf-gdb”所在的路径添加进去,这样我们就可以直接使用此gdb 了,根据
自己的实际情况修改PATH 值,比如我的PATH 内容如下:
export PATH=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin:/home/
zuozhongkai/linux/IMX6ULL/tool/gdb/bin:$PATH
其中红色加粗部分就是我所编译出来的9.1 版本gdb 工具所存放的路径,修改完以后重启
ubuntu,这个时候我们就可以使用命令“arm-linux-gnueabihf-gdb”来打开gdb 调试器了。
移植gdbserver
接下来移植gdbserver,gdbserver 是在开发板上运行的,因此要交叉编译。gdbserver 源码保
存在gdb-9.1/gdb/gdbserver 目录下,进入此目录,然后输入如下命令配置并编译:
cd gdb-9.1/gdb/gdbserver //进入到gdbserver 目录
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf //配置
make CC=arm-linux-gnueabihf-gcc //交叉编译gdbserver
编译完成以后就会在目录下生成一个名为“gdbserver”的文件,这个就是我们需要放到开
发板上去的gdbserver,如图B3.2.3.1 所示:
图B3.2.3.1 gdbserver 软件
将图B3.2.3.1 中交叉编译出来的gdbserver 软件发送到开发板中的/usr/bin 目录下,完成以
后在开发板中输入如下命令查看gdbserver 版本号:
gdbserver –version //查看版本号
如果gdbserver 移植成功的话就会打印出其版本号,如图B3.2.3.2 所示:
图B3.2.3.2 gdbserver 版本号
从图B3.2.3.2 可以看出,当前gdbserver 版本号为9.1,说明我们的移植是成功的。PC 上的
gdb 和开发板上的gdbserver 都已经准备好了,接下来就是使用这两个工具来完成调试。
使用GDB 进行嵌入式程序调试
编写一个测试应用
首先编写一个简单的测试软件,我们一会就用gdb 来调试这个软件,新建名为gdbtest.c 的
文件,在里面输入如下所示内容:
示例代码B3.3.1.1 gdbtest.c 测试代码
1 #include <stdio.h>
2 #include <unistd.h>
3
4 int main(int argc, char *argv[])
5 {
6 unsigned int times = 0;
7
8 while(1) {
9 printf("runing times:%d\r\n", times);
10 times++;
11 sleep(1);
12 }
13 }
使用arm-linux-gnueabihf-gcc 交叉编译gdbtest.c 文件,要想调试程序,那么编译的时候必
须加上“-g”选项,这样编译出来的可执行文件才带有调试信息,这一点一定要切记!编译命
令如下所示:
arm-linux-gnueabihf-gcc gdbtest.c -o gdbtest -g //编译测试程序,注意-g 选项
编译完成以后将得到的gdbtest 可执行文件发送到开发板中。
GDB 调试程序
一切准备就绪以后就可以使用GDB 进行调试了,确保ubuntu 和开发板可以进行网络通信。
在开发板中输入如下命令:
gdbserver 192.168.1.253:2001 gdbtest //启动开发板上的gdbserver
上述命令中192.168.1.253 为调试机的IP 地址,也就是ubuntu 的IP 地址,2001 是端口号,
可以任意给一个端口号,gdbtest 是要调试的可执行文件。输入以后开发板输出信息如图B3.3.2.1
所示:
图B3.3.2.1 开发板上gdbserver 运行
接着在ubuntu 中输入如下命令启动gdb 调试工具:
arm-linux-gdb gdbtest
结果如图B3.3.2.2 所示:
图B3.3.2.2 ubuntu 执行gdb 命令
图B3.3.2.2 中最下面的(gdb)行用于输入命令,输入如下命令连接到开发板上:
target remote 192.168.1.251:2001 //连接到开发板上
上述命令表示连接到开发板上,其中192.168.1.251 就是开发板IP 地址,2001 就是开发板
gdbserver 设置的端口号。连接成功以后开发板中的gdbserver 就会提示连接信息,如图B2.3.2.3
所示:
图B3.3.2.3 调试机与开发板连接成功
从图B3.3.2.3 可以看出,远端调试机的IP 地址为192.168.1.253,也就是我们的ubuntu 址,连接成功以后就可以在ubuntu 上进行代码调试了。gdb 工具是一个基于命令行的调试工具,我
们就来学习一下常用的几个命令。
1、l 命令
l 命令(list)用于列出所有程序源码,输入“l”,结果如图B3.3.2.4 所示:
图B3.3.2.4 l 命令运行结果
从图B3.3.2.4 可以看出,输入“l”命令以后就打印出了调试程序的所有源码,如果源码没
有打印完的话就重复按下“l”命令,或者按下回车键,gdb 调试工具中回车键表示重复上一个
命令!
2、b 命令
b 命令(break)用于设置断点,也可以用缩写“b”,后面可以跟具体的函数或者行号,比如
“break main”表示在main 函数处设置断点,“break 11”在第11 行设置断点。输入如下命令,
在main 函数处设置断点:
b main 或break main
设置以后提示如图B3.3.2.5 所示:
图B3.3.2.5 在main 函数处设置断点
从图B3.3.2.5 可以看出,断点1 设置到了gdbtest.c 的第6 行,大家可以看一下图B3.3.2.4,
第6 行正好是main 函数的起始处。
3、c 命令
c 命令用于运行到断点处,输入c 命令程序就会运行,直到下一个断点处,如图B3.3.2.6 所
示:
图B3.3.2.6 c 命令运行结果
从图B3.3.2.6 可以看出,当前程序运行到第6 行停止,因为我们前面在第6 行放置了一个
断点,因此程序运行停止。继续输入“c”命令,程序就会持续不断的运行,开发板中就会不断
的打印出信息,如图B3.3.2.7 所示:
图B3.3.2.7 程序继续运行
4、s 命令
s 命令(step)是单步运行执行,此函数会进入到函数里面。
5、n 命令
n 命令(next)也是单步运行,但是n 命令不会进入到函数里面。
6、p 命令
p 命令(print)用于打印某个变量值。
7、q 命令
q 命令(quit)用于退出调试,开发板上的gdbserver 也会停止。
关于gdb 调试更多详细的使用方法和命令大家自行上网查阅,这里就不一一介绍了。
VSCode+gdbserver 图形化调试
上一章我们讲了如何使用gdb+gdbserver 实现对嵌入式linux 程序的调试,由于主机上的
gdb 工具是基于命令行的,因此调试起来不方便,虽然可以加一些插件,但是依旧和IDE 的调
试体验差很多。本章我们就来学习一下,如何使用VSCode+gdbserver 来实现图形化界面的嵌入
式linux 程序调试。
VSCode 设置
给VScode 安装远程调试插件“Remote Development”,点击“调试”->“添加配置”,然后
选择“C++(GDB/LLDB)”选项,如图B4.1.1 所示:
图B4.1.1 选择调试配置文件
选择图B4.1.1 中的“C++(GDB/LLDB)”,会在当前文件夹新建一个名为“launch.json”的文
件,此文件会存放在.vscode 目录下,如图B4.1.2 所示:
图B4.1.2 launch.json 文件
launch.json 文件默认的内容如下所示:
示例代码B4.1.2 launch.json 文件默认内容
1 {
2 // 使用IntelliSense 了解相关属性。
3 // 悬停以查看现有属性的描述。
4 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "name": "(gdb) 启动",
9 "type": "cppdbg",
10 "request": "launch",
11 "program": "输入程序名称,例如${workspaceFolder}/a.out",
12 "args": [],
13 "stopAtEntry": false,
14 "cwd": "${workspaceFolder}",
15 "environment": [],
16 "externalConsole": false,
17 "MIMode": "gdb",
18 "setupCommands": [
19 {
20 "description": "为gdb 启用整齐打印",
21 "text": "-enable-pretty-printing",
22 "ignoreFailures": true
23 }
24 ]
25 }
26 ]
27 }
launch.json 文件中有几个项目是需要我们根据实际情况配置的:
①、name:调试的项目名
②、program:需要调试的应用程序可执行文件路径。
③、cwd:需要调试的应用程序源码路径。
④、miDebuggerPath:此项需要手动添加,用于指定所使用的交叉编译器gdb 路径。
⑤、miDebuggerServerAddress:此项需要手动添加,远程gdbserver 服务器地址。
修改完成以后的launch.json 文件内容如下所示:
示例代码B4.1.3 launch.json 配置好的内容
1 {
......
5 "version": "0.2.0",
6 "configurations": [
7 {
8 "name": "gdbtest",
9 "type": "cppdbg",
10 "request": "launch",
11 "program": "${workspaceFolder}/gdbtest",
12 "args": [],
13 "stopAtEntry": false,
14 "cwd": "${workspaceFolder}",
......
25 "miDebuggerPath": "/home/zuozhongkai/linux/IMX6ULL/tool/gdb/bin/arm-linux-gnueabihf-gdb",
26 "miDebuggerServerAddress": "192.168.1.251:2001"
27
28 }
29 ]
30 }
注意示例代码B4.1.3 中加粗的部分就是我根据自己的实际情况所填写的内容。
VSCode 调试方法
VSCode 设置好以后就可以进行调试了,首先要启动开发板上的gdbserver,输入如下命令:
gdbserver 192.168.1.253:2001 gdbtest
接下来在点击VSCode 上的“调试”->“启动调试”按钮,如图B4.2.1 所示:
图B4.2.1 启动调试
由于是通过网络进行调试的,因此启动调试以后会有一个建立连接的过程,可能需要几秒
钟,建立成功以后如图B4.2.2 所示:
图B4.2.2 调试界面
图B4.2.2 就是调试界面,调试功能非常强大,简单介绍一下调试方法。
1、控制程序运行
首先肯定是如何控制程序运行,在VSCode 上方居中的位置有如图B4.2.3 所示控制面板:
图B4.2.3 程序运行控制面板
可以看出,一共有6 个控制按钮,这6 个按钮从左往右功能及快捷键依次如下:
①、继续按钮,快捷键为F5,用于控制程序的运行和暂停,程序运行到断点暂停以后可以
按下此按钮继续运行。
②、单步跳过按钮,快捷键为F10。
③、单步调试按钮,快捷键为F11。
④、单步跳出按钮,快捷键为Shift+F11。
⑤、重启按钮,快捷键为Ctrl+Shift+F5。
⑥、停止按钮,快捷键为Shift+F5。
2、断点添加
添加断点的方式也很简单,在需要添加断点的行前面,直接点击即可添加或取消断点,断点添加成功以后会在所在行前面显示一个小红点,如图B4.2.4 所示:
图B4.2.4 添加断点
3、监视变量
有时候我们需要监视一个变量的变化,这个也很简单,鼠标双击选中需要监视的变量名
上,然后点击鼠标右键,选择“调试:添加到监视器”,如图B4.2.5 所示:
图B4.2.5 添加变量到调试器
添加成功以后我们就可以在左侧的“监视”窗口看到刚刚添加的变量,如图B4.2.6 所示:
图B4.2.6 监视的变量
关于VSCode 调试嵌入式linux 程序的方法就介绍到这里,大家可以多练习几次,以后编写
linux 应用的时候就可以通过VSCode 来进行图形化调试。