ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32-从源码到烧录

STM32-从源码到烧录 第一阶段编写源代码这是你作为开发者直接参与的阶段。你使用文本编辑器如 VS Code、CLion或 IDE如 Keil、STM32CubeIDE创建和编写以下两类文件「应用程序代码」main.c、stm32f1xx_it.c、uart_driver.c等包含了你的业务逻辑和外设驱动代码。「启动文件」startup_stm32f103xb.s。这是一段汇编代码是 MCU 上电后执行的「第一条指令」。它的核心任务是设置堆栈指针SP。初始化.data段将 Flash 中的初始值复制到 RAM。清零.bss段。调用SystemInit()函数配置系统时钟。跳转到main()函数。「链接脚本」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完成。注意这里的“交叉”是指编译器运行在 PCx86 架构上但生成的是给 ARM 架构使用的机器码。编译器会逐个处理每个.c和.s文件执行以下步骤「预处理」处理#include、#define、#ifdef等预处理指令生成一个纯净的、已展开的源代码文件。「编译」将 C/C 源代码翻译成「汇编语言」。「汇编」将汇编语言翻译成「机器码」并打包成「目标文件」Object File。「这一阶段产出的是.o文件」。例如main.c会生成main.ostm32f1xx_it.c会生成stm32f1xx_it.o。「关键点」此时每个.o文件内的地址都是相对的从 0 开始它们不知道彼此的存在也不知道最终的 Flash 地址。第三阶段链接Linking这一阶段由「链接器」arm-none-eabi-ld完成通常通过arm-none-eabi-gcc间接调用。链接器的工作是「将多个.o文件合并成一个可执行文件」并解析它们之间的符号引用。链接器会严格按照你提供的「链接脚本.ld文件」来执行「合并段」将所有main.o中的.text段、stm32f1xx_it.o中的.text段等全部合并到输出文件的一个大的.text段中。.data、.bss等段也同理。「分配绝对地址」根据链接脚本中MEMORY命令的定义将合并后的.text段分配到 Flash 的起始地址0x08000000将.data段分配到 RAM 的起始地址0x20000000并为每个函数和全局变量分配一个「绝对地址」。「重定位」将代码中所有需要跳转或访问的地址从相对地址修正为刚刚分配的绝对地址。「解析符号」如果一个函数在main.c中被调用但定义在stm32f1xx_it.c中链接器会找到它的地址并填入BL指令中。「这一阶段产出的是.elfExecutable and Linkable Format文件」。这个文件包含了完整的机器码、地址信息以及调试信息如符号表。「你的 CMake 命令make或cmake --build完成后在你指定的构建目录下就能找到这个.elf文件」。第四阶段烧录Flashing/Programming这一阶段由「烧录工具」配合「调试器硬件」完成。你使用的「JLink」就是调试器的一种。「格式转换」虽然.elf文件包含所有信息但很多烧录工具如 JLink 的JFlash或JLinkExe可以直接识别.elf。也可以将其转换为更精简的.hex或.bin文件。「建立连接」通过 USB 线连接 PC 和 JLink 调试器再通过 SWDSerial Wire Debug或 JTAG 线连接 JLink 和 STM32 目标板。「传输数据」烧录工具如JLinkExe或OpenOCD将.elf文件中的机器码数据通过 SWD/JTAG 协议逐字节地写入到 STM32 的 Flash 存储器中。写入的起始地址就是链接脚本中定义的0x08000000。「验证」烧录完成后工具通常会回读 Flash 中的数据并与原始文件进行比对以确保写入正确无误。「这一阶段的结果是STM32 芯片的 Flash 中已经存储了你的程序机器码」。第五阶段运行Execution「上电复位」给 STM32 板子上电或按下复位键。「硬件自动加载」CPU 内核自动从地址0x00000000映射到 Flash 地址0x08000000读取栈顶指针_estack的值设置到MSP寄存器。「读取复位向量」CPU 自动从地址0x00000004映射到 Flash 地址0x08000004读取复位向量Reset_Handler的地址并跳转到该地址执行。「执行启动文件」Reset_Handler开始执行你之前写的汇编启动代码完成系统初始化复制.data、清零.bss、配置时钟等。「跳转到main()」启动代码最后调用main()函数你的程序开始正式运行。
返回列表