3、开发环境搭建:Keil/IAR/STM32CubeIDE安装与配置、交叉编译工具链、调试器(J-Link/ST-Link)连接、第一个点灯程序验证。

好,咱们正式开始动手了。

这一章,说白了就是“把家伙事儿备齐”。你想想看,一个木匠开工前得先把锯子、刨子磨利索。咱们搞嵌入式Bootloader也一样,开发环境没搭好,后面全是扯淡。

我个人习惯,不管用什么IDE,第一件事就是先把点灯程序跑通。灯亮了,说明你的工具链、调试器、芯片之间这条路是通的。这一步走稳了,后面写Bootloader才有底气。

3.1 IDE的选择与安装:Keil、IAR、STM32CubeIDE

市面上主流的IDE就这三家。我分别说说我的看法。

3.1.1 Keil MDK(μVision)

这玩意儿在ARM Cortex-M生态里,占有率最高。很多老工程师从51单片机时代就用它,界面虽然复古,但胜在稳定。

  • 优点:编译速度快,对ARM内核优化好,调试体验流畅。很多芯片厂商(比如NXP、ST)的官方例程直接就是Keil工程。
  • 缺点:代码大小有限制(32KB免费版),商用需要买License。而且它对GCC支持不太好,基本只能用ARMCC编译器。
  • 安装注意:安装路径不要有中文!不要有空格!我见过有人装在“Program Files (x86)”里,结果某些老版本插件死活认不到路径。

3.1.2 IAR Embedded Workbench

IAR的编译器优化能力是出了名的强。同样的代码,IAR编译出来的体积往往比Keil小10%-15%。

  • 优点:代码密度高,适合Flash紧张的芯片。它的调试器支持也做得很好,尤其是断点管理。
  • 缺点:界面操作逻辑跟Keil不太一样,新手会觉得别扭。而且它的License更贵。
  • 个人经验:我在做一款低功耗蓝牙项目时,Flash只剩2KB了,Keil怎么优化都塞不下。换成IAR,调整了一下优化等级,居然刚好够用。从那以后,我对IAR的编译器就高看一眼。

3.1.3 STM32CubeIDE

这是ST官方基于Eclipse和GCC打造的免费IDE。最大的优势是——免费且开源。

  • 优点:集成了STM32CubeMX,可以图形化配置时钟、外设,直接生成初始化代码。对于新手来说,非常友好。
  • 缺点:Eclipse的底子,启动慢,偶尔会卡顿。而且GCC编译出来的代码,在某些极端情况下,效率不如ARMCC。
  • 避坑指南:我曾经在STM32CubeIDE里打开一个稍大的工程,结果Eclipse直接报内存溢出。后来我把JVM的堆内存调大了(在eclipse.ini里改-Xmx1024m),才解决问题。

我的建议:如果你是初学者,或者主要用STM32,直接用STM32CubeIDE。如果你在公司做产品,且团队都用Keil,那就随大流。如果你追求极致的代码密度,试试IAR。

3.2 交叉编译工具链

什么是交叉编译?说白了,就是你在电脑(x86架构)上写代码,编译出来的程序是给ARM芯片跑的。这个“翻译官”就是交叉编译工具链。

如果你用Keil或IAR,它们自带编译器,你不需要额外安装。但如果你用STM32CubeIDE,它用的是GCC工具链。

常用的ARM GCC工具链有两个版本:

  • arm-none-eabi-gcc:用于裸机或RTOS开发,不支持Linux。
  • arm-linux-gnueabihf-gcc:用于带Linux系统的ARM芯片。

咱们做Bootloader,用的是前者。安装很简单,去ARM官网下载,解压,然后把bin目录加到系统环境变量里就行。

验证方法:打开命令行,输入 arm-none-eabi-gcc --version,如果能看到版本号,说明安装成功。

3.3 调试器连接:J-Link与ST-Link

调试器就是你的“眼睛”。没有它,你只能靠猜。

3.3.1 ST-Link

ST-Link是ST官方调试器,买STM32开发板(比如Nucleo、Discovery系列)时,板上就集成了。它支持SWD和JTAG两种接口。

  • 连接方式:SWD只需要4根线——VCC、GND、SWDIO、SWCLK。JTAG需要5根线。
  • 驱动问题:Windows 10/11通常能自动识别。如果识别不了,去ST官网下载“ST-Link USB driver”。
  • 个人经验:我遇到过ST-Link固件版本太旧,导致连接不上的情况。解决办法是下载“STM32CubeProgrammer”,用它来更新ST-Link的固件。

3.3.2 J-Link

J-Link是SEGGER公司的产品,性能比ST-Link强,调试速度快,支持芯片种类多。但价格也贵。

  • 连接方式:同样用SWD接口。J-Link的SWD接口定义是:1脚VCC、2脚SWDIO、3脚GND、4脚SWCLK、5脚GND(有的版本不同,建议看丝印)。
  • 驱动安装:去SEGGER官网下载“J-Link Software and Documentation Pack”,安装后会自动装驱动。
  • 避坑指南:我曾经用一根劣质杜邦线连接J-Link和板子,结果SWD信号衰减严重,调试器频繁断开。后来换了屏蔽线,问题解决。记住,调试线越短越好,最好不超过20cm。

重要提醒:连接调试器时,一定要先确认板子的供电电压。J-Link默认输出3.3V,如果你的板子是1.8V供电,直接接上去可能会烧芯片。解决办法是:只接SWDIO、SWCLK、GND三根线,VCC不接,让板子自己供电。

3.4 第一个点灯程序验证

好了,环境搭好了,调试器也连上了。咱们来写个点灯程序,验证一下整个链路是否通畅。

以STM32F103C8T6为例,LED通常接在PC13引脚(高电平熄灭,低电平点亮)。

3.4.1 代码示例

#include "stm32f10x.h"

void delay(uint32_t count) {
    while(count--) {
        __NOP(); // 空操作,防止被优化掉
    }
}

int main(void) {
    // 使能GPIOC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    // 配置PC13为推挽输出,50MHz
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    while(1) {
        GPIO_ResetBits(GPIOC, GPIO_Pin_13); // 点亮LED
        delay(1000000);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);   // 熄灭LED
        delay(1000000);
    }
}

3.4.2 编译与下载

  1. 在IDE里新建工程,选择芯片型号(STM32F103C8)。
  2. 把上面的代码复制进去,编译。如果报错,检查一下头文件路径是否包含对了。
  3. 连接调试器,点击“Download”或“Flash”按钮。
  4. 如果一切顺利,你会看到板子上的LED开始闪烁。

如果灯不亮,别慌。按这个顺序排查:

  • 检查调试器连接:IDE里能不能识别到芯片?
  • 检查供电:板子上的电源指示灯亮了吗?
  • 检查引脚:LED是不是真的接在PC13上?有些开发板接的是PA1或PB12。
  • 检查代码:时钟使能了吗?GPIO配置对了吗?

3.4.3 调试技巧

灯亮了,说明你的开发环境搭建成功了。但我想多说一句:

点灯程序虽然简单,但它验证了从“编写代码”到“编译”到“下载”到“运行”的完整流程。这个流程通了,后面写Bootloader时,你才能把精力集中在逻辑上,而不是被环境问题卡住。

我记得有一次,我在一个新电脑上装Keil,折腾了半天,点灯程序就是下载不进去。最后发现是调试器的驱动版本不对。从那以后,我每换一台电脑,第一件事就是跑一遍点灯程序,确认环境没问题。

进阶建议:点灯程序跑通后,你可以试试用调试器单步执行,观察GPIO寄存器的变化。这能帮你理解“寄存器”这个概念,对后面写Bootloader很有帮助。

好了,环境搭好了,灯也亮了。下一章,咱们开始真正进入Bootloader的世界——聊聊它的启动流程。