vscode图形化远程调试嵌入式linux开发板程序

概要

嵌入式开发往往采用交叉编译,在自己主机编译好开发板所需的程序,然后上传到开发板进行执行观察效果,在开发阶段往往会采用加日志打印的方式进行调试执行,有些场景往往没有debug调试来的直接,在嵌入式设备上虽然可以使用gdb来调试程序,但开发板资源(CPU、内存)通常有限,直接运行 gdb 可能影响调试效率,调试时开发板还要复制源代码才能做到代码定位,往往比较麻烦。

以下讲解主机vscode图形界面 + 交叉编译工具链的gdb + 开发板 gdbserver 的远程调试方式。

  1. 开发板是sipeed公司的Maix-II-Dock(M2dock) M2dock
  2. 开发的示例程序为libmaix,这个是我从官方fork的项目,基于官方的项目在examples/camera示例目录下开发的视频监控项目作为远程调试的演示
  3. 主机使用的是windows下wsl子系统对开发板程序进行编译和远程调试
  4. 开发工具使用vscode远程连接到wsl子系统
  5. windows下安装usbipd工具,可以将开发板连接到windows系统产生的usb连接映射到wsl子系统中方便使用adb和开发板交互

整体架构流程

  1. 下载windows下安装usbipd工具,将开发板接入电脑usb口,先usbipd查看开版本对应的BUSID,我这里是1-4然后执行usbipd attach -a -w -b=1-4命令将usb口抓取到wsl子系统使用,执行完毕后在子系统中可以执行adb devices查看是否有显示相应的设备,后续可以直接使用adb push将程序推送到开发板,以及后续可以直接adb shell进入开发板的shell来操作开发板,如果自己的wsl子系统没有adb命令先用apt安装adb
    在这里插入图片描述

  2. 示例代码编译完成后会在dist目录下生成相关可执行程序、库、启动程序的脚本,正常情况下我们直接将dist目录下的所有程序都推送到开发板中,直接在开发板中执行./start_app.sh脚本程序就能正常运行了,但是正常编译的程序并不带有调试信息。

  3. 修改examples/camera目录下的CMakeLists.txt文件,增加带有调试信息的编译选择add_compile_options(-g -O0),然后再重新编译程序,把编译得到的带调试信息的程序通过adb push推送到开发板
    在这里插入图片描述

  4. 使用交叉编译工具链编译能在开发板上运行的gdbserver
    安装必要依赖(编译 gdb 所需的基础工具):
    sudo apt update && sudo apt install -y wget tar bzip2 build-essential libgmp-dev libmpfr-dev libmpc-dev zlib1g-dev libexpat1-dev texinfo

    下载 gdb 源码
    wget http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.xz
    tar -xf gdb-10.2.tar.xz
    cd gdb-10.2/

    确保交叉编译工具链已正确设置,并且路径已添加到系统 PATH 中。
    export PATH=/opt/toolchain-sunxi-musl/toolchain/bin:$PATH
    设置 STAGING_DIR 环境变量,OpenWrt 工具链通常需要这个变量:
    export STAGING_DIR=/opt/toolchain-sunxi-musl

    手动指定头文件和库路径在编译时显式指定工具链的 include 和 lib 路径:
    ./configure
    –host=arm-openwrt-linux-muslgnueabi
    –prefix=$PWD/install
    –disable-werror
    CFLAGS=“-I/opt/toolchain-sunxi-musl/toolchain/arm-openwrt-linux-muslgnueabi/include”
    LDFLAGS=“-L/opt/toolchain-sunxi-musl/toolchain/arm-openwrt-linux-muslgnueabi/lib”
    CC=arm-openwrt-linux-muslgnueabi-gcc
    CXX=arm-openwrt-linux-muslgnueabi-g++

    编译
    make -j$(nproc)

    进入 gdbserver 目录
    cd gdbserver
    由于编译gdbserver需要依赖编译gdb生成的文件所以前面先编译gdb是必须的

    配置 gdbserver
    使用与 GDB 相同的工具链配置,显式指定头文件和库路径:
    ./configure
    –host=arm-openwrt-linux-muslgnueabi
    –prefix=$PWD/install
    CFLAGS=“-I/opt/toolchain-sunxi-musl/toolchain/arm-openwrt-linux-muslgnueabi/include”
    LDFLAGS=“-L/opt/toolchain-sunxi-musl/toolchain/arm-openwrt-linux-muslgnueabi/lib”
    CC=arm-openwrt-linux-muslgnueabi-gcc
    CXX=arm-openwrt-linux-muslgnueabi-g++

    编译 gdbserver
    make -j$(nproc)

    检查生成的 gdbserver
    file gdbserver
    正常输出应类似:
    gdbserver: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-arm.so.1, not stripped

    使用adb push命令将gdbserver推送到和要调试的程序在相同目录下
    adb push gdbserver /root/maix_dist/

    该交叉编译工具链编译所得的gdbserver我已经上传到github上了,如有需要可以自取

  5. 开发板使用gdbserver启动要调试的程序
    在这里插入图片描述
    启动debug_app.sh脚本观察到以下打印说明启动正常
    在这里插入图片描述

  6. vscode配置launch.json来进行远程调试

  7. 启动时可能会存在报错,这是因为wsl缺少libtinfo.so.5库
    在这里插入图片描述

  8. 创建libtinfo.so.5软链接到libtinfo.so.6,我wsl本机内有libtinfo.so.6,如果没有可使apt进行安装
    sudo ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5
    在这里插入图片描述

  9. 再次启动调试,程序正常被调试
    在这里插入图片描述

小结

以上就是vscode图形化远程调试嵌入式linux开发板程序的整个过程,如有问题欢迎沟通交流

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐