Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
333 lines (267 loc) · 14.6 KB
/
Copy pathMakefile
File metadata and controls
333 lines (267 loc) · 14.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# makefile for AM32 bootloader
QUIET = @
# tools
comma := ,
CC = $(ARM_SDK_PREFIX)gcc
OBJCOPY = $(ARM_SDK_PREFIX)objcopy
ECHO = echo
# common variables
IDENTIFIER := AM32
# Folders
HAL_FOLDER := Mcu
MAIN_INC_DIR := Inc
# Working directories
ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
# include the rules for OS independence
include $(ROOT)/make/tools.mk
# MCU builds, if with _xxK then adds build with given flash size
MCU_BUILDS := E230 F031 F051 F415 F415_128K F421 G071 G071_64K L431 L431_128K G431 V203 L431_CAN F415_CAN G431_CAN A153 SITL_CAN
# we support bootloader comms on a list of possible pins
BOOTLOADER_PINS = PB4 PA2 PA6 PA15 PA0 PB2
# filter out any unsupported MCUs for this host OS
filter_mcus = $(foreach w,$(MCU_NOBUILD),$(eval MCU_BUILDS := $(filter-out $w,$(MCU_BUILDS))))$(MCU_BUILDS)
MCU_BUILDS := $(call filter_mcus)
# extract the MCU from a build type of form MCU_nK
define base_mcu
$(word 1,$(subst _, ,$1))
endef
MCU_TYPES := $(sort $(foreach mcu,$(MCU_BUILDS),$(call base_mcu,$(mcu))))
# custom per-board targets defined in Inc/targets.h, parsed by make/parse_targets.py.
# BOARD_TARGETS entries are "BUILD|TAG|BOARDDEFINE|PIN", e.g.
# G431_CAN|ARKG4|ARK_G431_CAN|PB4. The tag names the build, the pin is the
# board's real bootloader comms pin and is what goes in the amj file
BOARD_TARGETS := $(shell python3 make/parse_targets.py builds)
BOARD_MCUS := $(shell python3 make/parse_targets.py mcus)
# make sure each custom board's per-MCU makefile gets included below
MCU_TYPES := $(sort $(MCU_TYPES) $(BOARD_MCUS))
# Function to include makefile for each MCU type
define INCLUDE_MCU_MAKEFILES
$(foreach MCU_TYPE,$(MCU_TYPES),$(eval include $(call lc,$(MCU_TYPE))makefile.mk))
endef
$(call INCLUDE_MCU_MAKEFILES)
# additional libs
LIBS := -lnosys
# Compiler options
CFLAGS_BASE := -fsingle-precision-constant -fomit-frame-pointer -ffast-math --specs=nosys.specs
CFLAGS_BASE += -I$(MAIN_INC_DIR) -g3 -Os -ffunction-sections -fdata-sections -funsigned-char
CFLAGS_BASE += -flto
CFLAGS_BASE += -Wall -Wextra -Wundef -Werror -Wno-unused-parameter
# force-include per-board config; inert for builds with no board define
CFLAGS_BASE += -include $(MAIN_INC_DIR)/targets.h
CFLAGS_COMMON := $(CFLAGS_BASE)
# Linker options
# -fdata-sections lets --gc-sections drop unused globals (companion to -ffunction-sections).
# -flto enables link-time optimisation (cross-TU inlining + DCE); pass it on both
# the compile and link command lines so the linker gets the IR not raw object code.
LDFLAGS_COMMON := -specs=nano.specs $(LIBS) -Wl,--gc-sections -Wl,--print-memory-usage -flto
# configure some directories that are relative to wherever ROOT_DIR is located
OBJ := obj
BIN_DIR := $(ROOT)/$(OBJ)
# find the SVD files
$(foreach MCU,$(MCU_TYPES),$(eval SVD_$(MCU) := $(wildcard $(HAL_FOLDER_$(MCU))/*.svd)))
# a recipe that fails must not leave its target behind: a hex that failed
# its layout check would otherwise look up to date on the next build
.DELETE_ON_ERROR:
.PHONY : clean all
all : check_tools bootloaders
# Check if tools are installed
check_tools:
ifeq ($(MSYSTEM),UCRT64)
@$(SHELL) -c 'command -v $(CC) >/dev/null 2>&1 || { echo "Error: please install tools first with target arm_sdk_install."; exit 1; }'
else
ifeq ($(OS),Windows_NT)
@if not exist "$(CC).exe" ( \
echo Error: please install tools first with target arm_sdk_install. & exit /B 1 \
)
else
@$(SHELL) -c 'command -v $(CC) >/dev/null 2>&1 || { echo "Error: please install tools first with target arm_sdk_install."; exit 1; }'
endif
endif
clean :
@echo Removing $(OBJ) directory
@$(RM) -rf $(OBJ)
# get bootloader version
BOOTLOADER_VERSION := $(shell $(FGREP) "define BOOTLOADER_VERSION" $(MAIN_INC_DIR)/version.h | $(CUT) -d" " -f3 )
SRC_BL := $(foreach dir,bootloader,$(wildcard $(dir)/*.[cs]))
SRC_BLU := $(foreach dir,bl_update,$(wildcard $(dir)/*.[cs]))
LDSCRIPT_BL := bootloader/ldscript_bl.ld
LDSCRIPT_BL_CAN := bootloader/ldscript_bl_CAN.ld
LDSCRIPT_BLU := bl_update/ldscript_bl.ld
LDSCRIPT_BLU_CAN := bl_update/ldscript_bl_CAN.ld
LDSCRIPT_BLT := bl_update/ldscript_bl_transition.ld
# Function to extract CFLAGS based on target name
get_flash_size = $(if $(filter %K,$(word 2,$(subst _, ,$1))),-DBOARD_FLASH_SIZE=$(subst K,,$(word 2,$(subst _, ,$1))))
# Function to check for _CAN suffix
has_can_suffix = $(findstring _CAN,$1)
# Function to return CFLAGS
define get_cflags
$(call get_flash_size,$1) \
$(if $(call has_can_suffix,$1),-DDRONECAN_SUPPORT=1 -DBOARD_FLASH_SIZE=128,-DDRONECAN_SUPPORT=0)
endef
# get a tag in the form _nK if the build has a _nK suffix
define get_k_tag
$(if $(findstring _,$1),_$(patsubst %_,%,$(word 2,$(subst _, ,$1))))
endef
# bootloader target names for example "make AM32_F421_BOOTLOADER" with optional _nK suffix
define BOOTLOADER_BASENAME
$(IDENTIFIER)_$(call base_mcu,$(1))_BOOTLOADER_$(2)$(call get_k_tag,$(1))
endef
define BOOTLOADER_UPDATE_BASENAME
$(IDENTIFIER)_$(call base_mcu,$(1))_BL_UPDATER_$(2)$(call get_k_tag,$(1))
endef
# a transition updater is one that is flashed by a legacy 4k bootloader
define BOOTLOADER_TRANSITION_BASENAME
$(call BOOTLOADER_UPDATE_BASENAME,$(1),$(2))_FROM4K
endef
# bootloader target names with version for filename
define BOOTLOADER_BASENAME_VER
$(call BOOTLOADER_BASENAME,$(1),$(2))_V$(BOOTLOADER_VERSION)
endef
# bootloader target names with version for filename
define BOOTLOADER_UPDATE_BASENAME_VER
$(call BOOTLOADER_UPDATE_BASENAME,$(1),$(2))_V$(BOOTLOADER_VERSION)
endef
define BOOTLOADER_TRANSITION_BASENAME_VER
$(call BOOTLOADER_TRANSITION_BASENAME,$(1),$(2))_V$(BOOTLOADER_VERSION)
endef
# a transition updater is only built for CAN builds on MCUs where the legacy
# 4k bootloader used the 64k flash layout, so that the updater fits between
# the 16k CAN bootloader and the legacy eeprom
has_transition = $(if $(call has_can_suffix,$1),$(BL_TRANSITION_$(call base_mcu,$1)))
# list of targets formed using CREATE_BOOTLOADER_TARGET
ALL_BUILDS :=
BLU_BUILDS :=
# create a bootloader build target given a build in the form MCU or MCU_nK and a PIN
define CREATE_BOOTLOADER_TARGET
$(eval BUILD := $(1))
$(eval PIN := $(2))
$(eval BOARD := $(3))
# for a board target the build is named by its tag, but the amj file has to
# name the pin the bootloader really listens on
$(eval COMMS_PIN := $(if $(4),$(4),$(2)))
$(eval MCU := $$(call base_mcu,$$(1)))
$(eval EXTRA_CFLAGS := $(call get_cflags,$(1)))
$(eval ELF_FILE := $(BIN_DIR)/$(call BOOTLOADER_BASENAME_VER,$(BUILD),$(PIN)).elf)
$(eval HEX_FILE := $(ELF_FILE:.elf=.hex))
$(eval DEP_FILE := $(ELF_FILE:.elf=.d))
$(eval BIN_FILE := $(ELF_FILE:.elf=.bin))
$(eval MAP_FILE := $(ELF_FILE:.elf=.map))
$(eval H_FILE := $(ELF_FILE:.elf=.h))
$(eval BLU_ELF_FILE := $(BIN_DIR)/$(call BOOTLOADER_UPDATE_BASENAME_VER,$(BUILD),$(PIN)).elf)
$(eval BLU_HEX_FILE := $(BLU_ELF_FILE:.elf=.hex))
$(eval BLU_DEP_FILE := $(BLU_ELF_FILE:.elf=.d))
$(eval BLU_BIN_FILE := $(BLU_ELF_FILE:.elf=.bin))
$(eval BLU_MAP_FILE := $(BLU_ELF_FILE:.elf=.bin))
$(eval BLU_AMJ_FILE := $(BLU_ELF_FILE:.elf=.amj))
$(eval TARGET := $(call BOOTLOADER_BASENAME,$(BUILD),$(PIN)))
$(eval BLU_TARGET := $(call BOOTLOADER_UPDATE_BASENAME,$(BUILD),$(PIN)))
# get MCU specific compiler, objcopy and link script or use the ARM SDK one
$(eval xCC := $(if $($(MCU)_CC), $($(MCU)_CC), $(CC)))
$(eval xOBJCOPY := $(if $($(MCU)_OBJCOPY), $($(MCU)_OBJCOPY), $(OBJCOPY)))
$(eval xLDSCRIPT := $(if $($(MCU)_LDSCRIPT), $($(MCU)_LDSCRIPT), $$(if $$(call has_can_suffix,$$(BUILD)),$(LDSCRIPT_BL_CAN),$(LDSCRIPT_BL))))
$(eval xBLU_LDSCRIPT := $(if $($(MCU)_LDSCRIPT_BLU), $($(MCU)_LDSCRIPT_BLU), $$(if $$(call has_can_suffix,$$(BUILD)),$(LDSCRIPT_BLU_CAN),$(LDSCRIPT_BLU))))
$(eval CFLAGS_DRONECAN := $$(if $$(call has_can_suffix,$$(1)),$$(if $$(CFLAGS_DRONECAN_$(MCU)),$$(CFLAGS_DRONECAN_$(MCU)),$$(CFLAGS_DRONECAN_L431))))
$(eval SRC_DRONECAN := $(if $(call has_can_suffix,$(1)),$(SRC_DRONECAN_$(MCU))))
-include $(DEP_FILE)
-include $(BLU_DEP_FILE)
$(ELF_FILE): CFLAGS_BL := $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(if $$(CFLAGS_BASE_$(MCU)),$$(CFLAGS_BASE_$(MCU)),$$(CFLAGS_BASE)) -DBOOTLOADER -DUSE_$(PIN) $(if $(BOARD),-D$(BOARD)) $(EXTRA_CFLAGS) -DAM32_MCU=\"$(MCU)\" $$(CFLAGS_DRONECAN)
$(ELF_FILE): LDFLAGS_BL := $$(if $$(LDFLAGS_COMMON_$(MCU)),$$(LDFLAGS_COMMON_$(MCU)),$$(LDFLAGS_COMMON)) $$(LDFLAGS_$(MCU)) $(if $(NATIVE_$(MCU)),,-T$(xLDSCRIPT))
$(ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BL) $$(SRC_DRONECAN)
$$(QUIET)echo building bootloader for $(BUILD) with pin $(PIN)
$$(QUIET)$$(MKDIR) -p $(OBJ)
$$(QUIET)echo Compiling $(notdir $$@)
$$(QUIET)$(xCC) $$(CFLAGS_BL) $(CFLAGS_DRONECAN) $$(LDFLAGS_BL) -MMD -MP -MF $(DEP_FILE) -o $$(@) $$(SRC_$(MCU)_BL) $$(SRC_BL) $(SRC_DRONECAN) $(if $(and $(NATIVE_$(MCU)),$(filter Darwin,$(UNAME_S))),-Wl$(comma)-map$(comma)$(MAP_FILE),-Wl$(comma)-Map=$(MAP_FILE))
# debug.elf/svd/openocd.cfg are for on-chip debugging; skip them for the
# native SITL target so obj/debug.elf never becomes a host binary that
# arm-none-eabi-size (run over obj/*.elf in CI) cannot read
$(if $(NATIVE_$(MCU)),, $$(QUIET)$$(CP) -f $$@ $$(OBJ)$$(DSEP)debug.elf
$$(QUIET)$$(CP) -f $$(SVD_$(MCU)) $$(OBJ)/debug.svd
$$(QUIET)$$(CP) -f Mcu$(DSEP)$(call lc,$(MCU))$(DSEP)openocd.cfg $$(OBJ)$$(DSEP)openocd.cfg > $$(NUL))
$(H_FILE): $(BIN_FILE)
$$(QUIET)python3 bl_update/make_binheader.py $(BIN_FILE) $(H_FILE)
$(BLU_ELF_FILE): CFLAGS_BLU := -DAM32_MCU=\"$(MCU)\" $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DBOOTLOADER -DUSE_$(PIN) $(if $(BOARD),-D$(BOARD)) $(EXTRA_CFLAGS) -DBL_TRANSITION=0 -Wno-unused-variable -Wno-unused-function
$(BLU_ELF_FILE): LDFLAGS_BLU := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xBLU_LDSCRIPT)
$(BLU_ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BLU) $(H_FILE)
$$(QUIET)echo building bootloader updater for $(BUILD) with pin $(PIN)
$$(QUIET)$$(MKDIR) -p $(OBJ)
$$(QUIET)echo Compiling $(notdir $$@)
$$(QUIET)$(xCC) $$(CFLAGS_BLU) $$(LDFLAGS_BLU) -MMD -MP -MF $(DEP_FILE) -o $$(@) $$(SRC_$(MCU)_BL) $$(SRC_BLU) -I. -DBL_HEADER_FILE=$(H_FILE) -Wl,-Map=$(BLU_MAP_FILE)
# Generate bin and hex files
$(HEX_FILE): $$(ELF_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)$(xOBJCOPY) -O binary $$(<) $$(@:.hex=.bin)
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@:.bin=.hex)
$(BIN_FILE): $$(HEX_FILE)
# Generate bin and hex files for bl updater
$(BLU_BIN_FILE): $$(BLU_ELF_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)$(xOBJCOPY) -O binary $$(<) $$(@:.hex=.bin)
$$(QUIET)python3 bl_update/set_app_signature.py $$@ $$(<)
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@:.bin=.hex)
$(BLU_AMJ_FILE): $$(BLU_BIN_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)python3 bl_update/make_amj.py --type bl_update --pin $(COMMS_PIN) --githash $(shell git rev-parse HEAD) $(BLU_HEX_FILE) $(BLU_AMJ_FILE)
$(TARGET): $$(if $(NATIVE_$(MCU)),$$(ELF_FILE),$$(HEX_FILE))
$(BLU_TARGET): $$(BLU_AMJ_FILE)
# add to list; native builds have no bl_update variant
ALL_BUILDS := $(ALL_BUILDS) $(TARGET)
BLU_BUILDS := $(BLU_BUILDS) $(if $(NATIVE_$(MCU)),,$(BLU_TARGET))
endef
# create a transition updater build target, which is the same updater firmware
# linked to be flashed by a legacy 4k bootloader over the top of the
# application. It carries no valid app signature, as it is left behind in the
# application area once it has run and must never be booted
define CREATE_TRANSITION_TARGET
$(eval BUILD := $(1))
$(eval PIN := $(2))
$(eval BOARD := $(3))
$(eval COMMS_PIN := $(if $(4),$(4),$(2)))
$(eval MCU := $$(call base_mcu,$$(1)))
$(eval EXTRA_CFLAGS := $(call get_cflags,$(1)))
$(eval H_FILE := $(BIN_DIR)/$(call BOOTLOADER_BASENAME_VER,$(BUILD),$(PIN)).h)
$(eval BLT_ELF_FILE := $(BIN_DIR)/$(call BOOTLOADER_TRANSITION_BASENAME_VER,$(BUILD),$(PIN)).elf)
$(eval BLT_HEX_FILE := $(BLT_ELF_FILE:.elf=.hex))
$(eval BLT_DEP_FILE := $(BLT_ELF_FILE:.elf=.d))
$(eval BLT_MAP_FILE := $(BLT_ELF_FILE:.elf=.map))
$(eval BLT_AMJ_FILE := $(BLT_ELF_FILE:.elf=.amj))
$(eval BLT_TARGET := $(call BOOTLOADER_TRANSITION_BASENAME,$(BUILD),$(PIN)))
$(eval xCC := $(if $($(MCU)_CC), $($(MCU)_CC), $(CC)))
$(eval xOBJCOPY := $(if $($(MCU)_OBJCOPY), $($(MCU)_OBJCOPY), $(OBJCOPY)))
$(eval xBLT_LDSCRIPT := $(if $($(MCU)_LDSCRIPT_BLT), $($(MCU)_LDSCRIPT_BLT), $(LDSCRIPT_BLT)))
-include $(BLT_DEP_FILE)
$(BLT_ELF_FILE): CFLAGS_BLT := -DAM32_MCU=\"$(MCU)\" $$(MCU_$(MCU)) $$(CFLAGS_$(MCU)) $$(CFLAGS_BASE) -DBOOTLOADER -DUSE_$(PIN) $(if $(BOARD),-D$(BOARD)) $(EXTRA_CFLAGS) -DBL_TRANSITION=1 -Wno-unused-variable -Wno-unused-function
$(BLT_ELF_FILE): LDFLAGS_BLT := $$(LDFLAGS_COMMON) $$(LDFLAGS_$(MCU)) -T$(xBLT_LDSCRIPT)
$(BLT_ELF_FILE): $$(SRC_$(MCU)_BL) $$(SRC_BLU) $(H_FILE)
$$(QUIET)echo building transition bootloader updater for $(BUILD) with pin $(PIN)
$$(QUIET)$$(MKDIR) -p $(OBJ)
$$(QUIET)echo Compiling $(notdir $$@)
$$(QUIET)$(xCC) $$(CFLAGS_BLT) $$(LDFLAGS_BLT) -MMD -MP -MF $(BLT_DEP_FILE) -o $$(@) $$(SRC_$(MCU)_BL) $$(SRC_BLU) -I. -DBL_HEADER_FILE=$(H_FILE) -Wl,-Map=$(BLT_MAP_FILE)
# only a hex is generated: the image has a gap between the entry vector and
# the code, which the flashing client fills in
$(BLT_HEX_FILE): $$(BLT_ELF_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)$(xOBJCOPY) $$(<) -O ihex $$(@)
$$(QUIET)python3 bl_update/check_transition.py $$(@)
$(BLT_AMJ_FILE): $$(BLT_HEX_FILE)
$$(QUIET)echo Generating $(notdir $$@)
$$(QUIET)python3 bl_update/make_amj.py --type bl_update --pin $(COMMS_PIN) --githash $(shell git rev-parse HEAD) $(BLT_HEX_FILE) $(BLT_AMJ_FILE)
$(BLT_TARGET): $$(BLT_AMJ_FILE)
BLU_BUILDS := $(BLU_BUILDS) $(BLT_TARGET)
endef
# choose per-MCU pin override if set, otherwise the global BOOTLOADER_PINS
pins_for_build = $(if $(BOOTLOADER_PINS_$(call base_mcu,$1)),$(BOOTLOADER_PINS_$(call base_mcu,$1)),$(BOOTLOADER_PINS))
$(foreach BUILD,$(MCU_BUILDS),$(foreach PIN,$(call pins_for_build,$(BUILD)),$(eval $(call CREATE_BOOTLOADER_TARGET,$(BUILD),$(PIN)))$(if $(call has_transition,$(BUILD)),$(eval $(call CREATE_TRANSITION_TARGET,$(BUILD),$(PIN))))))
# custom per-board targets from Inc/targets.h (BUILD|TAG|BOARDDEFINE)
$(foreach B,$(BOARD_TARGETS),$(eval $(call CREATE_BOOTLOADER_TARGET,$(word 1,$(subst |, ,$(B))),$(word 2,$(subst |, ,$(B))),$(word 3,$(subst |, ,$(B))),$(word 4,$(subst |, ,$(B)))))$(if $(call has_transition,$(word 1,$(subst |, ,$(B)))),$(eval $(call CREATE_TRANSITION_TARGET,$(word 1,$(subst |, ,$(B))),$(word 2,$(subst |, ,$(B))),$(word 3,$(subst |, ,$(B))),$(word 4,$(subst |, ,$(B)))))))
bootloaders: $(ALL_BUILDS)
updaters: $(BLU_BUILDS)
# include the targets for installing tools
include $(ROOT)/make/tools_install.mk
# useful target to list all of the board targets so you can see what
# make target to use for your board
targets:
$(QUIET)echo List of targets. To build a target use 'make TARGETNAME'
$(QUIET)echo $(ALL_BUILDS)
updater_targets:
$(QUIET)echo List of updater targets. To build a target use 'make TARGETNAME'
$(QUIET)echo $(BLU_BUILDS)