点灯-一个Makefile控制
建立工程:~/stm32/project/1_GPIO_LED
目录树:
.
├── bsp
│ └── LED
│ ├── LED.c
│ ├── LED.h
│ └── LED.o
├── main.c
├── Makefile
└── stlib
├── core_cm3.c
├── core_cm3.h
├── flash.ld
├── inc
│ ├── misc.h
│ ├── stm32f10x_xxx.h
├── src
│ ├── misc.c
│ ├── stm32f10x_xxx.c
├── startup_stm32f10x.S
├── stm32f10x_conf.h
├── stm32f10x.h
├── system_stm32f10x.c
└── system_stm32f10x.h
- 关于main.c
- #include中的路径要明确标出相对路径
- 结尾处要有void _exit(void)函数,否则会编译错误
- 关于stlib目录
- 将peripheral相关.c和.h放入src和inc路径下(其实就是src和inc保留不动全部拷贝),其余的.S启动文件、stm32f10x.h、stm32f10x_conf.h、system_stm32f10x.c、system_stm32f10x.h、flash.ld(连接文件)直接放在stlib路径下,避免不必要的麻烦
-
关于bsp目录
无 -
关于Makefile
- vpath 路径要全,保证找得到所有.c、.h、.S文件
- DEFS 变量用来表示编译时的选项,变量的每一个值以-D开头且不用与宏的名分开。目前初步理解是arm-none-eabi-gcc工具识别cortex-m3芯片型号后,在编译时,会寻找stm32fxxx.h这个最主要的头文件,而本工程中用到的是stm32f10x.h(对应stm32f103zet6芯片),粗看该头文件后发现里边需要设定的条件编译选项有:
USE_STDPERIPH_DRIVER
STM32F10X_HD(10x系列芯片不同类型,stm32103zet6属于HD)
所以 DEFS += -DUSE_STDPERIPH_DRIVER –DSTM32F10X_HD
其实过去用keil编译时,在魔术棒的C/C++中就有设定过这两个参数(后知后觉) - INCS 变量用来包含编译时需要的头文件,以-I开头且不需要与路径名分开
- CFLAGS 编译选项变量指定芯片内核型号 (目前-mthumb还不清楚意思)
- LFLAGS 连接选项变量的值相同
- 在编译启动文件.S时不需要DEFS和INCS变量
- arm-none-eabi-objcopy 工具用来将编译出的.elf文件转换为.bin文件
- OBJS 目标变量用来指定最终目标文件在连接时需要的.o文件
防止遗漏规范为
main.o
startup_xxx.o system_stm32f10x.o
stm32f10x_periph1.o stm32f10x_periph2.o etc.
bsp_periph1.o bsp_periph2.o etc.
Makefile代码:
#LED_FLICK
vpath %.S stlib
vpath %.c stlib stlib/src bsp/LED
vpath %.h stlib stlib/inc bsp/LED
DEFS += -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD
INCS += -Istlib -Istlib/inc -Ihardware/LED
OBJS += main.o
OBJS += startup_stm32f10x.o system_stm32f10x.o
OBJS += stm32f10x_gpio.o stm32f10x_rcc.o
OBJS += LED.o
CFLAGS += -mcpu=cortex-m3 -mthumb -Wall
LFLAGS += -mcpu=cortex-m3 -mthumb
all : led_on.bin
clean :
@rm -f $(OBJS) led_on.bin led_on.elf
led_on.bin : led_on.elf
@arm-none-eabi-objcopy -O binary -S $< $@
led_on.elf : $(OBJS)
@arm-none-eabi-gcc $(LFLAGS) $^ -Tstlib/flash.ld -o $@
@arm-none-eabi-size $@
burn : led_on.bin
@st-flash write $< 0x08000000
%.o:%.S
@arm-none-eabi-gcc $(CFLAGS) -c $< -o $@
%.o:%.c
@arm-none-eabi-gcc $(CFLAGS) $(DEFS) $(INCS) -c $< -o $@
- 仍需改进:
显而易见,目前的Makefile编写还是基于vpath,通过一个Makefile来包含跨级的文件,这样违背了运用make工具的初衷(处理目录树复杂的项目时用层级间的Makefile调用,从而实现系统管理项目的编译),而且这个问题体现在一个现存的bug上:
make clean删除不了 ./bsp/lED 路径下的LED.o
所以仍需进一步改写Makefile文件,实现层级调用