本文已参与「新人创作礼」活动,一起开启掘金创作之路。
移植micropython最小工程到mm32f3270微控制器(3)-为新移植创建Makefile
为新移植创建Makefile
以SAMD移植项目下的Makefile作为模板, 改写.
最重要的事情写在前面, 不要手贱把TAB键换成4个空格, Makefile会报错! 我因为这事郁闷了一个晚上, 能想到改回来真tmd是天意.
- 改板子的名字
BOARD ?= MB_F3270
BOARD_DIR ?= boards/$(BOARD)
BUILD ?= build-$(BOARD)
CROSS_COMPILE ?= arm-none-eabi-
# UF2CONV ?= $(TOP)/tools/uf2conv.py
ifeq ($(wildcard $(BOARD_DIR)/.),)
$(error Invalid BOARD specified: $(BOARD_DIR))
endif
- 添加芯片相关源文件的路径引用
MCU_DIR = lib/mm32/$(MCU_SERIES)
Makefile后面好像没有直接指定相对路径的, 总是在前面要加个$(xxx), 我之前曾经试过类似如下的写法, 但总是觉得有点怪怪的, 同时考虑到这个路径可能会在个地方用到, 定义个变量复用字符串也不错.
INC += -Iboards/MB_F3270
这就是最终写的看起来不错并验证正确的做法.
INC += -I$(BOARD_DIR)
另外, 在设定路径的时候, 有时是以micropython的根目录作为相对路径, 有时又以具体移植项目根目录作为相对路径的. 瑞祥随俗吧. 实际上, 这也是micropython的makefile搞得鬼, make会把编号的obj文件放到另外创建的目录中, 这个目录已经不是原始代码所在目录了, 所以后来还导致了用ozone调试elf时看不到同源代码的映射.
- 增加源文件搜索路径
# includepath.
INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
INC += -I$(BOARD_DIR)
INC += -I$(TOP)/lib/cmsis/inc
# INC += -I$(TOP)/lib/asf4/$(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]')/include
INC += -I$(TOP)/$(MCU_DIR)/devices/$(CMSIS_MCU)
INC += -I$(TOP)/$(MCU_DIR)/drivers
# INC += -I$(TOP)/lib/tinyusb/src
- CFLAGS
这是SAMD移植中最良心的地方了. 我一直很头大armgcc编译器的CFLAGS, 这个不像keil或者iar提供可视化的选项, 没有典型配置可以使用, 文档解释又简单难懂. 但是SAMD的makefile同时提供了CM0P和CM4F的FLAGS组合, 我对照着改了一个CM3的版本, 竟然通了, 不可抑制地庆幸, 开心!
# flags.
CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU_$(MCU_SERIES)) -fsingle-precision-constant -Wdouble-promotion
CFLAGS_MCU_CM3 = -mtune=cortex-m3 -mcpu=cortex-m3 -msoft-float
CFLAGS_MCU_CM0P = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float
ifeq ($(MCU_SERIES), mm32f3270)
CFLAGS += $(CFLAGS_MCU_CM3)
else
CFLAGS += $(CFLAGS_MCU_CM0P)
endif
CFLAGS += -DMCU_$(MCU_SERIES) -D__$(CMSIS_MCU)__
LDFLAGS = -nostdlib $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref
LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
# Tune for Debugging or Optimization
ifeq ($(DEBUG),1)
CFLAGS += -O0 -ggdb
else
CFLAGS += -Os -DNDEBUG
LDFLAGS += --gc-sections
CFLAGS += -fdata-sections -ffunction-sections
endif
从后面的代码可以看到, micropython可能天然就支持CM3吧, 即使CM4F和CM7F, 甚至是我曾经移植成功过的CM33, 使用的都是gchelper_m3.s文件.
# also use cm3 as gchelper_m3.s
ifeq ($(MCU_SERIES),mm32f3270)
SRC_S = lib/utils/gchelper_m3.s
else
SRC_S = lib/utils/gchelper_m0.s
endif
- 加源文件
略.
- QSTR扫描文件清单
micropython的make在启动编译之前, 会用python脚本扫描源代码, 提取其中的关键字, 生成专门包含关键字的头文件.
后续添加模块是, 必然包含了micropython需要调用的关键字, 一定要在这里加上对应的源文件.
# List of sources for qstr extraction
SRC_QSTR += modmachine.c
- 编译OBJ文件输出路径及规则
这里特别加了大写S后缀的汇编文件的规则, 用了"SRC_SS", 专门为了兼容xxxxx_startup.S文件. 我在早期移植KE18F的时候, 曾经使用过用c代码内嵌汇编的方式, 把S文件改写成c文件, 这样就可以省却此处的麻烦了. 后面抽空可以试试再改一次.
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o))
- 创建规则
真是良心啊, 不仅仅可以生成elf文件, 把bin和hex的脚本也写好了.
all: $(BUILD)/firmware.bin
$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $@"
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
$(Q)$(SIZE) $@
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(Q)$(OBJCOPY) -O binary $^ $@
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
$(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@
- 包含其它mk文件
文件结尾的
include $(TOP)/py/mkrules.mk
和文件开始的
include ../../py/mkenv.mk
include $(BOARD_DIR)/mpconfigboard.mk
就这么放着吧, 别乱动.
附件
详细源码见gitee上的开源代码仓库:gitee.com/suyong_yq/m… 其中mm32f3移植项目基于本文创建,但后续经不断迭代至今(2022-07-30)
(完结)