在学习单片机的时候我们可以通过集成式IDE 来进行调试,比如MDK、IAR 等。在嵌入式linux 领域是否也可以进行调试呢?答案肯定是可以的,在嵌入式linux 领域我们最常用的就是GDB 调试工具,通过GDB 来调试嵌入式C 程序。本章我们首先学习如何搭建嵌入式Linux的GDB 调试环境,然后讲解如何使用GDB 工具调试C 程序。
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 需要我们移植到开发板上。
我是用的是飞凌的Linux开发板,板载系统和交叉编译器已经都准备好了以上的两个gdb 和gdbserver环境,只需要正确的使用就可以了
对于gdb,其实ubuntu本身有,但是我们因为要编译程序在Linux的arm板上运行,所以要使用对应的编译器才可以,这时候可以查看我们Ubuntu
输入
gdb -v
就可以看到ubuntu自己的gdb编译器
我们需要的则是交叉编译器中的gdb编译器
arm-poky-linux-gnueabi-gdb --v
可以看到版本号是7.10.1
(如果报错,先配置一下运行环境. /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
)
那么交叉编译器的gdb在哪里呢?
打开下面的文件夹
/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi
可以看到 arm-poky-linux-gnueabi-gdb
这就是我们要用到的gdb
在我们的开发板上检查gdbserver的环境,输入命令
gdbserver --version
可以看到版本号也是7.10.1
到这里准备工作完成,这里交叉编译器做的比较好,把自己的交叉编译器的名字修改了,不会引起和默认的gdb编译器名字的冲突,如果涉及编译器名字冲突,还要求改名字
/*gdbtest.c */
#include
#include
int main(int argc, char *argv[])
{
unsigned int times = 0;
while(1){
printf("runing times:%d\r\n", times);
times++;
sleep(1);
}
}
这一节的内容可以直接跳过,然后看后面 VSCode+gdbserver 图形化调试 的内容
使用 arm-poky-linux-gnueabi-gcc
(因为我使用的这一套交叉编译器配置过编译环境,所以直接使用 $CC代替gcc )交叉编译gdbtest.c 文件,要想调试程序,那么编译的时候必须加上“-g”选项,这样编译出来的可执行文件才带有调试信息,这一点一定要切记!编译命令如下所示:
$CC gdbtest.c -o gdbtest -g //编译测试程序,注意-g 选项
编译完成以后将得到的gdbtest 可执行文件发送到开发板中。
scp gdbtest root@192.168.0.232:/tmp
一切准备就绪以后就可以使用GDB 进行调试了,确保ubuntu 和开发板可以进行网络通信。
在开发板中输入如下命令:
gdbserver 192.168.0.2:9000 gdbtest //启动开发板上的gdbserver
上述命令中192.168.0.2 为调试机PC的IP 地址,也就是ubuntu 的IP 地址,9000是端口号,可以任意给一个端口号,gdbtest 是要调试的可执行文件。输入以后 开发板 输出信息如图所示:
接着在ubuntu 中输入如下命令启动gdb 调试工具:
arm-poky-linux-gnueabi-gdb gdbtest
target remote 192.168.0.232:9000
结果报错
试过了检查编译时候 -g,还是删除 -s 都没有成功,不知道怎么回事儿
但是Ubuntu却可以直接结束开发板的调试程序
上面的虽然失败了,但是还有其他的方法,更加的好用也更加的方便
由于主机上的gdb 工具是基于命令行的,因此调试起来不方便,虽然可以加一些插件,但是依旧和IDE 的调试体验差很多。下面我们就来学习一下,如何使用VSCode+gdbserver 来实现图形化界面的嵌入式linux 程序调试。
给VScode 安装远程调试插件“Remote Development”,点击“调试”->“添加配置”,然后选择“C++(GDB/LLDB)”选项,如图
会在当前文件夹新建一个名为“launch.json”的文件,此文件会存放在.vscode 目录下,如图
launch.json 文件默认的内容如下所示:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问:
https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "输入程序名称,例如 ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
launch.json 文件中有几个项目是需要我们根据实际情况配置的:
①、name:调试的项目名
②、program:需要调试的应用程序可执行文件路径。
③、cwd:需要调试的应用程序源码路径。
④、miDebuggerPath:此项需要手动添加,用于指定所使用的交叉编译器gdb 路径。
⑤、miDebuggerServerAddress:此项需要手动添加,远程gdbserver 服务器地址。
修改完成以后的launch.json 文件内容如下所示:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gdbtest",// 修改过
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/gdbtest",// 修改过
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"miDebuggerPath":"/opt/fsl-imx-x11/4.1.15-2.1.0/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gdb", // 修改过
"miDebuggerServerAddress": "192.168.0.232:9000",// 修改过
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
// "miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
这时候我们打开开发板的gdbserver然后直接F5调试我们的程序显然是不行的
这里会出现调试错误的信息,因为我们现在的VS Code还是windows的环境,自然没有办法调试Linux的东西,还是arm的
所以这里就用到vscode无比好用的,直接远程到wsl,步骤如下
然后开发板打开gdbserver
左下角远程到本机的wsl之后,F5调试
就可以看到开发板的调试信息正在输出,然后点击vscode的暂停,就会看到开发板的程序暂停了操作。
现在我们就可以打断点操作,也可以步进调试了
由于是通过网络进行调试的,因此启动调试以后会有一个建立连接的过程,可能需要几秒钟
首先肯定是如何控制程序运行,在VSCode 上方居中的位置有如图所示控制面板:
可以看出,一共有6 个控制按钮,这6 个按钮从左往右功能及快捷键依次如下:
①、继续按钮,快捷键为F5,用于控制程序的运行和暂停,程序运行到断点暂停以后可以
按下此按钮继续运行。
②、单步跳过按钮,快捷键为F10。
③、单步调试按钮,快捷键为F11。
④、单步跳出按钮,快捷键为Shift+F11。
⑤、重启按钮,快捷键为Ctrl+Shift+F5。
⑥、停止按钮,快捷键为Shift+F5。
添加断点的方式也很简单,在需要添加断点的行前面,直接点击即可添加或取消断点,断点添加成功以后会在所在行前面显示一个小红点
有时候我们需要监视一个变量的变化,这个也很简单,鼠标双击选中需要监视的变量名上,然后点击鼠标右键,选择“调试:添加到监视器”
添加成功以后我们就可以在左侧的“监视”窗口看到刚刚添加的变量
vscode 牛逼666