☰
STM32-从源码到烧录
2026/10/22 18:44:45 网站建设 项目流程

第一阶段:编写源代码

这是你作为开发者直接参与的阶段。你使用文本编辑器(如 VS Code、CLion)或 IDE(如 Keil、STM32CubeIDE)创建和编写以下两类文件:

  1. 「应用程序代码」:main.c、stm32f1xx_it.c、uart_driver.c等,包含了你的业务逻辑和外设驱动代码。

  2. 「启动文件」:startup_stm32f103xb.s。这是一段汇编代码,是 MCU 上电后执行的「第一条指令」。它的核心任务是:

    • 设置堆栈指针(SP)。

    • 初始化.data段(将 Flash 中的初始值复制到 RAM)。

    • 清零.bss段。

    • 调用SystemInit()函数配置系统时钟。

    • 跳转到main()函数。

  3. 「链接脚本」:STM32F103_FLASH.ld。就是你现在正在学习的这个文件,它定义了芯片的内存布局(Flash 和 RAM 的起始地址、大小),以及各个段(.text、.data、.bss等)在内存中的位置。

    MEMORY命令:定义物理存储区域

    MEMORY { ROM (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* STM32F103的Flash */ RAM (rw) : ORIGIN = 0x20000000, LENGTH = 64K /* STM32F103的SRAM */ }

SECTIONS命令:定义输出段布局

SECTIONS { .段名 : [AT(LMA地址)] { [输入文件列表(输入段名)] [符号赋值] } > 内存区域名 }

链接器在处理各段的放置顺序时,会按照 SECTIONS 命令中段定义的先后顺序进行

「这一阶段产出的是.c、.s、.ld等文本文件」。


第二阶段:编译(Compilation)

这一阶段由「交叉编译器」arm-none-eabi-gcc和arm-none-eabi-g++完成。注意,这里的“交叉”是指编译器运行在 PC(x86 架构)上,但生成的是给 ARM 架构使用的机器码。

编译器会逐个处理每个.c和.s文件,执行以下步骤:

  1. 「预处理」:处理#include、#define、#ifdef等预处理指令,生成一个纯净的、已展开的源代码文件。

  2. 「编译」:将 C/C++ 源代码翻译成「汇编语言」。

  3. 「汇编」:将汇编语言翻译成「机器码」,并打包成「目标文件」(Object File)。

「这一阶段产出的是.o文件」。例如,main.c会生成main.o,stm32f1xx_it.c会生成stm32f1xx_it.o。

「关键点」:此时,每个.o文件内的地址都是相对的(从 0 开始),它们不知道彼此的存在,也不知道最终的 Flash 地址。


第三阶段:链接(Linking)

这一阶段由「链接器」arm-none-eabi-ld完成(通常通过arm-none-eabi-gcc间接调用)。链接器的工作是「将多个.o文件合并成一个可执行文件」,并解析它们之间的符号引用。

链接器会严格按照你提供的「链接脚本(.ld文件)」来执行:

  1. 「合并段」:将所有main.o中的.text段、stm32f1xx_it.o中的.text段等,全部合并到输出文件的一个大的.text段中。.data、.bss等段也同理。

  2. 「分配绝对地址」:根据链接脚本中MEMORY命令的定义,将合并后的.text段分配到 Flash 的起始地址0x08000000,将.data段分配到 RAM 的起始地址0x20000000,并为每个函数和全局变量分配一个「绝对地址」。

  3. 「重定位」:将代码中所有需要跳转或访问的地址,从相对地址修正为刚刚分配的绝对地址。

  4. 「解析符号」:如果一个函数在main.c中被调用,但定义在stm32f1xx_it.c中,链接器会找到它的地址,并填入BL指令中。

「这一阶段产出的是.elf(Executable and Linkable Format)文件」。这个文件包含了完整的机器码、地址信息以及调试信息(如符号表)。

「你的 CMake 命令make或cmake --build完成后,在你指定的构建目录下就能找到这个.elf文件」。


第四阶段:烧录(Flashing/Programming)

这一阶段由「烧录工具」配合「调试器硬件」完成。你使用的「JLink」就是调试器的一种。

  1. 「格式转换」:虽然.elf文件包含所有信息,但很多烧录工具(如 JLink 的JFlash或JLinkExe)可以直接识别.elf。也可以将其转换为更精简的.hex或.bin文件。

  2. 「建立连接」:通过 USB 线连接 PC 和 JLink 调试器,再通过 SWD(Serial Wire Debug)或 JTAG 线连接 JLink 和 STM32 目标板。

  3. 「传输数据」:烧录工具(如JLinkExe或OpenOCD)将.elf文件中的机器码数据,通过 SWD/JTAG 协议,逐字节地写入到 STM32 的 Flash 存储器中。写入的起始地址就是链接脚本中定义的0x08000000。

  4. 「验证」:烧录完成后,工具通常会回读 Flash 中的数据,并与原始文件进行比对,以确保写入正确无误。

「这一阶段的结果是,STM32 芯片的 Flash 中已经存储了你的程序机器码」。


第五阶段:运行(Execution)

  1. 「上电复位」:给 STM32 板子上电或按下复位键。

  2. 「硬件自动加载」:CPU 内核自动从地址0x00000000(映射到 Flash 地址0x08000000)读取栈顶指针(_estack)的值,设置到MSP寄存器。

  3. 「读取复位向量」:CPU 自动从地址0x00000004(映射到 Flash 地址0x08000004)读取复位向量(Reset_Handler)的地址,并跳转到该地址执行。

  4. 「执行启动文件」:Reset_Handler开始执行你之前写的汇编启动代码,完成系统初始化(复制.data、清零.bss、配置时钟等)。

  5. 「跳转到main()」:启动代码最后调用main()函数,你的程序开始正式运行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询