VSCode+arm-none-eabi-gcc交叉编译+CMake构建+OpenOCD(基于Raspberry Pico RP2040)

发布于:2025-07-07 ⋅ 阅读:(18) ⋅ 点赞:(0)

settings.json:

{
  // 字符集编码选择
  "files.encoding": "utf8",
  // 自动保存任意文件
  "files.autoSave": "afterDelay",
  // 文件图标主题:"material-icon-theme"
  "workbench.iconTheme": "material-icon-theme",
  // 颜色主题设置
  "workbench.colorTheme": "Default Dark Modern",
  //粘贴时格式化代码
  "editor.formatOnPaste": true,
  //保存时格式化代码
  "editor.formatOnSave": true,
  //设置字体的大小,最小值能设置为6
  "editor.fontSize": 15,
  //设置字体的粗细
  "editor.fontWeight": "500",
  //设置字体的样式
  // "terminal.integrated.fontFamily":"Courier New",
  //使用Ctrl+滚轮缩放编辑区的字体大小
  "editor.mouseWheelZoom": true,
  //使用Ctrl+滚轮缩放终端Terminal的字体大小
  "terminal.integrated.mouseWheelZoom": true,
  //设置为false,这样打开新的文件时,不会自动关闭旧的文件
  "workbench.editor.enablePreview": false,
  //*************************************************************************//
  "cmake.buildBeforeRun": true,
  "cmake.configureOnOpen": true,
  "cmake.configureSettings": {
    "CMAKE_MODULE_PATH": "${env:PICO_INSTALL_PATH}/pico-sdk-tools"
  },
  //该行配置很重要!!!在tasks.json中的任务类型如果是"shell",则这里的shell选择,关系到对应shell命令的使用适配与否。
  "terminal.integrated.defaultProfile.windows": "Command Prompt", //You can also choose from the following three shells:"PowerShell" or "Git Bash" or "Windows PowerShell"
  "terminal.explorerKind": "integrated",
  /****************************VSCode的CMake默认构建生成器为Ninja******************************/
  /******************************************************************************************/
  /******************************************************************************************/
  /******************************************************************************************/
  // "makefile.makePath": "D:/Software/embedded_dev_tools/xpack-ninja-build-1.12.1-1/bin/ninja.exe",
  // "cmake.generator": "Ninja",
  /******************************************************************************************/
  /******************************************************************************************/
  /****************************VSCode的CMake默认构建生成器为Ninja******************************/
  // "makefile.makePath": "D:/Software/embedded_dev_tools/make/bin/make.exe",
  // "cmake.generator": "Unix Makefiles",
  //*************************************************************************//
  "cmake.statusbar.advanced": {
    "debug": {
      "visibility": "visible"
    },
    "launch": {
      "visibility": "visible"
    },
    "build": {
      "visibility": "visible"
    },
    "buildTarget": {
      "visibility": "visible"
    },
  },
  "MicroPython.executeButton": [
    {
      "text": "▶",
      "tooltip": "运行",
      "alignment": "left",
      "command": "extension.executeFile",
      "priority": 3.5
    }
  ],
  "MicroPython.syncButton": [
    {
      "text": "$(sync)",
      "tooltip": "同步",
      "alignment": "left",
      "command": "extension.execute",
      "priority": 4
    }
  ],
  "files.associations": {
    "stdio.h": "c",
    "stdlib.h": "c"
  }
}

c_cpp_properties.json:

{
  "configurations": [
    {
      "name": "Pico-RP2040_ARM_GCC",
      "includePath": [
        "${workspaceFolder}/**"
        // "${env:PICO_SDK_PATH}/**"
      ],
      "defines": [
        "__GNUC__"
      ],
      "compilerPath": "D:/Software/embedded_dev_tools/xpack-arm-none-eabi-gcc-13.3.1-1.1/bin/arm-none-eabi-gcc.exe",
      "compileCommands": "${workspaceFolder}/build/compile_commands.json",
      //这一配置在目前所搭建的环境下没用,但是如果你使用的是SDK,库和驱动文件与项目工程不在一个文件夹中,这一步就很有用了,它能让你在当前项目就能向库代码跳转。
      "cStandard": "gnu17",
      "cppStandard": "gnu++14",
      "intelliSenseMode": "gcc-arm",
      "configurationProvider": "ms-vscode.cmake-tools"
    }
  ],
  "version": 4
}

tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "CMake configure",
            "type": "shell",
            "command": "cmake", //要执行的命令,前提是已经在系统环境变量PATH中安装了CMake
            "args": [
                "-D",
                "CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE", //生成compile_commands.json的文件,该文件是为了让vscode有代码导航、自动补全和语法高亮功能。
                "-G", //配置生成器类型
                "Ninja", //"Unix Makefiles",
                "-B", //配置生成Makefile or Ninja脚本及其相关文件的路径, 使得源码和构建过程文件分开,以便更好地管理项目
                "./build" //这条命令会告诉 CMake 创建一个名为 build 的目录(如果它不存在的话),并在该目录下生成构建文件
                //"-DCMAKE_BUILD_TYPE=Debug", //设置构建类型:Debug,Release,RelWithDebInfo,MinSizeRel
                //"--debug-output", //显示详细的CMake 配置 过程信息
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": "$gcc"
        },
        {
            "label": "CMake build",
            "type": "shell", //直接使用shell的手动输入命令行“cmake --build”
            "command": "cmake",
            "args": [
                "--build", //调用CMake的统一命令在某个文件夹下构建,具有跨平台特性。不论后端构建工具是 Make or Ninja
                "${workspaceFolder}/build", //生成可执行文件.elf和进制文件.hex/.bin的路径
                "--config Debug",
                "--target ${workspaceRootFolderName}.elf", //"all", //允许指定单一或多个目标来构建,而不是构建整个项目。这可以显著减少构建时间
                "--parallel 5" //使用-j 5是等效的
                // "--verbose" //让底层的构建工具(如 Make 或 Ninja)输出详细的编译命令,为CMake通用命令,可简写为 -v
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "dependsOn": [
                "CMake configure"
            ],
            "problemMatcher": [
                "$gcc"
            ]
        },
        {
            "type": "shell",
            "label": "CMake cleanRebuild",
            "dependsOrder": "sequence",
            "dependsOn": [
                "CMake clean",
                "CMake build"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": [
                "$gcc"
            ]
        },
        {
            "label": "CMake clean",
            "type": "shell",
            // "command": "Remove-Item -Path ./build/* -Recurse", //powershell(win10系统及以上)可调用
            "command": "rm -rf ./build/*", //cmd(win10系统以下) 或 git bash 都可调用    rm -r -f,Linux用法
            //cmd下:del /q /s build或erase /q /s build仅删除文件,不删除文件夹;rmdir /q /s build或rd /q /s build删除文件夹, /s 递归删除非空的目录及其内容
            "args": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": [
                "$gcc"
            ]
        },
        {
            "label": "flash with CMSIS-DAP-Link",
            "type": "shell",
            "command": "openocd",
            "args": [
                "-f",
                "interface/cmsis-dap.cfg",
                "-f",
                "target/rp2040-v1.cfg",
                "-c",
                "adapter speed 2000",
                "-c",
                "program build/${workspaceRootFolderName}.elf verify reset exit"
            ],
            "group": "build",
            "problemMatcher": [
                "$gcc"
            ],
            "dependsOn": [ //任务依赖
                "CMake build"
            ]
        },
        {
            "label": "flash with J-Link",
            "type": "shell",
            "command": "openocd",
            "args": [
                "-f",
                "interface/jlink-swd.cfg",
                "-f",
                "target/rp2040-v1.cfg",
                "-c",
                "adapter speed 1000",
                "-c",
                "program build/${workspaceRootFolderName}.elf verify reset exit"
            ],
            "group": "build",
            "problemMatcher": [
                "$gcc"
            ],
            "dependsOn": [ //任务依赖
                "CMake build"
            ]
        }
    ]
}

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": "Pico-rp2040 Debug with cmsis-dap-link",
      "cwd": "${workspaceRoot}",
      "executable": "${command:cmake.launchTargetPath}",
      "request": "launch",
      "type": "cortex-debug",
      "servertype": "openocd",
      "gdbPath": "gdb-multiarch",
      "device": "RP2040",
      "configFiles": [
        "interface/cmsis-dap.cfg",
        "target/rp2040.cfg"
      ],
      "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
      "openOCDLaunchCommands": [
        "adapter speed 5000"
      ],
      "postRestartCommands": [
        "break main",
        "continue"
      ],
      "runToEntryPoint": "main",
      "showDevDebugOutput": "none",
      "preLaunchTask": "flash with CMSIS-DAP-Link" //每次调试之前会先下载程序
    },
    {
      "name": "Pico-rp2040 Debug with j-link",
      "cwd": "${workspaceRoot}",
      "executable": "${command:cmake.launchTargetPath}",
      "request": "launch",
      "type": "cortex-debug",
      "servertype": "openocd",
      "gdbPath": "gdb-multiarch",
      "device": "RP2040",
      "configFiles": [
        "interface/jlink-swd.cfg",
        "target/rp2040.cfg"
      ],
      "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
      "openOCDLaunchCommands": [
        "adapter speed 5000"
      ],
      "postRestartCommands": [
        "break main",
        "continue"
      ],
      "runToEntryPoint": "main",
      "showDevDebugTimestamps": true,
      "showDevDebugOutput": "none",
      "preLaunchTask": "flash with J-Link" //每次调试之前会先下载程序
    }
  ]
}

CMakeLists.txt:

# Raspberry pi Pico Cmake工程

cmake_minimum_required(VERSION 3.20)

set(CMAKE_SIZE arm-none-eabi-size)

set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)

# 设置pico_sdk
set(PICO_SDK_PATH "D:/Software/embedded_dev_tools/Pico_SDK_v1.5.1/pico-sdk")

# 导入pico_sdk,必须放在工程之前
include(pico_sdk_import.cmake)

# 设置工程,名称可以根据需要设置
# project : 定义工程名称,并可以指定工程可支持的语言,语法格式为 project(项目域名 语言)
# .HEX  .bin  .elf  .map的文件名设置
project(rp2040_blink C CXX ASM)


#设置代码调试等级
set(CMAKE_BUILD_TYPE "Debug")
#   +---------------+---------------+--------------+--------------+----------+
#   |               |               | optimization | assert works | stripped |
#   +---------------+---------------+--------------+--------------+----------|
#   |               |     None      |              |              |          |
#   |    -g         |     Debug     |     no       |     yes      |    no    |
#   |-O3 -DNDEBUG   |    Release    |    full      |      no      |   yes    |
#   |-O2 -g -DNDEBUG| RelWithDebInfo|    good      |      no      |    no    |
#   |-Os -DNDEBUG   |   MinSizeRel  |    size      |      no      |   yes    |
#   +---------------+---------------+--------------+--------------+----------+
# Release 进行优化,提高速度 -排除调试信息
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    message(VERBOSE "Maximum optimization for speed")
    add_compile_options(-Ofast)
# RelWithDebInfo 进行优化,提高速度 -包含调试信息
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
    message(VERBOSE "Maximum optimization for speed, debug info included")
    add_compile_options(-Ofast -g)
# MinSizeRel 优化二进制大小 -排除调试信息
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
    message(VERBOSE "Maximum optimization for size")
    add_compile_options(-Os)
# Debug 禁用优化 -包含调试信息
else ()
    message(VERBOSE "Minimal optimization, debug info included")
    add_compile_options(-Og -g)
endif ()


# 初始化SDK
pico_sdk_init()

#添加头文件路径,即.h文件
include_directories(
                    ./USER/Inc
                    )

file(GLOB_RECURSE SOURCES
     ./USER/Src/*.c
    )

add_link_options(-Wl,--print-memory-usage -Wl,--gc-sections -flto)

# 添加可执行文件
add_executable(${PROJECT_NAME} ${SOURCES})

# 设置工程信息
pico_set_program_name(${PROJECT_NAME} "${PROJECT_NAME}")
pico_set_program_version(${PROJECT_NAME} "0.1")

# 默认打开串口
pico_enable_stdio_uart(${PROJECT_NAME} 0)# 是否使能串口0作为标准输出
pico_enable_stdio_usb(${PROJECT_NAME} 1)# 是否使能USB CDC(使能-------→则关闭内建的USB-CDC支持:提供一个USB虚拟的串口以及JTAG调试器)

# 添加链接标准库
target_link_libraries(${PROJECT_NAME} pico_stdlib)

# Print executable size
add_custom_command(TARGET "${PROJECT_NAME}" POST_BUILD
        # COMMENT "Invoking: Cross ARM GNU Print Size"
        COMMAND ${CMAKE_SIZE} ${PROJECT_NAME}.elf
        )

# 除 ELF 文件外, 生成 map/bin/hex/uf2 文件
pico_add_extra_outputs(${PROJECT_NAME})

.vscode目录的launch.json参考下载的pico-examples例程包,路径如下:\pico-examples\pico-examples\ide\vscode
在这里插入图片描述
下载可能遇到的问题:
cmsis-dap-link方式下载
用的下载器不支持rp2040该款MCU,笔者一开始用的下图这款的PWLINK2 Lite,询问技术人员发现不支持rp2040。
在这里插入图片描述

后面笔者换到了下图这款WCH沁恒的WCH-LinkE,这款适用于带有SWD/JTAG接口的ARM芯片在线调试和下载,而rp2040为双核 Arm Cortex-M0 +的MCU。
在这里插入图片描述

②修改openocd烧录的目标文件rp2040.cfg
参考这篇文章:合宙RP2040开发板在Windows上使用C++技术栈的调试