如何使用VSCode+gdbserver远程调试ZMC900E

由于嵌入式设备资源受限,通常无法在其上安装庞大的IDE调试程序,且许多嵌入式系统并无桌面环境。为了方便调试自开发程序,本文介绍利用VSCode与gdbserver进行嵌入式设备上程序的远程调试方法。

  

前言

嵌入式Linux系统,由于系统资源的匮乏,通常无法安装本地编译器进行本地开发,而需要在借助一台主机进行交叉开发。一般情况下,在主机安装相应的交叉编译器,将在主机编辑好的程序交叉编译后,通过一定方式如以太网或者串口将程序下载到目标系统运行,或者进行调试。一般的交叉开发流程如图1所示。关于Windows上搭建交叉编译环境,可以参考《不借助Linux系统,在Windows下如何搭建ZMC900E交叉编译环境》。

图1 嵌入式Linux交叉开发一般流程

由于系统资源限制,通常在ZMC600E/900E上无法安装庞大的IDE来调试程序,同时ZMC600E/900E中默认不带桌面。我们可以通过VSCode+ssh协议远程到ZMC600E/900E来开发和运行程序,但通常只能在设备上通过gdb命令行程序进行调试。为了更加方便地调试程序,可以通过VSCode+gdbserver程序来实现远程调试的目的。接下来将详细介绍如何在Windows上实现远程调试ZMC600E/900E。

  

测试环境

  1. 远程设备:ZMC900E主站控制器

  2. 主机:Win10

  3. IDE: VS Code

  4. 所需软件环境:

  • cmake版本3.xx,推荐3.20及以上版本,下载路径:
  • ++https://cmake.org/download/ ++
  • mingw64(主要需要mingw32-make.exe)获取最新版本,下载路径:
  • ++https://github.com/skeeto/w64devkit/releases ++
  • aarch64-linux-gnu(windows)交叉编译链,包括:
  • ① 编译器aarch64-linux-gnu-gcc.exe aarch64-linux-gnu-g++.exe等;
  • ② aarch64-linux-gnu.cmake 交叉编译工具链配置文件;
  • ③ 调试器aarch64-linux-gnu-gdb.exe gdbserver(arm Linux程序);
  • ④ 可以联系我们技术支持获取。
  1. VSCode需要的插件:
  • C/C++
  • C/C++ Extension Pack
  • CMake
  • CMake Integration
  • CMake Tools
  • GDB Debug
  • Remote - SSH
  • Remote development

图2 VSCode中需要的插件

  1. 环境变量:
  • 将交叉编译链解压到D:/aarch64-linux-gnu(或其他容易找到的地方),将D:/aarch64-linux-gnu/bin 加入环境变量。
  • 将CMake和mingw64也加入到环境变量。
  • 重启使其生效。

图3 Windows环境变量配置

  1. OpenSSL

对win10及更新版本的Windows系统,已默认包含在系统软件中。旧版本Windows需要自行安装。

基本步骤

  1. Windows下交叉编译链的搭建,并尝试编译程序进行验证;

  2. 在VSCode上搭建图形化编译环境;

  3. 搭建远程gdbserver和本地gdb联调。

前两步可以参考《不借助Linux系统,在Windows下如何搭建ZMC900E交叉编译环境》。

  

远程GDB调试

远程调试的基本逻辑是:

  • 将程序、动态库、gdbserver以及ENI文件上传远程ZMC900E设备上,同时在本地需要保留一份一样的程序用于调试;
  • 在远程ZMC900E上启动gdbserver,在本地程序启动aarch64-linux-gnu-gdb.exe程序远程连接到服务器。

1. 修改CMakeLists.txt为Debug模式

打开CMakeLists.txt,输入以下内容。

cmake_minimum_required(VERSION 3.10) project(test) set(CMAKE_BUILD_TYPE Debug) add_definitions(-Wall -ggdb -O0 -pipe) include_directories("../../include") link_directories("../../lib") add_executable(test test.c) target_link_options(test PRIVATE -lpthread -lrt -ldl -lstdc++ -lm) target_link_libraries(test zecm)

其中新增了以下内容:

  • set(CMAKE_BUILD_TYPE Debug)配置编译类型为debug模式;
  • add_definitions(-Wall -ggdb -O0 -pipe)增加编译参数,-Wall开启所有编译警告与提示,指定调试器为gdb,并-O0关闭所有编译优化。

注意:set(CMAKE_BUILD_TYPE Debug)  add_definitions(-Wall -ggdb -O0 -pipe)

这两行为debug必需,且不能开-O优化,必须写-O零,否则调试信息会不完整并错乱,断点或单步调试会错位。

2. 配置本地VSCode的gdb

在侧边栏点Debug,打开下拉栏,点Add Configure,生成新的配置文件。或点击"create a new launch.json file"。将以下配置复制进去并作相应修改,保存。

图4 配置launch.json

图5 配置launch.json 2

在launch.json中写入以下内容。

{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [     {         "name": "g++",         "type": "cppdbg",         "request": "launch",         "program": "{workspaceFolder}/build/{fileBasenameNoExtension}",         "args": [             "test.xml"         ],         "cwd": "{workspaceFolder}", \  \  \  \ \ "stopAtEntry":\ false, \  \  \  \ \ "externalConsole":\ false, \  \  \  \ \ "useExtendedRemote":\ true, \  \  \  \ \ "MIMode":\ "gdb", \  \  \  \ \ "targetArchitecture":\ "arm", \  \  \  \ \ "setupCommands": \[ \  \  \  \  \  \  { \  \  \  \  \  \  \  \ \ "description":\ "Enable pretty-printing for gdb", \  \  \  \  \  \  \  \ \ "text":\ "-enable-pretty-printing", \  \  \  \  \  \  \  \ \ "ignoreFailures":\ true \  \  \  \  \  \  }, \  \  \  \  \  \  { \  \  \  \  \  \  \  \ \ "description":\ "set up remote debug program", \  \  \  \  \  \  \  \ \ "text":\ "set remote exec-file\ {fileBasenameNoExtension}",                 "ignoreFailures": false             },         ],         "miDebuggerPath": "D:/aarch64-linux/bin/aarch64-linux-gnu-gdb.exe",         // "miDebuggerPath": "/usr/bin/gdb-multiarch",         "miDebuggerServerAddress": "192.168.1.136:2000"         }     ] }

这个文件很重要,远程gdb调试的配置项大多都在这个文件中。下面会对文件中的每个需要配置的选项进行说明:

2.1 "program": "{workspaceFolder}/build/{fileBasenameNoExtension}",此选项要指向放在本地的要执行的程序。例如可以写成${workspaceFolder}/build/hello。fileBasenameNoExtension的意思是,如果当前主界面打开hello.c源文件,则fileBasenameNoExtension == hello,将启动同名程序调试,根据实际情况替换为实际程序名或保留。

2.2 "args": ["test.xml"],传给程序的命令行参数。注意调试EtherCAT的时候,命令行参数ENI文件名从此项配置传入,但是ENI文件必须先上传到ZMC900E,与gdbserver和调试程序放在同一路径下。

2.3 

{ "description": "set up remote debug program", "text": "set remote exec-file ${fileBasenameNoExtension}", "ignoreFailures": false }

项设置配合gdbserver --multi COM使用,可以避免频繁重启gdbserver,${fileBasenameNoExtension}同样根据实际情况替换为实际程序名或保留。

2.4 "miDebuggerPath": "D:/aarch64-linux/bin/aarch64-linux-gnu-gdb.exe",指向本地gdb,推荐使用绝对路径,这里指向的是交叉编译链里的gdb。

2.5 "miDebuggerServerAddress": "192.168.1.136:2000" ,远程gdbserver开启时绑定的接口。

3. 启动ZMC900E上的远程gdbserver

ssh远程登录到ZMC900E,把gdbserver传到ZMC900E并放在和待执行程序同一路径下,切换到工作路径,运行。

ZMC900E ./gdbserver --multi 192.168.1.136:200

此处参数---multi(两条杠)可以避免频繁启动gdbserver,使其开启后可以反复远程连接。192.168.1.136为与电脑连接的网口的IP地址,net1默认为192.168.1.136。端口号选择一个不会和其他程序冲突的端口,例如2000。

4. VSCode连接远程gdbserver,开始调试

在VSCode中,打开源代码,在gdb调试页中选择刚刚配置的调试选项,按F5,等待其连接并运行。

图6 启动远程调试

可以看到程序成功运行且断点有效,并且变量列表里也可以实时获取变量的值,可进行单步调试,与本地程序调试无异。

5. VSCode Debug调试界面介绍

首先介绍工具栏。启动调试后,会在代码编辑界面上方浮动一个工具栏。该工具栏的功能从左到右为:继续运行、按行/步骤运行、按步运行、运行直到当前调用栈退出、重新启动程序和停止调试。

图7 调试工具栏

左侧从上往下进行介绍。VARIABLES是变量窗口,可以查看局部变量和全局变量的值,还可以在调试中手动修改值进行测试。WATCH是监视窗口,可以将变量或表达式添加进去进行持续查看。CALL STACK是程序当前的调用栈情况。BREAKPOINTS是当前调试的断点情况。

图8 调试变量、监测、调用栈和断点等窗口

下方log会打印VSCode gdb插件的一些日志信息。

图9 VSCode gdb插件日志

在ZMC900E上,gdbserver也会打印一些日志。

图10 gdbserver日志

  

注意事项

gdbserver开启后由于捕捉了SIGNT信号,即ctrl+C信号,无法用命令行直接退出。如果要退出gdbserver可以另外开一个终端,用ps -A查看pid,然后kill -9 pid。

  

ZMC900E高性能EtherCAT主站控制器

图11 ZMC900E高性能EtherCAT主站控制器

++ZMC900E++  是ZLG致远电子开发的最新一代EtherCAT主站控制器,其核心采用多核异构的应用处理器,内核包括4+1个64位的Arm®Cortex®-A55核,主频2GHz;3个Cortex-R5F内核,主频800MHz。同时板载4GB LPDDR4、8GB eMMC以及32KB FRAM。

ZMC900E EtherCAT主站控制器为了满足不同的自动化应用需求,集成1路专用EtherCAT口、3路通用以太网、1路CANFD、1路RS485、1路TF卡、1路USB3.0 Host、1路HDMI接口、16路Dl数字输入、16路DO数字输出等接口,灵活满足自动化设备应用需求。

ZMC900E 示意图及接口图如下所示:

图12 ZMC900E接口

相关推荐
TDengine (老段)3 天前
TDengine 产品组件 taosX
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
QQ12958455047 天前
ThingsBoard部件数据结构解析
数据结构·数据库·物联网·iot
TDengine (老段)7 天前
TDengine 数学函数 TRUNCATE 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
starandsea9 天前
华为云iot消息积压问题
华为云·iot
starandsea9 天前
华为云iot mqtt 异常停止消费
物联网·华为云·iot
TDengine (老段)11 天前
从 Wonderware 到 TDengine:大理卷烟厂的国产化转型之路
数据库·物联网·时序数据库·iot·tdengine·涛思数据
小叮当⇔11 天前
知识就是力量——EMQX Dashboard核心规则编写方法及示例
python·iot
小叮当⇔13 天前
IOT——WiFi网关 ESP2+MQTT
物联网·iot
TDengine (老段)13 天前
TDengine 数学函数 SIGN 用户手册
大数据·数据库·sql·时序数据库·iot·tdengine·涛思数据
小叮当⇔14 天前
ESP8266无线开关
物联网·iot