2. 创建基础工程模板
任务说明
本案例面向STM32F103系列MCU,创建一个最小可编译的空工程模板。该模板包含三个必要文件:启动文件(汇编)、链接脚本(分散加载描述)和主函数(C语言入口)。目标是通过arm-none-eabi-gcc工具链编译生成ELF与HEX文件,为后续案例提供统一的工程骨架。
工程文件结构
代码实现
以下四个文件构成完整模板。启动文件定义中断向量表与复位入口;链接脚本指定Flash(64KB)与RAM(20KB)布局;主函数为空循环;Makefile封装编译命令。
// ========== main.c ==========
#include <stdint.h>
int main(void)
{
// 空工程模板:后续案例在此添加外设初始化与业务逻辑
while (1) {
// 主循环
}
}
// ========== startup_stm32f103.s ==========
.syntax unified
.cpu cortex-m3
.thumb
.section .isr_vector
.word _estack // 栈顶地址(由链接脚本提供)
.word Reset_Handler // 复位向量
.section .text
.thumb_func
.global Reset_Handler
Reset_Handler:
ldr r0, =_estack
mov sp, r0 // 设置栈指针
bl main // 跳转主函数
b . // 死循环(main不应返回)
// ========== stm32f103.ld ==========
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (rw) : ORIGIN = 0x20000000, LENGTH = 20K
}
_estack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS
{
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
. = ALIGN(4);
} > FLASH
.data :
{
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
_edata = .;
} > RAM AT> FLASH
.bss :
{
. = ALIGN(4);
_sbss = .;
*(.bss)
*(.bss*)
_ebss = .;
} > RAM
}
// ========== Makefile ==========
CROSS_COMPILE = arm-none-eabi-
CC = $(CROSS_COMPILE)gcc
OBJCOPY = $(CROSS_COMPILE)objcopy
CFLAGS = -mcpu=cortex-m3 -mthumb -nostdlib -ffreestanding -O0
LDFLAGS = -T stm32f103.ld -nostdlib
all: template.elf template.hex
template.elf: main.c startup_stm32f103.s stm32f103.ld
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ main.c startup_stm32f103.s
template.hex: template.elf
$(OBJCOPY) -O ihex $< $@
clean:
rm -f template.elf template.hex
.PHONY: all clean
编译与验证
在装有arm-none-eabi-gcc的Linux环境中,进入template目录执行make。预期生成template.elf与template.hex两个文件。验证判定标准:
make命令无报错退出,退出码为0;- template.elf存在且可通过
arm-none-eabi-size template.elf查看段大小,text段应包含约几十字节的向量表与代码; - template.hex文件首行以
:020000040800F2开头(表示扩展线性地址0x0800),表明链接地址正确。
若需烧录验证,可使用ST-Link配合st-flash write template.hex 0x08000000,但本案例仅要求编译通过,不涉及硬件运行。