找回密码
 立即注册
首页 业界区 安全 通用 ARM Cortex-M 全系列 Makefile 模板

通用 ARM Cortex-M 全系列 Makefile 模板

任俊慧 3 小时前
Makefile 是 Cortex-M 工程的标准化核心。它通过变量抽象自动屏蔽内核与 FPU 差异,集中管控编译链接与固件转换流程,并实现配置解耦与环境统一,支持一键切换调试/量产模式,大幅提升工程的可维护性与移植效率。以下针对模板中关键参数逐行解析:
1. 工程基础配置区(需适配,新增芯片专属配置)
  1. # 项目目标文件名(自定义,如APP/TEST)
  2. TARGET = APP
  3. # 调试模式开关(1=开启调试 0=关闭,量产用0)
  4. DEBUG = 1
  5. # 优化等级(-Og=调试优化 -O2=量产优化 -O0=无优化)
  6. OPT = -Og
  7. # 编译输出目录(统一存放.o/.elf/.hex等,避免源码混乱)
  8. BUILD_DIR = build
  9. # 目标内核(核心!需根据实际修改:cortex-m0/m3/m4/m7/m33)
  10. MCU_CORE = cortex-m7
  11. # 芯片系列/型号宏定义(必改!如STM32F103xE/STM32F407xx/STM32H743xx/STM32L552xx)
  12. CHIP_DEF = STM32H743xx
  13. # 芯片专属宏定义(按需添加,如电源配置、外设使能)
  14. CHIP_SPEC_DEFS = -DUSE_PWR_LDO_SUPPLY  # H7系列电源配置,其他系列可删除/替换
  15. # 链接脚本(必须与芯片/内核匹配,如STM32H743XX_FLASH.ld)
  16. LDSCRIPT = STM32H743XX_FLASH.ld
复制代码
核心说明:

  • MCU_CORE:整个模板的 “内核适配开关”,后续 FPU / 浮点 ABI 等参数基于此自动适配;
  • CHIP_SPEC_DEFS:新增芯片专属宏定义字段,用于存放如-DUSE_PWR_LDO_SUPPLY(H7)、-DUSE_HSE_BYPASS(F1/F4)等仅针对特定芯片的宏,避免通用宏定义混乱。
2. 源文件管理区(通用逻辑,需适配文件路径)
  1. # 自动搜索业务代码目录下所有.c文件(Core/Src为通用目录,可自定义)
  2. CORE_SRC_DIR = Core/Src
  3. CORE_C_SOURCES = $(wildcard $(CORE_SRC_DIR)/*.c)
  4. # 手动列出HAL/驱动库文件(精准控制核心驱动,避免无关文件编译)
  5. # 提示:不同芯片系列的HAL库文件名不同(如stm32f1xx_hal.c / stm32h7xx_hal.c),需对应修改
  6. HAL_C_SOURCES =  \
  7. Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c \
  8. Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c \
  9. Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
  10. # 合并所有C源文件
  11. C_SOURCES = $(CORE_C_SOURCES) $(HAL_C_SOURCES)
  12. # 汇编文件(启动文件,需与芯片型号严格匹配)
  13. # 提示:不同芯片启动文件不同(如startup_stm32f103xe.s / startup_stm32h743xx.s)
  14. ASM_SOURCES =  startup_stm32h743xx.s
复制代码
通用规则:

  • 业务代码(Core/Src)用wildcard自动搜索,新增文件无需修改 Makefile;
  • 驱动库(HAL/LL)需按芯片系列手动匹配文件名(如 F1 对应stm32f1xx_hal.c,H7 对应stm32h7xx_hal.c);
  • 汇编启动文件必须与芯片型号一一对应(如 STM32H743xx 对应startup_stm32h743xx.s),不可混用。
3. 工具链配置区(通用,无需修改)
  1. # ARM交叉编译工具链前缀(全系列Cortex-M通用)
  2. PREFIX = arm-none-eabi-
  3. # 编译器(C/汇编,-x assembler-with-cpp让汇编器支持C预处理)
  4. CC = $(PREFIX)gcc
  5. AS = $(PREFIX)gcc -x assembler-with-cpp
  6. # 格式转换工具(ELF→HEX/BIN,烧录用)
  7. CP = $(PREFIX)objcopy
  8. SZ = $(PREFIX)size  # 查看固件大小(TEXT/DATA/BSS)
  9. HEX = $(CP) -O ihex
  10. BIN = $(CP) -O binary -S
复制代码
核心说明:所有 Cortex-M 内核均使用arm-none-eabi-工具链,无需因内核 / 芯片不同修改。
4. 内核架构参数区(自动适配,核心差异化)
  1. # 核心架构(通用,基于MCU_CORE自动适配)
  2. CPU = -mcpu=$(MCU_CORE)
  3. # FPU配置(浮点单元,不同内核差异核心!自动适配)
  4. # M0/M3:无FPU → 空
  5. # M4:单精度FPU → fpv4-sp-d16
  6. # M7:双精度FPU → fpv5-d16
  7. # M33:单/双精度可选 → fpv5-sp-d16(单精度)/fpv5-d16(双精度)
  8. ifeq ($(MCU_CORE), cortex-m0)
  9. FPU =
  10. else ifeq ($(MCU_CORE), cortex-m3)
  11. FPU =
  12. else ifeq ($(MCU_CORE), cortex-m4)
  13. FPU = -mfpu=fpv4-sp-d16
  14. else ifeq ($(MCU_CORE), cortex-m7)
  15. FPU = -mfpu=fpv5-d16
  16. else ifeq ($(MCU_CORE), cortex-m33)
  17. # M33可选单/双精度,根据实际需求选其一
  18. FPU = -mfpu=fpv5-sp-d16
  19. endif
  20. # 浮点ABI(与FPU配套,自动适配)
  21. # 无FPU内核(M0/M3):空
  22. # 有FPU内核(M4/M7/M33):hard(硬浮点)/softfp(软浮点兼容)
  23. ifeq ($(filter $(MCU_CORE), cortex-m0 cortex-m3), $(MCU_CORE))
  24. FLOAT-ABI =
  25. else
  26. # M33需注意:部分芯片(如STM32L5系列)的M33内核裁剪了FPU,需设为空
  27. FLOAT-ABI = -mfloat-abi=hard
  28. endif
  29. # 汇编宏定义(通用宏 + 芯片专属宏)
  30. AS_DEFS = -D$(CHIP_DEF) $(CHIP_SPEC_DEFS)
  31. # 汇编头文件路径(需匹配芯片系列的HAL库路径)
  32. AS_INCLUDES = -ICore/Inc
  33. # 合并MCU核心参数(通用,所有内核需加-mthumb,Cortex-M专属指令集)
  34. MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
复制代码
不同内核 FPU / 浮点 ABI 配置对照表

内核FPU配置FLOAT-ABI配置硬件特性说明Cortex-M0空空无 FPU,仅支持整数运算Cortex-M3空空无 FPU,Thumb-2 指令集Cortex-M4-mfpu=fpv4-sp-d16-mfloat-abi=hard单精度 FPU,硬浮点加速Cortex-M7-mfpu=fpv5-d16-mfloat-abi=hard双精度 FPU,支持复杂浮点运算Cortex-M33-mfpu=fpv5-sp-d16-mfloat-abi=hard单精度 FPU(可选双精度),带 TrustZone常见芯片专属宏定义对照表(新增)

芯片系列专属宏定义示例作用说明STM32F1-DUSE_HSE_BYPASS启用外部晶振旁路模式STM32F4-DUSE_TIM_CLOCK_DIVIDER_4TIM 时钟分频配置STM32H7-DUSE_PWR_LDO_SUPPLY配置电源为 LDO 模式(H7 专属)STM32L5-DUSE_RTC_LSEDRIVE_LOWRTC 低速晶振驱动能力配置STM32G0-DUSE_FULL_LL_DRIVER启用 LL 库(G0 推荐)关键补充:

  • AS_DEFS 中引入$(CHIP_SPEC_DEFS),将芯片专属宏与通用宏分离,便于维护;
  • M33 需额外注意:部分芯片(如 STM32L5 系列)的 M33 内核裁剪了 FPU,此时需将FPU和FLOAT-ABI设为空;
  • 软浮点(softfp):适用于 “有 FPU 但需兼容无 FPU 代码” 的场景,性能略低于硬浮点(hard)。
5. C 语言编译参数区(通用,适配芯片系列路径 / 宏)
  1. # C宏定义(通用宏 + 芯片专属宏)
  2. C_DEFS =  \
  3. -DUSE_HAL_DRIVER \
  4. -D$(CHIP_DEF) \
  5. $(CHIP_SPEC_DEFS)  # 引入芯片专属宏
  6. # M33额外宏:开启TrustZone(如需)
  7. ifeq ($(MCU_CORE), cortex-m33)
  8. C_DEFS += -DCORE_CM33 -DTZ_ENABLE=1
  9. endif
  10. # C头文件路径(需匹配芯片系列的HAL/CMSIS路径)
  11. # 提示:不同芯片系列的HAL库路径不同(如STM32H7xx_HAL_Driver / STM32F1xx_HAL_Driver)
  12. C_INCLUDES =  \
  13. -ICore/Inc \
  14. -IDrivers/STM32H7xx_HAL_Driver/Inc \
  15. -IDrivers/STM32H7xx_HAL_Driver/Inc/Legacy \
  16. -IDrivers/CMSIS/Device/ST/STM32H7xx/Include \
  17. -IDrivers/CMSIS/Include \
  18. # M33额外路径:TrustZone相关头文件
  19. ifeq ($(MCU_CORE), cortex-m33)
  20. C_INCLUDES += -IDrivers/CMSIS/Include/core_cm33
  21. endif
  22. # 汇编编译标志(通用,无需修改)
  23. ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
  24. # C编译标志(通用,核心参数解析)
  25. CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
  26. # 调试配置(DEBUG=1时生成gdb调试信息,通用)
  27. ifeq ($(DEBUG), 1)
  28. CFLAGS += -g -gdwarf-2
  29. endif
  30. # 自动生成依赖文件(.d),实现增量编译(通用)
  31. CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
复制代码
核心编译参数解析

参数作用-Wall开启所有编译警告,提前发现代码问题(如未定义变量、类型不匹配)-fdata-sections将每个数据项放入独立段,链接时可删除未使用数据,减小固件体积-ffunction-sections将每个函数放入独立段,链接时可删除未使用函数,减小固件体积-g -gdwarf-2生成调试信息,支持 gdb/IDE 调试(量产时关闭)-MMD -MP自动生成.d依赖文件,记录.c 文件依赖的头文件,头文件修改时自动重编$(CHIP_SPEC_DEFS)引入芯片专属宏,适配硬件底层配置(如 H7 的 LDO 电源、F1 的晶振配置)6. 链接配置区(通用,适配芯片专属链接脚本)
  1. # 链接脚本(核心!需与芯片型号严格匹配,不同系列不可混用)
  2. # 示例:STM32F103xE→STM32F103XX_FLASH.ld,STM32H743xx→STM32H743XX_FLASH.ld
  3. LDSCRIPT = STM32H743XX_FLASH.ld
  4. # 链接库(嵌入式通用,newlib-nano精简库)
  5. LIBS = -lc -lm -lnosys
  6. # 链接标志(通用,核心参数解析)
  7. LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
复制代码
核心链接参数解析

参数作用-specs=nano.specs使用 newlib-nano(精简版 C 库),适配嵌入式有限 RAM/FLASH-T$(LDSCRIPT)指定链接脚本,定义 FLASH/RAM 的起始地址、大小(不同芯片存储布局不同)-Wl,--gc-sections删除未使用的代码 / 数据段,大幅减小固件体积(需配合 -fdata-sections)-Map=xxx.map生成映射文件,查看函数 / 数据的存储地址,便于调试 / 内存优化7. 编译规则区(通用,无需修改)

[code]# 默认目标:编译生成ELF/HEX/BINall: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin# 创建输出目录(不存在时自动创建,-p避免已存在时报错)$(BUILD_DIR):        @mkdir -p $@# 生成目标文件列表(.o文件)OBJECTS = $(addprefix $(BUILD_DIR)/, $(notdir $(C_SOURCES:.c=.o)))vpath %.c $(sort $(dir $(C_SOURCES)))  # 告诉make去哪里找.c文件OBJECTS += $(addprefix $(BUILD_DIR)/, $(notdir $(ASM_SOURCES:.s=.o)))vpath %.s $(sort $(dir $(ASM_SOURCES)))  # 告诉make去哪里找.s文件# C文件编译规则:.c → .o$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)         $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(

相关推荐

您需要登录后才可以回帖 登录 | 立即注册