附录B 其他第三方软件移植(FTP、OpenSSH、GDB)

目录

  • 开发板 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 来进行图形化调试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/108667.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

利用Excel支持JUnit参数化测试

在JUnit里面&#xff0c;可以使用CsvFileSource读取csv文件进行参数化测试&#xff0c;可是CSV文件不支持格式&#xff0c;编辑颇为麻烦&#xff0c;尤其是多次编辑&#xff0c;因此自然想到是否可以使用Excel文件&#xff0c;可以有各种格式&#xff0c;支持各类数据。 最新开…

常见面试题-MySQL专栏(一)

为什么 mysql 删了行记录&#xff0c;反而磁盘空间没有减少&#xff1f; 答&#xff1a; 在 mysql 中&#xff0c;当使用 delete 删除数据时&#xff0c;mysql 会将删除的数据标记为已删除&#xff0c;但是并不去磁盘上真正进行删除&#xff0c;而是在需要使用这片存储空间时&…

(速进)完美解决“用户在命令行上发出了 EULAS_AGREED=1,表示不接受许可协议。”以及“此产品安装程序不支持降级”

安装VMware时候&#xff0c;出现以下两种情况的原因是&#xff1a;未彻底卸载&#xff08;之前安装过VMware&#xff09;&#xff0c;例如&#xff1a;还有相关配置信息、注册表信息等。只要彻底清理就可以解决此问题。 网上很多帖子使用了powershell里的命令 例如&#xff1…

基于 matplotlib 实现的基本排序算法的动态可视化项目源码,通过 pyaudio 增加音效,冒泡、选择、插入、快速等排序

基本排序算法动态可视化 依托 matplotlib 实现的基本排序算法的动态可视化&#xff0c;并通过 pyaudio 增加音效。 安装 在使用之前请先检查本地是否存在以下库&#xff1a; matplotlibpyaudiofire requirements.txt 中包含了上述的库 使用 目前本项目仅提供了以下排序算…

【Java网络原理】 六

本文主要介绍了网络层的IP协议/NAT机制/IPv6的由来以及在数据链路层涉及到的以太网协议和DNS域名解析系统 一.网络层 1.IP协议 各个字段所表示的含义 >4位版本号 用来表示IP协议的版本&#xff0c;现在只有两个版本IPv4 &#xff0c;IPv6 >4位首部长度 IP报头可变&…

ZYNQ连载02-开发环境

ZYNQ连载02-开发环境 1. 官方文档 ZYNQ开发使用的软件为Vivado/Vitis/PetaLinux,软件体积比较大&#xff0c;硬盘保留100G以上的空间&#xff0c;赛灵思提供详细的文档&#xff0c;链接如下&#xff1a; ZYNQ文档 2. Vivido和Vitis安装 赛灵思统一安装程序 3. PetaLinux安装…

设计模式面试知识点总结

文章目录 设计原则常用设计模式单例模式1. 饿汉式2. 懒汉式3. 双重检测 工厂方法模式&#xff08;简单工厂、工厂方法、抽象工厂&#xff09;简单工厂静态工厂工厂方法模式抽象工厂模式 策略模式责任链模式 设计原则 标记设计模式原则名称简单定义OCP开闭原则对扩展开放&#…

VSCode 自动格式化

1.打开应用商店&#xff0c;搜索 prettier code formatter &#xff0c;选择第一个&#xff0c;点击安装。 2.安装完成后&#xff0c;点击文件&#xff0c;选择首选项&#xff0c;选择设置。 3.在搜索框内输入 save &#xff0c;勾选在保存时格式化文件。 4.随便打开一个文件&a…

【iOS】——知乎日报第二周总结

文章目录 一、自定义cell内容乱序问题二、WKWebView加载网页三、通过cell的协议函数进入指定网页四、滚动视图左滑加载新的网页五、隐藏导航栏 一、自定义cell内容乱序问题 当我下拉刷新的时候一开始我自定义的cell的内容顺序没有问题&#xff0c;当我一直下拉刷新或者上滑看以…

leetcode-链表

链表是一个用指针串联起来的线性结构&#xff0c;每个结点由数据域和指针域构成&#xff0c;指针域存放的是指向下一个节点的指针&#xff0c;最后一个节点指向NULL&#xff0c;第一个结点称为头节点head。 常见的链表有单链表、双向链表、循环链表。双向链表就是多了一个pre指…

ITSource 分享 第5期【校园信息墙系统】

项目介绍 本期给大家介绍一个 校园信息墙 系统&#xff0c;可以发布信息&#xff0c;表白墙&#xff0c;分享墙&#xff0c;校园二手买卖&#xff0c;咨询分享等墙信息。整个项目还是比较系统的&#xff0c;分为服务端&#xff0c;管理后台&#xff0c;用户Web端&#xff0c;小…

ELASTICO-A Secure Sharding Protocol For Open Blockchains

INTRO 在中本聪共识中&#xff0c;通过POW机制来公平的选举leader&#xff0c;不仅非常消耗power&#xff0c;并且拓展性也不好。现在比特币中是7 TPS&#xff0c;和其他的支付系统相比效率相差甚远。 当前的许多拜占庭共识协议&#xff0c;并不支持在一个开放的环境中使用&a…

C语言实现输入一个字符串,递归将其逆序输出

完整代码&#xff1a; // 输入一个字符串&#xff0c;递归将其逆序输出。如输入 LIGHT&#xff0c;则输出 THGIL #include<stdio.h> #include<stdlib.h> //字符串的最大长度 #define N 20//逆序输出字符串 void func(char *str){if (*str\0){//结尾时直接退出递归…

Java SE 学习笔记(十七)—— 单元测试、反射

目录 1 单元测试1.1 单元测试概述1.2 单元测试快速入门1.3 JUnit 常用注解 2 反射2.1 反射概述2.2 获取类对象2.3 获取构造器对象2.4 获取成员变量对象2.5 获取常用方法对象2.6 反射的作用2.6.1 绕过编译阶段为集合添加数据2.6.2 通用框架的底层原理 1 单元测试 1.1 单元测试概…

基于单片机的太阳跟踪系统的设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、设计的主要内容二、硬件电路设计2.1跟踪控制方案的选择2.1.1跟踪系统坐标系的选择2.2系统总体设计及相关硬件介绍…

服务熔断保护实践--Hystrix

概述 微服务有很多互相调用的服务&#xff0c;构成一系列的调用链路&#xff0c;如果调用链路中某个服务失效或者网络堵塞等问题&#xff0c;而有较多请求都需要调用有问题的服务时&#xff0c;这是就会造成多个服务的大面积失效&#xff0c;造成服务“雪崩”效应。 服务“雪…

十九、类型信息(2)

本章概要 Class 对象 类字面常量泛化的 Class 引用cast() 方法 Class 对象 要理解 RTTI 在 Java 中的工作原理&#xff0c;首先必须知道类型信息在运行时是如何表示的。这项工作是由称为 **Class**对象 的特殊对象完成的&#xff0c;它包含了与类有关的信息。实际上&#x…

JVM第二十三讲:Java动态调试技术原理

Java动态调试技术原理 本文是JVM第二十三讲&#xff0c;Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践&#xff0c;通过学习java agent方式进行动态调试&#xff0c;了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …

微信小程序设计之主体文件app-wxss/less

一、新建一个项目 首先&#xff0c;下载微信小程序开发工具&#xff0c;具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后&#xff0c;注册小程序账号&#xff0c;具体注册方法&#xff0c;可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

elementUI 特定分辨率(如1920*1080)下el-row未超出一行却换行

在1920*1080分辨率下&#xff0c; el-col 内容未超出 el-col 宽度&#xff0c;el-col 不足以占据一行&#xff0c;el-row 却自动换行了&#xff08;其他分辨率没有这个问题&#xff09;。 截图&#xff1a; 排查&#xff1a; el-col 内容没有溢出&#xff1b;没有多余的 pad…