当前位置:首页>Linux>用VSCode打造嵌入式Linux开发的终极IDE

用VSCode打造嵌入式Linux开发的终极IDE

  • 2026-10-11 08:10:09
用VSCode打造嵌入式Linux开发的终极IDE

大家好,我是情报小哥~

第N次scp驱动模块到板子上后,串口又Oops了。手忙脚乱地在板子上用vim看日志,切回本地改代码,再scp,再重启,再看串口……循环往复,一上午就这么没了。

确实有点难忍受这种"原始人"式的开发方式了,于是准备了这篇文章。作为一名写了8年嵌入式Linux的老兵,我曾经也是vim+Source Insight+Eclipse的重度用户,直到我把VScode打造成了一体化开发环境。

今天分享11个非显而易见的高级技巧,覆盖交叉编译、远程开发、内核调试、设备树等全流程。每一个都直击痛点,配置完立刻能用,让你的开发效率至少提升200%,上干货~

技巧1:Remote-SSH终极配置:免密登录+跳板机穿透

解决痛点:每次连接开发板或服务器都要输密码,内网设备无法直接访问,代码同步慢如蜗牛。

具体配置步骤

  1. 生成SSH密钥对(本地执行):
ssh-keygen -t ed25519 -C "your_email@example.com"# 一路回车,不要设置密码
  1. 将公钥复制到目标机器:
# 直接连接的情况ssh-copy-id root@192.168.1.100# 需要跳板机的情况ssh-copy-id -o ProxyCommand="ssh -W %h:%p jump_user@jump_server" root@192.168.1.100
  1. 配置VScode的SSH config文件(~/.ssh/config):
# 跳板机Host jump-server    HostName 123.45.67.89    User jump_user    Port 22    IdentityFile ~/.ssh/id_ed25519# 目标开发板(通过跳板机访问)Host imx6ull-board    HostName 192.168.1.100    User root    IdentityFile ~/.ssh/id_ed25519    ProxyCommand ssh -W %h:%p jump-server    # 关键:保持连接不断开    ServerAliveInterval 60    ServerAliveCountMax 30
  1. 在VScode中按Ctrl+Shift+P,输入Remote-SSH: Connect to Host,选择imx6ull-board即可连接。

连接后,VScode会自动在远程机器上安装服务器端,你可以直接在本地编辑远程文件,完全不需要scp同步。所有操作都是"无感"的,就像在本地编辑一样。

坑点:如果连接失败,检查远程机器的/etc/ssh/sshd_config是否允许密码登录和公钥认证。

技巧2:内核源码智能感知:彻底消灭红色波浪线

解决痛点:内核源码太大,VScode默认索引不全,到处都是红色波浪线,函数跳转经常跳错。

具体配置步骤

  1. 安装bear工具(用于生成编译命令数据库):
# Ubuntu/Debiansudo apt install bear# CentOS/RHELsudo yum install bear
  1. 在内核源码根目录执行编译,生成compile_commands.json:
# 清理之前的编译产物make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- clean# 用bear包装make命令,生成编译命令数据库bear -- make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfigbear --append -- make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8
  1. 配置VScode的c_cpp_properties.json:
{"configurations": [        {"name": "Linux-ARM64","includePath": ["${workspaceFolder}/**","${workspaceFolder}/arch/arm64/include","${workspaceFolder}/include"            ],"defines": ["__KERNEL__","CONFIG_ARM64"            ],"compilerPath": "/usr/bin/aarch64-linux-gnu-gcc","cStandard": "c11","cppStandard": "c++17","intelliSenseMode": "linux-gcc-arm64",// 关键:引入编译命令数据库"compileCommands": "${workspaceFolder}/compile_commands.json"        }    ],"version": 4}

配置完成后,VScode的IntelliSense会精准解析内核的所有宏定义、结构体和函数。你可以:

  • 按F12跳转到任意函数或宏的定义
  • 按Shift+F12查看所有引用
  • 鼠标悬停查看函数原型和注释

坑点:每次修改内核配置(make menuconfig)后,都需要重新生成compile_commands.json。

技巧3:一键交叉编译:tasks.json自动化任务

解决痛点:每次编译都要输入一长串环境变量和make命令,容易出错,效率低下。

具体配置步骤

在.vscode目录下创建tasks.json:

{"version": "2.0.0","tasks": [        {"label": "编译内核镜像","type": "shell","command": "make","args": ["ARCH=arm64","CROSS_COMPILE=aarch64-linux-gnu-","-j8"            ],"group": {"kind": "build","isDefault": true            },"problemMatcher": "$gcc","presentation": {"clear": true            }        },        {"label": "编译设备树","type": "shell","command": "make","args": ["ARCH=arm64","CROSS_COMPILE=aarch64-linux-gnu-","dtbs"            ],"problemMatcher": "$gcc"        },        {"label": "编译并安装模块","type": "shell","command": "make","args": ["ARCH=arm64","CROSS_COMPILE=aarch64-linux-gnu-","modules","INSTALL_MOD_PATH=./modules_install","modules_install"            ],"problemMatcher": "$gcc"        },        {"label": "清理编译产物","type": "shell","command": "make","args": ["ARCH=arm64","CROSS_COMPILE=aarch64-linux-gnu-","clean"            ],"problemMatcher": []        }    ]}
  • 按Ctrl+Shift+B直接执行默认的"编译内核镜像"任务
  • 按Ctrl+Shift+P输入Tasks: Run Task选择其他任务
  • 编译错误会直接在源码中高亮显示,点击即可跳转

小技巧:绑定快捷键。打开键盘快捷键设置(Ctrl+K Ctrl+S),搜索"运行任务",为常用任务设置快捷键,比如F5编译内核,F6编译设备树。

技巧4:远程应用调试:gdbserver+VScode集成

解决痛点:在目标板上用gdb调试应用程序太麻烦,没有图形界面,查看变量和调用栈不方便。

具体配置步骤

  1. 在目标板上安装gdbserver:
# 以Debian/Ubuntu为例apt install gdbserver
  1. 在VScode中安装C/C++插件。

  2. 配置.vscode/launch.json:

{"version": "0.2.0","configurations": [        {"name": "远程调试应用","type": "cppdbg","request": "launch","program": "${workspaceFolder}/build/hello_world","args": [],"stopAtEntry": false,"cwd": "${workspaceFolder}","environment": [],"externalConsole": false,"MIMode": "gdb","miDebuggerPath": "/usr/bin/aarch64-linux-gnu-gdb","miDebuggerServerAddress": "192.168.1.100:1234","setupCommands": [                {"description": "为gdb启用整齐打印","text": "-enable-pretty-printing","ignoreFailures": true                }            ]        }    ]}
  1. 在目标板上启动gdbserver:
gdbserver :1234 ./hello_world
  1. 在VScode中按F5开始调试。

你可以在VScode中设置断点、单步执行、查看变量、查看调用栈,所有操作都和本地调试一样。调试嵌入式应用程序从未如此简单。

坑点:确保本地的交叉gdb版本和目标板上的gdbserver版本一致,否则可能出现兼容性问题。

技巧5:内核调试黑魔法:kgdb+QEMU

解决痛点:内核调试一直是嵌入式Linux开发的噩梦,printk调试效率极低,JTAG调试器又贵又难用。

具体配置步骤

  1. 配置内核开启kgdb支持:
make ARCH=arm64 menuconfig# 开启以下选项:# CONFIG_KGDB=y# CONFIG_KGDB_SERIAL_CONSOLE=y# CONFIG_DEBUG_INFO=y# CONFIG_DEBUG_INFO_DWARF4=y
  1. 编译内核并启动QEMU:
qemu-system-aarch64 \    -machine virt \    -cpu cortex-a57 \    -smp 2 \    -m 1024M \    -kernel arch/arm64/boot/Image \    -append "root=/dev/vda console=ttyAMA0 kgdboc=ttyAMA0,115200 kgdbwait" \    -drive file=rootfs.ext4,if=virtio,format=raw \    -nographic \    -gdb tcp::1234
  1. 配置VScode的launch.json:
{"name": "调试Linux内核(QEMU)","type": "cppdbg","request": "launch","program": "${workspaceFolder}/vmlinux","args": [],"stopAtEntry": false,"cwd": "${workspaceFolder}","environment": [],"externalConsole": false,"MIMode": "gdb","miDebuggerPath": "/usr/bin/aarch64-linux-gnu-gdb","miDebuggerServerAddress": "localhost:1234","setupCommands": [        {"text": "set architecture aarch64"        },        {"text": "target remote localhost:1234"        }    ]}

你可以在VScode中调试内核的任何部分,包括驱动程序。设置断点、单步执行、查看内核变量和寄存器,甚至可以在中断处理函数中打断点。

小技巧:如果有JTAG/SWD调试器,可以安装Cortex-Debug插件,实现硬件级别的内核调试,速度更快,功能更强大。

技巧6:设备树开发利器:语法高亮+一键编译

解决痛点:设备树文件没有语法高亮,容易写错,编译和拷贝到目标板的过程繁琐。

具体配置步骤

  1. 安装DeviceTree插件。

  2. 配置tasks.json添加设备树编译和部署任务:

{"label": "编译并部署设备树","type": "shell","command": "make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs &&     scp arch/arm64/boot/dts/freescale/imx6ull-myboard.dtb root@192.168.1.100:/boot/","problemMatcher": "$gcc"}
  1. 配置VScode的文件关联(settings.json):
{"files.associations": {"*.dts": "devicetree","*.dtsi": "devicetree"    }}
  • 设备树文件有语法高亮和自动补全
  • 按快捷键一键编译并部署设备树到目标板
  • 利用VScode的差异对比工具(右键文件→"选择以进行比较")快速检查dts修改

坑点:设备树修改后必须重启目标板才能生效。

技巧7:大型工程极速搜索:过滤无关代码

解决痛点:Linux内核源码有几十万个文件,搜索一个函数要等半天,而且会搜到很多无关架构的代码。

具体配置步骤

在.vscode/settings.json中添加搜索排除规则:

{"files.exclude": {"**/.git": true,"**/arch/alpha": true,"**/arch/arc": true,"**/arch/arm": true, // 如果你只开发ARM64"**/arch/csky": true,"**/arch/h8300": true,"**/arch/hexagon": true,"**/arch/ia64": true,"**/arch/m68k": true,"**/arch/microblaze": true,"**/arch/mips": true,"**/arch/nds32": true,"**/arch/nios2": true,"**/arch/openrisc": true,"**/arch/parisc": true,"**/arch/powerpc": true,"**/arch/riscv": true,"**/arch/s390": true,"**/arch/sh": true,"**/arch/sparc": true,"**/arch/um": true,"**/arch/x86": true,"**/arch/xtensa": true,"**/drivers/**": false, // 保留驱动目录"**/sound/**": true,"**/tools/**": true,"**/samples/**": true    },"search.exclude": {"**/build": true,"**/modules_install": true    }}

配置完成后,VScode只会索引你关心的架构和目录,搜索速度会提升10倍以上。按Ctrl+P可以秒搜任何文件,按Ctrl+Shift+F可以在整个工程中搜索字符串。

小技巧:使用工作区(Workspace)管理多个相关项目,比如内核、U-Boot和应用程序,可以在一个窗口中切换,非常方便。

技巧8:终端与串口无缝集成:分屏操作

解决痛点:需要在多个窗口之间切换,一会儿看串口输出,一会儿编译代码,一会儿拷贝文件,手忙脚乱。

具体配置步骤

  1. 在VScode中按Ctrl+打开内置终端。

  2. 点击终端右上角的"+"号新建终端,然后点击"拆分终端"按钮,将终端分成左右两部分。

  3. 在左侧终端运行串口工具:

# 使用picocom(推荐)picocom -b 115200 /dev/ttyUSB0# 或者使用minicomminicom -D /dev/ttyUSB0 -b 115200
  1. 在右侧终端执行编译、scp拷贝文件等操作。
  • 所有操作都在一个窗口中完成,不需要切换窗口
  • 可以同时查看串口输出和编译日志
  • 按Ctrl+Shift+可以快速切换终端

小技巧:配置快捷键一键发送文件到目标板。在keybindings.json中添加:

{"key": "ctrl+alt+s","command": "workbench.action.terminal.sendSequence","args": {"text": "scp ${file} root@192.168.1.100:/root/\u000D"    }}

按Ctrl+Alt+S即可将当前编辑的文件发送到目标板的/root目录。

技巧9:代码片段定制:3秒生成驱动框架

解决痛点:每次写驱动都要重复写很多模板代码,比如字符设备驱动、platform_driver等,浪费时间。

具体配置步骤

  1. 按Ctrl+Shift+P输入Preferences: Configure User Snippets,选择c.json。

  2. 添加以下代码片段:

{"字符设备驱动框架": {"prefix": "chardev","body": ["#include <linux/module.h>","#include <linux/fs.h>","#include <linux/cdev.h>","#include <linux/device.h>","","#define DEVICE_NAME \"${1:mydev}\"","#define CLASS_NAME \"${2:myclass}\"","","static dev_t dev_num;","static struct cdev cdev;","static struct class *dev_class;","static struct device *dev_device;","","static int ${1:mydev}_open(struct inode *inode, struct file *file)","{","    printk(KERN_INFO \"${1:mydev} opened\\n\");","    return 0;","}","","static int ${1:mydev}_release(struct inode *inode, struct file *file)","{","    printk(KERN_INFO \"${1:mydev} closed\\n\");","    return 0;","}","","static struct file_operations fops = {","    .owner = THIS_MODULE,","    .open = ${1:mydev}_open,","    .release = ${1:mydev}_release,","};","","static int __init ${1:mydev}_init(void)","{","    int ret;","","    // 分配设备号","    ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME);","    if (ret < 0) {","        printk(KERN_ERR \"Failed to allocate device number\\n\");","        return ret;","    }","","    // 初始化cdev","    cdev_init(&cdev, &fops);","    cdev.owner = THIS_MODULE;","","    // 添加cdev","    ret = cdev_add(&cdev, dev_num, 1);","    if (ret < 0) {","        printk(KERN_ERR \"Failed to add cdev\\n\");","        goto unregister_chrdev;","    }","","    // 创建类","    dev_class = class_create(THIS_MODULE, CLASS_NAME);","    if (IS_ERR(dev_class)) {","        printk(KERN_ERR \"Failed to create class\\n\");","        ret = PTR_ERR(dev_class);","        goto del_cdev;","    }","","    // 创建设备","    dev_device = device_create(dev_class, NULL, dev_num, NULL, DEVICE_NAME);","    if (IS_ERR(dev_device)) {","        printk(KERN_ERR \"Failed to create device\\n\");","        ret = PTR_ERR(dev_device);","        goto destroy_class;","    }","","    printk(KERN_INFO \"${1:mydev} module loaded\\n\");","    return 0;","","destroy_class:","    class_destroy(dev_class);","del_cdev:","    cdev_del(&cdev);","unregister_chrdev:","    unregister_chrdev_region(dev_num, 1);","    return ret;","}","","static void __exit ${1:mydev}_exit(void)","{","    device_destroy(dev_class, dev_num);","    class_destroy(dev_class);","    cdev_del(&cdev);","    unregister_chrdev_region(dev_num, 1);","    printk(KERN_INFO \"${1:mydev} module unloaded\\n\");","}","","module_init(${1:mydev}_init);","module_exit(${1:mydev}_exit);","","MODULE_LICENSE(\"GPL\");","MODULE_AUTHOR(\"Your Name\");","MODULE_DESCRIPTION(\"${1:mydev} character device driver\");"        ],"description": "生成字符设备驱动框架"    }}

在C文件中输入chardev,按Tab键,3秒就能生成一个完整的字符设备驱动框架。你还可以添加platform_driver、i2c_driver、spi_driver等常用代码片段。

技巧10:内核日志高亮分析:快速定位问题

解决痛点:内核日志密密麻麻,很难一眼找到Oops、panic等关键信息。

具体配置步骤

  1. 安装Log File Highlighter插件。

  2. 配置settings.json添加自定义高亮规则:

{"logFileHighlighter.customPatterns": [        {"pattern": "Oops","foreground": "#ff0000","fontWeight": "bold"        },        {"pattern": "BUG","foreground": "#ff0000","fontWeight": "bold"        },        {"pattern": "panic","foreground": "#ff0000","fontWeight": "bold"        },        {"pattern": "ERROR","foreground": "#ff0000"        },        {"pattern": "WARNING","foreground": "#ff9900"        },        {"pattern": "INFO","foreground": "#0099ff"        },        {"pattern": "\\[\\s*\\d+\\.\\d+\\]","foreground": "#00cc00"        }    ]}
  • 内核日志中的时间戳显示为绿色
  • ERROR显示为红色
  • WARNING显示为橙色
  • Oops、BUG、panic显示为粗体红色

一眼就能找到关键信息,大大提高问题定位效率。

技巧11:Dev Containers:一键搭建统一开发环境

解决痛点:新成员入职要花好几天搭建开发环境,每个人的环境都不一样,经常出现"在我电脑上能跑"的问题。

具体配置步骤

  1. 安装Dev Containers插件。

  2. 在工程根目录创建.devcontainer目录,添加Dockerfile:

FROM ubuntu:22.04# 安装必要的工具RUN apt update && apt install -y \    build-essential \    gcc-aarch64-linux-gnu \    g++-aarch64-linux-gnu \    gdb-multiarch \    make \    cmake \    git \    bear \    picocom \    ssh \    && rm -rf /var/lib/apt/lists/*# 设置工作目录WORKDIR /workspace
  1. 添加devcontainer.json:
{"name": "嵌入式Linux开发环境","build": {"dockerfile": "Dockerfile"    },"customizations": {"vscode": {"extensions": ["ms-vscode.cpptools","ms-vscode.cpptools-extension-pack","ms-vscode-remote.remote-ssh","ms-vscode-remote.remote-containers","plorefice.devicetree","emilast.logfilehighlighter"            ]        }    },"forwardPorts": [1234],"postCreateCommand": "git config --global --add safe.directory /workspace"}
  1. 按Ctrl+Shift+P输入Dev Containers: Reopen in Container,VScode会自动构建Docker镜像并启动容器。
  • 所有团队成员使用完全相同的开发环境
  • 新成员入职只需要安装Docker和VScode,一键打开工程即可开始开发
  • 可以为不同的项目配置不同的开发环境,互不干扰

写在最后

以上11个技巧,覆盖了嵌入式Linux开发的全流程。从代码编辑、智能感知、交叉编译,到远程调试、设备树开发、日志分析,再到团队协作的环境统一,VScode都能完美胜任。

我已经用这套工作流开发了5年多,彻底告别了vim、Source Insight和Eclipse。现在我的开发效率比以前提高了至少3倍,再也不用在多个工具之间来回切换了。

END

来源:嵌入式情报局


版权归原作者所有,如有侵权,请联系删除。
▍推荐阅读
“0 : 5,中国程序员惨败!”
如果不考虑STM32,你会推荐哪些国产单片机?
这个法国老哥写的C代码,把全世界程序员都干沉默了
→点关注,不迷路←

最新文章

随机文章