VSCode+arm-none-eabi-gcc交叉编译+CMake构建+OpenOCD(基于Raspberry Pico RP2040)
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++技术栈的调试