1. 项目概述:为什么选择GD32F103CBT6与VSCode

如果你和我一样,是从STM32转过来接触国产MCU的,那么兆易创新的GD32F103系列绝对是你绕不开的一个选择。我手头这块GD32F103CBT6,从引脚到外设,几乎和STM32F103C8T6是“Pin to Pin”兼容的,这意味着你之前为STM32设计的电路板,大概率可以直接焊上GD32就能跑,迁移成本极低。但内核和性能上,它又有些不同,GD32用的是Cortex-M3内核,主频能跑到108MHz,比同级别的STM32F103要快,片上Flash有128KB,SRAM有20KB,对于大多数中等复杂度的控制应用来说,这个资源是相当充裕的。

那么,为什么我要折腾在VSCode里配置它的开发环境呢?原因很简单:自由、轻量和强大。传统的Keil MDK或者IAR固然稳定,但它们是商业软件,有版权和成本的顾虑,而且界面和编辑体验对于现代开发者来说,确实有些“复古”了。VSCode作为一个免费的、高度可定制的代码编辑器,配合强大的插件生态,可以打造出一个集代码编辑、智能提示、编译、调试于一体的高效开发环境。这对于个人开发者、学生或者追求极致效率的团队来说,吸引力巨大。这个配置过程,本质上就是把GCC交叉编译工具链、OpenOCD调试器以及GD32的芯片支持包,整合到VSCode这个“外壳”里,让我们能用更现代的方式,去驾驭这颗国产的“芯”。

2. 环境搭建前的核心准备与工具选型

在真正打开VSCode之前,我们需要把“地基”打好。这个地基由几个关键部件构成,选对工具,后续的配置会事半功倍。

2.1 工具链三件套:编译器、调试器与芯片支持

首先是最核心的 ARM交叉编译工具链 。我们开发的是ARM Cortex-M架构的MCU,需要在x86的电脑上生成ARM指令集的机器码,所以必须使用交叉编译器。这里我强烈推荐使用 arm-none-eabi-gcc 。你可以从ARM官方或GNU MCU Eclipse等镜像站点下载预编译好的版本。选择版本时,不必追求最新,选择一个较新且稳定的版本即可,比如10.x或11.x系列。将其解压到一个没有中文和空格的路径下,例如 C:\GNU_Tools_ARM_Embedded ,并记得将它的 bin 目录(比如 C:\GNU_Tools_ARM_Embedded\bin )添加到系统的环境变量 PATH 中。这是后续一切编译命令能够执行的前提。

其次是 调试与烧录工具 。我们常用的ST-Link、J-Link、DAP-Link等调试器,都需要一个软件来驱动它们与GD32芯片通信,这个软件就是 OpenOCD 。OpenOCD是一个开源的片上调试器,它支持众多的调试探头和芯片目标。我们需要下载一个已经包含GD32芯片支持的OpenOCD版本。兆易创新官方有时会提供定制版,你也可以使用社区维护的版本。和工具链一样,解压并配置好环境变量。

最后是 芯片支持包与SDK 。这是让编译器认识GD32F103CBT6的关键。你需要从兆易创新官网下载GD32F10x系列的 设备支持包 固件库 。设备支持包包含芯片的链接脚本、启动文件、系统初始化代码等;固件库则提供了所有外设(GPIO、USART、TIMER等)的驱动函数。官方的GigaDevice.GD32F10x_DFP.x.x.x.pack(用于Keil)不一定直接适用于GCC,但我们可以提取其中的核心文件,或者直接使用社区移植好的GCC版SDK,这会省去大量移植工作。

2.2 VSCode本体与必备插件安装

VSCode本身直接从官网下载安装即可。安装完成后,我们需要安装几个核心插件来武装它:

  1. C/C++ :微软官方出品,提供代码智能感知、跳转、错误提示等核心功能。
  2. Cortex-Debug :这是调试Cortex-M芯片的神器。它提供了图形化的寄存器、内存、外设查看界面,以及调试控制台。
  3. Chinese (Simplified) Language Pack :如果需要中文界面,可以安装这个语言包。

安装完插件后,建议进行一些基础设置。打开VSCode的设置( Ctrl+, ),搜索“C_Cpp: Default: Intelli Sense Mode”,将其设置为 gcc-arm 。这能帮助C/C++插件更好地理解我们的交叉编译环境。

注意 :所有工具的安装路径务必避免包含中文和空格。这是很多“诡异”问题的根源,比如编译失败、找不到文件等。一个纯英文、无空格的路径(如 C:\GD32_Dev_Tools )是最安全的选择。

3. 项目工程结构的深度解析与创建

一个清晰、标准的工程结构,是项目可维护性的基石。我们不能把所有的 .c .h 文件都堆在根目录下。下面是我为一个典型GD32项目推荐的结构,你可以以此为模板。

Your_GD32_Project/
├── .vscode/               # VSCode专属配置目录
│   ├── c_cpp_properties.json # C/C++智能感知配置
│   ├── launch.json        # 调试配置
│   └── tasks.json         # 构建任务配置
├── build/                 # 编译输出目录(可被.gitignore忽略)
├── gd32_lib/             # 芯片相关的库文件
│   ├── CMSIS/            # Cortex-M微控制器软件接口标准
│   │   ├── Core/         # M3内核相关文件
│   │   ├── Device/       # GD32设备特定头文件和启动文件
│   │   └── gd32f10x.h    # 芯片总头文件
│   ├── Firmware/         # GD32固件库
│   │   ├── GD32F10x_standard_peripheral/
│   │   │   ├── Include/  # 外设驱动头文件
│   │   │   └── Source/   # 外设驱动源文件
│   │   └── system_gd32f10x.c/.h # 系统时钟配置
│   └── Startup/          # 启动文件
│       └── gd32f10x.s    # GCC汇编启动文件(关键!)
├── user/                 # 用户应用代码
│   ├── inc/              # 用户头文件
│   ├── src/              # 用户源文件
│   └── main.c            # 主函数入口
├── drivers/              # 项目级外设驱动(如OLED、传感器)
├── middleware/           # 中间件(如FreeRTOS、文件系统)
├── tools/                # 脚本或其他工具
├── Makefile              # 主Makefile
└── README.md

关键文件解读

  • gd32f10x.s :这是GCC编译环境下的汇编启动文件。它负责初始化堆栈指针、调用 SystemInit 函数设置时钟、然后跳转到 main 函数。这个文件通常需要从GD32的GCC示例工程或社区资源中获取,Keil用的 .s 文件格式可能不兼容。
  • system_gd32f10x.c :包含 SystemInit 函数,用于配置系统时钟(比如将内部RC振荡器倍频到108MHz)。你需要根据板载晶振修改这里的 HSE_VALUE 宏定义。
  • 链接脚本( .ld 文件) :它告诉链接器如何把代码、数据分配到芯片的Flash和RAM中。对于GD32F103CBT6,你需要一个定义Flash为128K、RAM为20K的链接脚本。这个文件通常也包含在设备支持包中,名为 GD32F10x_Flash.ld

创建好这个结构后,将下载的SDK中的对应文件,分别拷贝到 gd32_lib 下的相应目录。这一步需要耐心和仔细,确保文件路径正确。

4. VSCode核心配置文件的逐行详解

VSCode通过 .vscode 文件夹下的三个JSON文件来驱动整个开发流程。它们是配置的核心。

4.1 c_cpp_properties.json —— 智能感知的引擎

这个文件告诉C/C++插件去哪里找头文件,使用哪种编译器定义,从而提供准确的代码补全和错误检查。

{
    "configurations": [
        {
            "name": "GD32 ARM",
            "includePath": [
                "${workspaceFolder}/**", // 包含工作区所有文件
                "${workspaceFolder}/gd32_lib/CMSIS/Device",
                "${workspaceFolder}/gd32_lib/CMSIS/Core",
                "${workspaceFolder}/gd32_lib/Firmware/GD32F10x_standard_peripheral/Include",
                "${workspaceFolder}/user/inc"
            ],
            "defines": [
                "GD32F10X_MD", // 定义芯片为中密度型号(与CBT6对应)
                "USE_STDPERIPH_DRIVER" // 使用标准外设库
            ],
            "compilerPath": "C:/GNU_Tools_ARM_Embedded/bin/arm-none-eabi-gcc.exe", // 你的工具链路径
            "cStandard": "c11",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "gcc-arm"
        }
    ],
    "version": 4
}
  • includePath :这里列出了所有头文件所在的目录。插件会扫描这些路径,这样你在代码里写 #include “gd32f10x_gpio.h” 时,它才能找到并理解这个文件。
  • defines :全局宏定义。 GD32F10X_MD 至关重要,它决定了芯片型号相关的代码编译分支。 USE_STDPERIPH_DRIVER 告诉固件库我们要使用标准外设驱动。
  • compilerPath :必须正确指向你的 arm-none-eabi-gcc.exe 。设置好后,VSCode会用这个编译器来检查语法和计算智能感知,效果最准确。

4.2 tasks.json —— 构建自动化流水线

这个文件定义了如何编译和链接你的项目,也就是替代你在命令行里手动输入一长串 gcc 命令。

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build GD32 Project",
            "type": "shell",
            "command": "make", // 调用Makefile
            "args": ["-j4"], // 使用4个线程并行编译,加快速度
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": ["$gcc"], // 用GCC模式捕捉编译错误,并能在问题面板点击跳转
            "detail": "使用Makefile构建整个项目"
        },
        {
            "label": "Clean Build",
            "type": "shell",
            "command": "make",
            "args": ["clean"],
            "group": "build",
            "problemMatcher": []
        }
    ]
}

这里我使用了 make 命令,这意味着你还需要在项目根目录编写一个 Makefile Makefile 定义了源文件列表、编译选项、链接规则等。使用 Makefile 的好处是规则清晰,且跨平台(在Linux下也能用)。当然,你也可以直接在 tasks.json command 里写完整的 arm-none-eabi-gcc 编译命令,但对于稍大的项目,这很快就会变得难以管理。

一个极简的 Makefile 核心部分示例如下:

# 工具链定义
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size

# 编译选项
CFLAGS = -mcpu=cortex-m3 -mthumb -specs=nano.specs -specs=nosys.specs
CFLAGS += -DGD32F10X_MD -DUSE_STDPERIPH_DRIVER
CFLAGS += -Og -g -Wall -fdata-sections -ffunction-sections
# 包含头文件路径
CFLAGS += -I../gd32_lib/CMSIS/Device -I../gd32_lib/CMSIS/Core -I../gd32_lib/Firmware/.../Include -Iuser/inc

# 链接选项
LDFLAGS = -mcpu=cortex-m3 -mthumb -specs=nano.specs -specs=nosys.specs
LDFLAGS += -T”GD32F10x_Flash.ld” -Wl,–gc-sections -static
LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map

# 源文件
SRCS = user/src/main.c \
       gd32_lib/Startup/gd32f10x.s \
       gd32_lib/Firmware/system_gd32f10x.c \
       # ... 添加其他外设库文件

# 构建目标
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin

$(BUILD_DIR)/$(TARGET).elf: $(OBJS)
	@$(CC) $(OBJS) $(LDFLAGS) -o $@
	@$(SZ) $@

%.hex: %.elf
	@$(CP) -O ihex $< $@

%.bin: %.elf
	@$(CP) -O binary -S $< $@

配置好 tasks.json Makefile 后,按 Ctrl+Shift+B 就可以直接执行默认的构建任务,在终端看到编译输出,并在 build/ 目录下生成 .elf .hex .bin 等文件。

4.3 launch.json —— 一体化调试配置

这是连接VSCode和硬件调试器的桥梁,配置好后可以实现一键下载、调试。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Cortex Debug (OpenOCD)",
            "cwd": "${workspaceRoot}",
            "executable": "${workspaceFolder}/build/your_project.elf", // 指向编译生成的elf文件
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "serverpath": "C:/OpenOCD/bin/openocd.exe", // 你的OpenOCD路径
            "configFiles": [
                "interface/stlink-v2.cfg", // 调试器接口配置,根据你的调试器修改
                "target/gd32f1x.cfg"       // 目标芯片配置
            ],
            "armToolchainPath": "C:/GNU_Tools_ARM_Embedded/bin", // 工具链路径
            "preLaunchTask": "Build GD32 Project", // 调试前自动构建
            "svdPath": "${workspaceFolder}/gd32_lib/CMSIS/Device/GD/GD32F10x/gd32f10x.svd" // SVD文件路径
        }
    ]
}
  • servertype configFiles :这是关键。 servertype 指定我们使用OpenOCD作为调试服务器。 configFiles 指定了两个配置文件:第一个是调试器接口(我用的ST-Link V2,所以是 stlink-v2.cfg ,如果是DAP-Link则用 cmsis-dap.cfg ),第二个是目标芯片配置文件。你需要确保OpenOCD的 scripts 目录下存在这些配置文件,或者提供绝对路径。
  • executable :必须指向你项目编译出的 .elf 文件,它包含调试信息。
  • preLaunchTask :设置为之前定义的构建任务名( ”Build GD32 Project” ),这样每次启动调试前,都会自动重新编译,确保调试的是最新代码。
  • svdPath 强烈建议配置 。SVD文件是芯片外设寄存器的XML描述文件。配置后,在调试时,Cortex-Debug插件就能解析它,并在VSCode的“外设寄存器”视图中图形化地展示所有外设寄存器,查看和修改寄存器值变得异常方便。这个文件通常可以在GD32的SDK包或Keil的DFP包里找到。

配置完成后,按 F5 即可启动调试。VSCode会自动调用OpenOCD连接板卡、下载程序、复位并停在 main 函数开头。你可以设置断点、单步执行、查看变量和调用栈,体验不输于专业IDE的调试流程。

5. 编译、下载与调试全流程实战

理论配置完毕,现在让我们走一遍完整的流程,看看如何从零开始,点亮一个LED。

5.1 编写第一个测试程序

user/src/main.c 中,我们写一个最简单的程序,让连接在PC13(假设是板载LED)的GPIO口周期性翻转。

#include “gd32f10x.h”
#include “systick.h” // 如果需要使用延时函数,需要实现或包含

void led_init(void) {
    rcu_periph_clock_enable(RCU_GPIOC); // 使能GPIOC时钟
    gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); // 推挽输出,50MHz
    gpio_bit_reset(GPIOC, GPIO_PIN_13); // 初始低电平,LED亮(假设低电平点亮)
}

int main(void) {
    // 系统时钟初始化(在启动文件中已调用SystemInit,通常无需再调)
    // 但如果需要重配时钟,可在此调用相关函数

    led_init(); // 初始化LED GPIO

    while(1) {
        gpio_bit_write(GPIOC, GPIO_PIN_13, (bit_status)(1 - gpio_input_bit_get(GPIOC, GPIO_PIN_13))); // 翻转LED状态
        delay_1ms(500); // 延时500ms,需要自己实现systick延时函数
    }
}

5.2 执行构建与问题排查

  1. 打开终端 :在VSCode中按 Ctrl+` 打开集成终端。
  2. 执行构建 :输入 make 命令(或者按 Ctrl+Shift+B )。终端会开始编译。
  3. 解读输出
    • 成功 :最后会看到 arm-none-eabi-objcopy 生成hex和bin文件,并且 arm-none-eabi-size 会显示程序占用的Flash和RAM大小,例如:
      text    data     bss     dec     hex filename
      1234      56     200    1490     5d2 your_project.elf
      
      这表示代码段( text )1234字节,已初始化数据( data )56字节,未初始化数据( bss )200字节。
    • 失败 :最常见的错误是“找不到头文件”或“未定义的引用”。
      • 找不到头文件 :检查 c_cpp_properties.json 中的 includePath 是否完整、路径是否正确。可以在终端手动运行 arm-none-eabi-gcc -I… -c main.c 测试。
      • 未定义的引用 :通常是链接错误,比如找不到 SystemInit _start 。这很可能是启动文件 gd32f10x.s 没有正确加入编译,或者链接脚本 .ld 文件指定了错误的入口。检查 Makefile 中的源文件列表( SRCS )和链接脚本路径( -T 参数)。

5.3 连接硬件与下载调试

  1. 硬件连接 :用USB线将GD32开发板(或核心板)的调试接口(SWDIO, SWCLK)与你的ST-Link等调试器连接好,并为板子上电。
  2. 启动调试 :按 F5 。VSCode底部状态栏会变橙,并显示调试控制台。如果一切正常,OpenOCD会输出连接成功的信息,程序会暂停在 main 函数开始处。
  3. 基础调试操作
    • 设置断点 :在代码行号左侧点击,出现红点。
    • 单步执行 :使用调试工具栏的 Step Over (F10) Step Into (F11)
    • 查看变量 :在左侧“运行和调试”视图的“变量”窗口,可以查看局部和全局变量。
    • 查看外设 :如果配置了SVD文件,可以在“外设寄存器”视图看到所有外设的寄存器状态,这对于调试驱动代码极其有用。
  4. 下载程序 :在调试状态下,程序其实已经下载到Flash了。你也可以不进入调试,仅下载。一种方法是在 launch.json 中配置 ”runToMain”: false ,然后按 F5 ,程序会直接运行。另一种更直接的方法是使用OpenOCD命令。在VSCode终端中(确保OpenOCD在运行),可以打开另一个终端使用Telnet连接OpenOCD( telnet localhost 4444 ),然后输入 program your_project.elf verify reset 命令来烧录并复位。

6. 进阶配置与效率提升技巧

基础环境搭好能跑通后,我们可以追求更高效、更舒适的开发体验。

6.1 代码智能感知与格式化优化

  • 使用 compile_commands.json :C/C++插件最准确的智能感知来自于“编译数据库”。我们可以让编译系统(如Makefile)生成这个文件。对于Makefile项目,可以安装 bear 工具,运行 bear – make ,它会生成 compile_commands.json 。然后在 c_cpp_properties.json 中配置 “compileCommands”: “${workspaceFolder}/compile_commands.json” 。这样,插件就能获知每个文件确切的编译参数,提示和跳转将达到“编译级”准确。
  • 代码格式化 :安装 Clang-Format 插件,并在项目根目录放置一个 .clang-format 配置文件。可以按 Alt+Shift+F 格式化当前文件,或配置保存时自动格式化。统一的代码风格能极大提升可读性。

6.2 多工程管理与模板化

当你需要开发多个GD32项目时,每次都从头配置是低效的。

  1. 创建项目模板 :将上面配置好的、可以成功编译调试的“最小工程”保存为一个模板文件夹。
  2. 使用VSCode工作区 :对于相关联的多个项目(例如,一个核心驱动库项目和多个应用项目),可以创建一个 .code-workspace 文件来管理它们,方便同时打开和跳转。
  3. 脚本自动化 :编写一个Python或Shell脚本,用于从模板创建新项目,自动替换项目名、芯片型号等变量。

6.3 版本控制集成

使用Git进行版本控制是专业开发的基本功。在项目根目录初始化Git仓库( git init ),并创建一个合理的 .gitignore 文件,忽略 build/ 目录、 *.elf *.hex *.bin 等编译输出文件,以及VSCode的本地设置 .vscode/ (但可以考虑将 tasks.json , launch.json , c_cpp_properties.json 的通用版本纳入版本控制,个人设置除外)。

7. 常见问题排查与解决方案实录

在实际配置过程中,你几乎一定会遇到下面这些问题。这里是我踩过坑后的经验总结。

7.1 编译链接类问题

  • 问题: undefined reference to _start’ undefined reference to SystemInit’

    • 原因 :链接器找不到程序的入口。 _start 在启动文件里定义, SystemInit system_gd32f10x.c 里定义。
    • 排查
      1. 检查 Makefile SRCS 变量是否包含了启动文件( .s .c )和 system_gd32f10x.c
      2. 检查启动文件内容是否正确,特别是对于GCC,入口符号通常是 Reset_Handler ,它会调用 SystemInit
      3. 检查链接脚本 .ld 文件中的入口点设置: ENTRY(Reset_Handler)
  • 问题:程序大小超出Flash限制,链接失败

    • 原因 :代码或数据太多。
    • 排查
      1. 使用 arm-none-eabi-size 查看各段大小。优化 -Os 可以减小代码体积。
      2. 检查是否链接了不必要的库文件。在 Makefile LDFLAGS 中增加 -Wl,–gc-sections ,并在 CFLAGS 中增加 -ffunction-sections -fdata-sections ,让链接器移除未使用的函数和数据段。
      3. 检查是否将大型数组、常量定义在了错误的段(如默认放在了RAM)。
  • 问题: .s 启动文件编译报错,语法错误

    • 原因 :汇编器语法不兼容。GD32官方提供的启动文件可能是针对ARMCC(Keil)或IAR汇编器的。
    • 解决 :必须找到或自己修改为GCC汇编语法的启动文件。关键区别在于:
      • GCC用 .section 而不是 AREA
      • GCC用 .global .globl 声明全局符号,而不是 EXPORT
      • GCC用 .word 定义字数据。
      • 向量表定义方式也不同。网上有很多STM32的GCC启动文件,可以参考其格式为GD32适配。

7.2 调试下载类问题

  • 问题:OpenOCD连接失败,提示“Error: open failed”或“无法找到ST-Link”

    • 原因 :驱动问题或接口配置错误。
    • 排查
      1. 驱动 :确保ST-Link等调试器的USB驱动已正确安装。在设备管理器中查看是否有未知设备。
      2. 接口配置 :检查 launch.json 中的 configFiles interface/stlink-v2.cfg 是针对ST-Link V2的,如果你是V3,可能需要尝试 stlink.cfg interface/stlink.cfg 。DAP-Link则用 interface/cmsis-dap.cfg
      3. 权限 (Linux/Mac):可能需要将当前用户加入 plugdev 组,或使用 sudo 运行OpenOCD/VSCode(不推荐)。
  • 问题:可以连接芯片,但下载程序时校验失败

    • 原因 :Flash编程算法不匹配或芯片写保护未解除。
    • 排查
      1. 检查OpenOCD的芯片配置文件(如 target/gd32f1x.cfg )中指定的Flash大小和算法是否正确。有时需要手动在配置文件中指定 flash bank … gd32f1x …
      2. 尝试在OpenOCD命令中先执行 flash protect 0 0 last off 解除保护,再下载。
      3. 有些GD32芯片需要特殊的解锁序列,查看芯片参考手册的Flash编程章节。
  • 问题:调试时无法查看外设寄存器,或者SVD加载报错

    • 原因 svdPath 配置错误或SVD文件内容不兼容。
    • 排查
      1. 确认 svdPath 指向的文件确实存在且是有效的XML格式。
      2. GD32的SVD文件可能来自Keil的DFP包,有时需要稍微编辑一下。用文本编辑器打开SVD文件,检查其结构。Cortex-Debug插件对SVD格式有一定要求。
      3. 可以尝试在Github上搜索 “GD32F10x.svd”,社区可能有整理好的版本。

7.3 VSCode编辑器类问题

  • 问题:代码有红色波浪线,提示“无法打开源文件 gd32f10x.h”

    • 原因 :C/C++插件的智能感知找不到头文件。
    • 解决
      1. 检查 c_cpp_properties.json includePath compilerPath
      2. Ctrl+Shift+P ,输入 “C/C++: 重新扫描工作区”,强制插件更新索引。
      3. 如果使用了 compile_commands.json ,确保它已生成且路径配置正确。
  • 问题: Makefile 中定义的宏在编辑器里不被识别

    • 原因 :编辑器的智能感知基于 c_cpp_properties.json ,而编译基于 Makefile ,两者定义可能不一致。
    • 解决 :确保 c_cpp_properties.json 中的 defines 列表与 Makefile 中的 -D 编译选项保持一致。最佳实践是将所有宏定义统一写在一个 config.h 文件中,或者通过 Makefile 生成 compile_commands.json 供编辑器使用。

配置VSCode开发GD32的过程,是一个典型的“磨刀不误砍柴工”。初期会遇到各种工具链、路径、配置文件的挑战,但一旦打通,你将获得一个高度自由、可定制且强大的开发环境。这套环境不仅适用于GD32,经过微调(主要是芯片支持包、链接脚本和调试配置),完全可以迁移到其他ARM Cortex-M芯片平台,成为你嵌入式开发生涯中的一把利器。

更多推荐