【Linux】GCC+Makefile打造正点原子stm32单片机开发环境
2025-10-22 来源:bilibili
arm-none-eabi-gcc+stlink-tool+Makefile
正点原子精英STM32F103ZET6开发板采用V3.5库的头文件
下载固件库:https://www.st.com/content/ccc/resource/technical/software/firmware/48/ab/e5/17/0d/79/43/74/stsw-stm32054.zip/files/stsw-stm32054.zip/jcr:content/translations/en.stsw-stm32054.zip
解压得到STM32F10x_StdPeriph_Lib_V3.5.0
新建文件夹:stm32,stm32/lib,stm32/ware
将下列文件(夹)到使stm32/lib文件夹下
STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/TrueSTUDIO/startup_stm32f10x_hd.s STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/TrueSTUDIO/STM3210E-EVAL/stm32_flash.ld STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.h STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/inc STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src
stm32启动文件:startup_stm32f10x_hd.s
stm32链接文件:stm32_flash.ld
stm32头文件:stm32f10x.h
时钟配置文件:system_stm32f10x.h和system_stm32f10x.c,
内核支持文件:core_cm3.h
中断服务程序文件:stm32f10x_it.h和stm32f10x_it.c
固件库配置头文件:stm32f10x_conf.h
外设驱动库:STM32F10x_StdPeriph_Driver
如果用KEIL MDK环境开发就选择arm文件夹下的启动文件,如果用IAR环境开发就选择iar环境下的启动文件,gcc_ride7适用基于GCC_ride7编译器
truestudio使用的是gcc编译器
makefile详解
TARGET=testCC=arm-none-eabi-gccCP=arm-none-eabi-objcopy
使用适合Arm Cortex-M的交叉编译器arm-none-eabi-gcc
利用arm-none-eabi-objcopy工具可以将elf文件转化为适合于单片机的bin文件和hex文件
PWD=$(shell pwd)
使用shell命令pwd,生成当前文件的绝对路径
把自己写的和正点原子提供的文件都放到ware中
WARE=$(patsubst %,-I $(PWD)/ware/%,$(shell ls $(PWD)/ware))
patsubst:模式字符串替换函数。函数返回被替换过后的字符串
%:表示任意长度的字串
这段代码大致意思就是:在ware文件夹下所有的文件夹路径前面都加上一个-I参数。在后面的CFLAGS变量里用到
把正点原子提供的寄存器版本源码的sys文件夹下的sys和delay文件夹复制ware下
略作修改
#sys.c
##把下列源码换成下下列代码
__aSM void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
void MSR_MSP(u32 addr)
{
__ASM volatile("MSR MSP, r0");
__ASM volatile("BX r14");
}
usart的printf无法在此编译器下使用,网上有很多解决办法,但我没成功。下面是网上的一个解决方案
#usart.c
#if 0
###endif下面写
int _write (int fd, char *pBuffer, int size)
{
for (int i=0;i<size;i++)
{
while((USART1->SR&0X40)==0); //等待上一次串口数据发送完成
USART1->DR=(u8) pBuffer[1]; //写DR,串口1将发送数据
}
return size;
}
还要在链接器参数那里加上-specs=nosys.specs -specs=nano.specs
后面那个加不加编译都会成功,但烧录后printf好像没用
find启动文件
把.s后缀的换成.o
START_SRC=$(shell find . -name startup_stm32f10x_hd.s)START_OBJ=$(START_SRC:%.s=%.o)
find所有的.c文件
C_SRC=$(shell find . -name '*.c')C_OBJ=$(C_SRC:%.c=%.o)
CPUFLAGS=-mthumb -mcpu=cortex-m3INCFLAGS=-I $(PWD)/lib -I $(PWD)/lib/inc $(WARE)CFLAGS=$(CPUFLAGS) $(INCFLAGS) -D STM32F10X_HD -D USE_STDPERIPH_DRIVER -Wall -g -c -o
-mthumb 表明使用的指令集
-mcpu=cortex-m3 表明芯片内核
-I 声明头文件路径
-D 定义宏
-Wall 允许输出所有警告
-g 产生调试信息
-c 编译和汇编但不链接
-o 重命名生成文件
对于STM32F103系列芯片,设置原则如下:
16KB≤FLASH≤32KB 选择:STM32F10X_LD
64KB≤FLASH≤128KB 选择:STM32F10X_MD
256KB≤FLASH≤512KB 选择:STM32F10X_HD
正点原子精英开发板STM32F103ZET6的芯片属于大容量STM32芯片,所以选择STM32F10X_HD
只有用预编译指令预定义了“USE_STDPERIPH_DRIVER”,才会将"stm32f10x_conf.h"包含进“stm32f10x.h”中,从而被"main.c"用到。
官方推荐使用arm-none-eabi-gcc来链接,不建议直接使用arm-none-eabi-ld
LDFLAGS=-T $(PWD)/lib/stm32_flash.ld -Wl,-cref,-u,Reset_Handler -Wl,-Map=$(TARGET).map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -0
-T 指定链接脚本
-Wl,<options> 传<options>到链接器
-Map 生成映射文件 还能减少输出
-Wl,--start-group <options> -Wl,--end-group options为要使用的静态库
-o 重命名生成文件
$(TARGET).hex:$(TARGET).elf $(CP) $^ -Oihex $@$(TARGET).elf:$(START_OBJ) $(C_OBJ) $(CC) $^ $(LDFLAGS) $@$(START_OBJ):$(START_SRC) $(CC) $^ $(CFLAGS) $@$(C_OBJ):%.o:%.c $(CC) $^ $(CFLAGS) $@
抽取全部C_OBJ中.o文件的文件名前缀作为%代表的字符串
$@ 代表目标文件(冒号前)
$^ 代表所有的依赖文件(冒号后)
指定伪目标,避免和文件重名
.PHONY: hex bin clean flash
生成hex文件
hex: $(CP) $(TARGET).elf -Oihex $(TARGET).hex
生成bin文件bin: $(CP) $(TARGET).elf $(TARGET).bin
烧录hex文件,因为博主还没学到地址的具体用处,所以选择hex烧录
flash: st-flash --format ihex write $(TARGET).hex
清除生成文件
clean: rm -f $(shell find . -name '*.o') $(TARGET).*
Makefile
TARGET=testCC=arm-none-eabi-gccCP=arm-none-eabi-objcopyPWD=$(shell pwd)WARE=$(patsubst %,-I $(PWD)/ware/%,$(shell ls $(PWD)/ware))START_SRC=$(shell find . -name startup_stm32f10x_hd.s)START_OBJ=$(START_SRC:%.s=%.o)C_SRC=$(shell find . -name '*.c')C_OBJ=$(C_SRC:%.c=%.o)CPUFLAGS=-mthumb -mcpu=cortex-m3INCFLAGS=-I $(PWD)/lib -I $(PWD)/lib/inc $(WARE)CFLAGS=$(CPUFLAGS) $(INCFLAGS) -D STM32F10X_HD -D USE_STDPERIPH_DRIVER -Wall -g -c -oLDFLAGS=-T $(PWD)/lib/stm32_flash.ld -Wl,-cref,-u,Reset_Handler -Wl,-Map=$(TARGET).map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -0$(TARGET).hex:$(TARGET).elf $(CP) $^ -Oihex $@$(TARGET).elf:$(START_OBJ) $(C_OBJ) $(CC) $^ $(LDFLAGS) $@$(START_OBJ):$(START_SRC) $(CC) $^ $(CFLAGS) $@$(C_OBJ):%.o:%.c $(CC) $^ $(CFLAGS) $@.PHONY: hex bin clean flashhex: $(CP) $(TARGET).elf -Oihex $(TARGET).hexbin: $(CP) $(TARGET).elf $(TARGET).binflash: st-flash --format ihex write $(TARGET).hexclean: rm -f $(shell find . -name '*.o') $(TARGET).*
- SUSE 被曝以 60 亿美元估值寻找新买家
- Linux嵌入式开发必备命令速查表
- 使用JTAG在Zynq UltraScale+ MPSoC上引导嵌入式Linux系统
- Linux 内核将引入缓存感知调度,性能最高提升 44%
- Linux 之父罕见发声:GPLv2 许可仅限软件开源,不管硬件解锁
- AGL 发布 SoDeV 开源方案,加速软件定义汽车落地
- Linux 内核首个涉及 Rust 代码的安全漏洞公开:源于开发者在 unsafe 代码逻辑疏漏
- 基于安路DR1M90 FPSoC的Linux系统全流程开发指南(第四部分)
- 基于迅为iTOP-3568开发板的Linux驱动开发实战:menuconfig图形化配置实验
- 员工代码写不够就解雇!Linux创始人炮轰马斯克太愚蠢
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 蓝牙信道探测技术原理与开发套件实践
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析




