Merge pull request #3575 from iNavFlight/agh_cms_osd_settings
[inav/snaewe.git] / Makefile
blobab74b50e35a781eec1fa898eb851f10d04aa2a44
1 ###############################################################################
2 # "THE BEER-WARE LICENSE" (Revision 42):
3 # <msmith@FreeBSD.ORG> wrote this file. As long as you retain this notice you
4 # can do whatever you want with this stuff. If we meet some day, and you think
5 # this stuff is worth it, you can buy me a beer in return
6 ###############################################################################
8 # Makefile for building the iNav firmware.
10 # Invoke this with 'make help' to see the list of supported targets.
12 ###############################################################################
15 # Things that the user might override on the commandline
18 # The target to build, see VALID_TARGETS below
19 TARGET ?= REVO
21 # Compile-time options
22 OPTIONS ?=
24 # Debugger optons, must be empty or GDB
25 DEBUG ?=
27 # Build suffix
28 BUILD_SUFFIX ?=
30 # Serial port/Device for flashing
31 SERIAL_DEVICE ?= $(firstword $(wildcard /dev/ttyUSB*) no-port-found)
33 # Flash size (KB). Some low-end chips actually have more flash than advertised, use this to override.
34 FLASH_SIZE ?=
36 ## V : Set verbosity level based on the V= parameter
37 ## V=0 Low
38 ## V=1 High
39 export AT := @
41 ifndef V
42 export V0 :=
43 export V1 := $(AT)
44 export STDOUT :=
45 else ifeq ($(V), 0)
46 export V0 := $(AT)
47 export V1 := $(AT)
48 export STDOUT:= "> /dev/null"
49 export MAKE := $(MAKE) --no-print-directory
50 else ifeq ($(V), 1)
51 export V0 :=
52 export V1 :=
53 export STDOUT :=
54 endif
56 ###############################################################################
57 # Things that need to be maintained as the source changes
60 FORKNAME = inav
62 # Working directories
63 ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
64 SRC_DIR := $(ROOT)/src/main
65 OBJECT_DIR := $(ROOT)/obj/main
66 BIN_DIR := $(ROOT)/obj
67 CMSIS_DIR := $(ROOT)/lib/main/CMSIS
68 INCLUDE_DIRS := $(SRC_DIR) \
69 $(ROOT)/src/main/target
70 LINKER_DIR := $(ROOT)/src/main/target/link
72 # default xtal value for F4 targets
73 HSE_VALUE = 8000000
75 # used for turning on features like VCP and SDCARD
76 FEATURES =
78 ALT_TARGETS = $(sort $(filter-out target, $(basename $(notdir $(wildcard $(ROOT)/src/main/target/*/*.mk)))))
80 VALID_TARGETS = $(dir $(wildcard $(ROOT)/src/main/target/*/target.mk))
81 VALID_TARGETS := $(subst /,, $(subst ./src/main/target/,, $(VALID_TARGETS)))
82 VALID_TARGETS := $(VALID_TARGETS) $(ALT_TARGETS)
83 VALID_TARGETS := $(sort $(VALID_TARGETS))
85 CLEAN_TARGETS = $(addprefix clean_,$(VALID_TARGETS) )
86 TARGETS_CLEAN = $(addsuffix _clean,$(VALID_TARGETS) )
88 ifeq ($(filter $(TARGET),$(ALT_TARGETS)), $(TARGET))
89 BASE_TARGET := $(firstword $(subst /,, $(subst ./src/main/target/,, $(dir $(wildcard $(ROOT)/src/main/target/*/$(TARGET).mk)))))
90 -include $(ROOT)/src/main/target/$(BASE_TARGET)/$(TARGET).mk
91 else
92 BASE_TARGET := $(TARGET)
93 endif
95 # silently ignore if the file is not present. Allows for target specific.
96 -include $(ROOT)/src/main/target/$(BASE_TARGET)/target.mk
98 F4_TARGETS = $(F405_TARGETS) $(F411_TARGETS) $(F427_TARGETS) $(F446_TARGETS)
99 F7_TARGETS = $(F7X2RE_TARGETS) $(F7X5XE_TARGETS) $(F7X5XG_TARGETS) $(F7X5XI_TARGETS) $(F7X6XG_TARGETS)
101 ifeq ($(filter $(TARGET),$(VALID_TARGETS)),)
102 $(error Target '$(TARGET)' is not valid, must be one of $(VALID_TARGETS). Have you prepared a valid target.mk?)
103 endif
105 ifeq ($(filter $(TARGET),$(F1_TARGETS) $(F3_TARGETS) $(F4_TARGETS) $(F7_TARGETS)),)
106 $(error Target '$(TARGET)' has not specified a valid STM group, must be one of F1, F3, F405, F411, F427 or F7x. Have you prepared a valid target.mk?)
107 endif
109 ifeq ($(TARGET),$(filter $(TARGET),$(F3_TARGETS)))
110 TARGET_MCU := STM32F3
111 else ifeq ($(TARGET),$(filter $(TARGET), $(F4_TARGETS)))
112 TARGET_MCU := STM32F4
113 else ifeq ($(TARGET),$(filter $(TARGET), $(F7_TARGETS)))
114 TARGET_MCU := STM32F7
115 else ifeq ($(TARGET),$(filter $(TARGET), $(F1_TARGETS)))
116 TARGET_MCU := STM32F1
117 else
118 $(error Unknown target MCU specified.)
119 endif
121 GROUP_1_TARGETS := ALIENFLIGHTF3 ALIENFLIGHTF4 AIRHEROF3 AIRHEROF3_QUAD COLIBRI_RACE LUX_RACE SPARKY REVO SPARKY2 COLIBRI FALCORE FF_F35_LIGHTNING FF_FORTINIF4 FF_PIKOF4 FF_PIKOF4OSD
122 GROUP_2_TARGETS := SPRACINGF3 SPRACINGF3EVO SPRACINGF3EVO_1SS SPRACINGF3MINI SPRACINGF3NEO SPRACINGF4EVO CLRACINGF4AIR CLRACINGF4AIRV2 BEEROTORF4 BETAFLIGHTF3 BETAFLIGHTF4 PIKOBLX
123 GROUP_3_TARGETS := OMNIBUS AIRBOTF4 BLUEJAYF4 OMNIBUSF4 OMNIBUSF4PRO OMNIBUSF4V3 FIREWORKSV2 SPARKY2 MATEKF405 OMNIBUSF7 DYSF4PRO OMNIBUSF4PRO_LEDSTRIPM5 OMNIBUSF7NXT OMNIBUSF7V2 ASGARD32F4
124 GROUP_4_TARGETS := ANYFC ANYFCF7 ANYFCF7_EXTERNAL_BARO ANYFCM7 ALIENFLIGHTNGF7 PIXRACER YUPIF4 YUPIF4MINI YUPIF4R2 YUPIF7 MATEKF405SE MATEKF411 MATEKF722 MATEKF405OSD MATEKF405_SERVOS6
125 GROUP_OTHER_TARGETS := $(filter-out $(GROUP_1_TARGETS) $(GROUP_2_TARGETS) $(GROUP_3_TARGETS) $(GROUP_4_TARGETS), $(VALID_TARGETS))
127 REVISION = $(shell git rev-parse --short HEAD)
129 FC_VER_MAJOR := $(shell grep " FC_VERSION_MAJOR" src/main/build/version.h | awk '{print $$3}' )
130 FC_VER_MINOR := $(shell grep " FC_VERSION_MINOR" src/main/build/version.h | awk '{print $$3}' )
131 FC_VER_PATCH := $(shell grep " FC_VERSION_PATCH" src/main/build/version.h | awk '{print $$3}' )
133 FC_VER := $(FC_VER_MAJOR).$(FC_VER_MINOR).$(FC_VER_PATCH)
134 FC_VER_SUFFIX ?=
136 BUILD_DATE = $(shell date +%Y%m%d)
138 # Search path for sources
139 FATFS_DIR = $(ROOT)/lib/main/FatFS
140 FATFS_SRC = $(notdir $(wildcard $(FATFS_DIR)/*.c))
142 VPATH := $(SRC_DIR):$(SRC_DIR)/startup
143 VPATH := $(VPATH):$(ROOT)/make/mcu
144 VPATH := $(VPATH):$(ROOT)/make
146 CSOURCES := $(shell find $(SRC_DIR) -name '*.c')
148 # start specific includes
149 include $(ROOT)/make/mcu/$(TARGET_MCU).mk
151 # Configure default flash sizes for the targets (largest size specified gets hit first) if flash not specified already.
152 ifeq ($(FLASH_SIZE),)
153 ifneq ($(TARGET_FLASH),)
154 FLASH_SIZE := $(TARGET_FLASH)
155 else
156 $(error FLASH_SIZE not configured for target $(TARGET))
157 endif
158 endif
160 # Configure devide and target-specific defines and compiler flags
161 DEVICE_FLAGS := $(DEVICE_FLAGS) -DFLASH_SIZE=$(FLASH_SIZE)
162 TARGET_FLAGS := $(TARGET_FLAGS) -D$(TARGET_MCU) -D$(TARGET)
164 ifneq ($(HSE_VALUE),)
165 DEVICE_FLAGS := $(DEVICE_FLAGS) -DHSE_VALUE=$(HSE_VALUE)
166 endif
168 ifneq ($(BASE_TARGET), $(TARGET))
169 TARGET_FLAGS := $(TARGET_FLAGS) -D$(BASE_TARGET)
170 endif
172 TARGET_DIR = $(ROOT)/src/main/target/$(BASE_TARGET)
173 TARGET_DIR_SRC = $(notdir $(wildcard $(TARGET_DIR)/*.c))
175 INCLUDE_DIRS := $(INCLUDE_DIRS) \
176 $(ROOT)/lib/main/MAVLink
178 INCLUDE_DIRS := $(INCLUDE_DIRS) \
179 $(TARGET_DIR)
181 VPATH := $(VPATH):$(TARGET_DIR)
183 .DEFAULT_GOAL := hex
185 include $(ROOT)/make/source.mk
186 include $(ROOT)/make/release.mk
188 ###############################################################################
189 # Things that might need changing to use different tools
192 # Tool names
193 ifneq ($(TOOLCHAINPATH),)
194 CROSS_CC = $(TOOLCHAINPATH)/arm-none-eabi-gcc
195 OBJCOPY = $(TOOLCHAINPATH)/arm-none-eabi-objcopy
196 SIZE = $(TOOLCHAINPATH)/arm-none-eabi-size
197 else
198 CROSS_CC = arm-none-eabi-gcc
199 OBJCOPY = arm-none-eabi-objcopy
200 SIZE = arm-none-eabi-size
201 endif
204 # Tool options.
207 ifeq ($(DEBUG),GDB)
208 OPTIMIZE = -O0
209 LTO_FLAGS = $(OPTIMIZE)
210 else
211 OPTIMIZE = -Os
212 LTO_FLAGS = -flto -fuse-linker-plugin $(OPTIMIZE)
213 endif
215 DEBUG_FLAGS = -ggdb3 -DDEBUG
217 CFLAGS += $(ARCH_FLAGS) \
218 $(LTO_FLAGS) \
219 $(addprefix -D,$(OPTIONS)) \
220 $(addprefix -I,$(INCLUDE_DIRS)) \
221 $(DEBUG_FLAGS) \
222 -std=gnu99 \
223 -Wall -Wextra -Wunsafe-loop-optimizations -Wdouble-promotion \
224 -Werror=switch \
225 -ffunction-sections \
226 -fdata-sections \
227 $(DEVICE_FLAGS) \
228 -DUSE_STDPERIPH_DRIVER \
229 $(TARGET_FLAGS) \
230 -D'__FORKNAME__="$(FORKNAME)"' \
231 -D'__TARGET__="$(TARGET)"' \
232 -D'__REVISION__="$(REVISION)"' \
233 -save-temps=obj \
234 -MMD -MP
236 ASFLAGS = $(ARCH_FLAGS) \
237 -x assembler-with-cpp \
238 $(addprefix -I,$(INCLUDE_DIRS)) \
239 -D$(TARGET) \
240 -MMD -MP
242 LDFLAGS = -lm \
243 -nostartfiles \
244 --specs=nano.specs \
245 -lc \
246 -lnosys \
247 $(ARCH_FLAGS) \
248 $(LTO_FLAGS) \
249 $(DEBUG_FLAGS) \
250 -static \
251 -Wl,-gc-sections,-Map,$(TARGET_MAP) \
252 -Wl,-L$(LINKER_DIR) \
253 -Wl,--cref \
254 -Wl,--no-wchar-size-warning \
255 -Wl,--print-memory-usage \
256 -T$(LD_SCRIPT)
258 ###############################################################################
259 # No user-serviceable parts below
260 ###############################################################################
262 CPPCHECK = cppcheck $(CSOURCES) --enable=all --platform=unix64 \
263 --std=c99 --inline-suppr --quiet --force \
264 $(addprefix -I,$(INCLUDE_DIRS)) \
265 -I/usr/include -I/usr/include/linux
268 # Things we will build
270 TARGET_BIN := $(BIN_DIR)/$(FORKNAME)_$(FC_VER)
271 ifneq ($(FC_VER_SUFFIX),)
272 TARGET_BIN := $(TARGET_BIN)-$(FC_VER_SUFFIX)
273 endif
274 TARGET_BIN := $(TARGET_BIN)_$(TARGET)
275 ifneq ($(BUILD_SUFFIX),)
276 TARGET_BIN := $(TARGET_BIN)_$(BUILD_SUFFIX)
277 endif
278 TARGET_BIN := $(TARGET_BIN).bin
279 TARGET_HEX = $(TARGET_BIN:.bin=.hex)
281 TARGET_OBJ_DIR = $(OBJECT_DIR)/$(TARGET)
282 TARGET_ELF = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).elf
283 TARGET_OBJS = $(addsuffix .o,$(addprefix $(TARGET_OBJ_DIR)/,$(basename $(TARGET_SRC))))
284 TARGET_DEPS = $(addsuffix .d,$(addprefix $(TARGET_OBJ_DIR)/,$(basename $(TARGET_SRC))))
285 TARGET_MAP = $(OBJECT_DIR)/$(FORKNAME)_$(TARGET).map
288 CLEAN_ARTIFACTS := $(TARGET_BIN)
289 CLEAN_ARTIFACTS += $(TARGET_HEX)
290 CLEAN_ARTIFACTS += $(TARGET_ELF) $(TARGET_OBJS) $(TARGET_MAP)
292 # Make sure build date and revision is updated on every incremental build
293 $(TARGET_OBJ_DIR)/build/version.o : $(TARGET_SRC)
295 # Settings generator
296 .PHONY: .FORCE settings clean-settings
297 UTILS_DIR = $(ROOT)/src/utils
298 SETTINGS_GENERATOR = $(UTILS_DIR)/settings.rb
299 BUILD_STAMP = $(UTILS_DIR)/build_stamp.rb
300 STAMP = $(TARGET_OBJ_DIR)/build.stamp
302 GENERATED_SETTINGS = $(TARGET_OBJ_DIR)/settings_generated.h $(TARGET_OBJ_DIR)/settings_generated.c
303 SETTINGS_FILE = $(SRC_DIR)/fc/settings.yaml
304 GENERATED_FILES = $(GENERATED_SETTINGS)
305 $(GENERATED_SETTINGS): $(SETTINGS_GENERATOR) $(SETTINGS_FILE) $(STAMP)
307 # Make sure the generated files are in the include path
308 CFLAGS += -I$(TARGET_OBJ_DIR)
310 $(STAMP): .FORCE
311 $(V1) CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(BUILD_STAMP) $(SETTINGS_FILE) $(STAMP)
313 # Use a pattern rule, since they're different than normal rules.
314 # See https://www.gnu.org/software/make/manual/make.html#Pattern-Examples
315 %generated.h %generated.c:
316 $(V1) echo "settings.yaml -> settings_generated.h, settings_generated.c" "$(STDOUT)"
317 $(V1) CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) -o $(TARGET_OBJ_DIR)
319 settings-json:
320 $(V0) CFLAGS="$(CFLAGS)" TARGET=$(TARGET) ruby $(SETTINGS_GENERATOR) . $(SETTINGS_FILE) --json settings.json
322 clean-settings:
323 $(V1) $(RM) $(GENERATED_SETTINGS)
325 # List of buildable ELF files and their object dependencies.
326 # It would be nice to compute these lists, but that seems to be just beyond make.
328 $(TARGET_HEX): $(TARGET_ELF)
329 $(V0) $(OBJCOPY) -O ihex --set-start 0x8000000 $< $@
331 $(TARGET_BIN): $(TARGET_ELF)
332 $(V0) $(OBJCOPY) -O binary $< $@
334 $(TARGET_ELF): $(TARGET_OBJS)
335 $(V1) echo Linking $(TARGET)
336 $(V1) $(CROSS_CC) -o $@ $(filter %.o, $^) $(LDFLAGS)
337 $(V0) $(SIZE) $(TARGET_ELF)
339 # Compile
340 $(TARGET_OBJ_DIR)/%.o: %.c
341 $(V1) mkdir -p $(dir $@)
342 $(V1) echo %% $(notdir $<) "$(STDOUT)"
343 $(V1) $(CROSS_CC) -c -o $@ $(CFLAGS) $<
345 # Assemble
346 $(TARGET_OBJ_DIR)/%.o: %.s
347 $(V1) mkdir -p $(dir $@)
348 $(V1) echo %% $(notdir $<) "$(STDOUT)"
349 $(V1) $(CROSS_CC) -c -o $@ $(ASFLAGS) $<
351 $(TARGET_OBJ_DIR)/%.o: %.S
352 $(V1) mkdir -p $(dir $@)
353 $(V1) echo %% $(notdir $<) "$(STDOUT)"
354 $(V1) $(CROSS_CC) -c -o $@ $(ASFLAGS) $<
357 ## all : Build all valid targets
358 all: $(VALID_TARGETS)
360 ## targets-group-1 : build some targets
361 targets-group-1: $(GROUP_1_TARGETS)
363 ## targets-group-2 : build some targets
364 targets-group-2: $(GROUP_2_TARGETS)
366 ## targets-group-3 : build some targets
367 targets-group-3: $(GROUP_3_TARGETS)
369 ## targets-group-3 : build some targets
370 targets-group-4: $(GROUP_4_TARGETS)
372 ## targets-group-rest: build the rest of the targets (not listed in group 1, 2 or 3)
373 targets-group-rest: $(GROUP_OTHER_TARGETS)
375 ## targets-group-rest: build targets specified in release-targets list
376 release: $(RELEASE_TARGETS)
378 $(VALID_TARGETS):
379 $(V0) echo "" && \
380 echo "Building $@" && \
381 $(MAKE) -j 8 TARGET=$@ && \
382 echo "Building $@ succeeded."
384 ## clean : clean up all temporary / machine-generated files
385 clean:
386 $(V0) echo "Cleaning $(TARGET)"
387 $(V0) rm -f $(CLEAN_ARTIFACTS)
388 $(V0) rm -rf $(TARGET_OBJ_DIR)
389 $(V0) echo "Cleaning $(TARGET) succeeded."
391 ## clean_test : clean up all temporary / machine-generated files (tests)
392 clean_test:
393 $(V0) cd src/test && $(MAKE) clean
395 ## clean_<TARGET> : clean up one specific target
396 $(CLEAN_TARGETS) :
397 $(V0) $(MAKE) -j 8 TARGET=$(subst clean_,,$@) clean
399 ## <TARGET>_clean : clean up one specific target (alias for above)
400 $(TARGETS_CLEAN) :
401 $(V0) $(MAKE) -j 8 TARGET=$(subst _clean,,$@) clean
403 ## clean_all : clean all valid targets
404 clean_all:$(CLEAN_TARGETS)
406 ## all_clean : clean all valid targets (alias for above)
407 all_clean:$(TARGETS_CLEAN)
409 flash_$(TARGET): $(TARGET_HEX)
410 $(V0) stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
411 $(V0) echo -n 'R' >$(SERIAL_DEVICE)
412 $(V0) stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
414 ## flash : flash firmware (.hex) onto flight controller
415 flash: flash_$(TARGET)
417 st-flash_$(TARGET): $(TARGET_BIN)
418 $(V0) st-flash --reset write $< 0x08000000
420 ## st-flash : flash firmware (.bin) onto flight controller
421 st-flash: st-flash_$(TARGET)
423 binary: $(TARGET_BIN)
424 hex: $(TARGET_HEX)
426 unbrick_$(TARGET): $(TARGET_HEX)
427 $(V0) stty -F $(SERIAL_DEVICE) raw speed 115200 -crtscts cs8 -parenb -cstopb -ixon
428 $(V0) stm32flash -w $(TARGET_HEX) -v -g 0x0 -b 115200 $(SERIAL_DEVICE)
430 ## unbrick : unbrick flight controller
431 unbrick: unbrick_$(TARGET)
433 ## cppcheck : run static analysis on C source code
434 cppcheck: $(CSOURCES)
435 $(V0) $(CPPCHECK)
437 cppcheck-result.xml: $(CSOURCES)
438 $(V0) $(CPPCHECK) --xml-version=2 2> cppcheck-result.xml
440 ## help : print this help message and exit
441 help: Makefile
442 $(V0) @echo ""
443 $(V0) @echo "Makefile for the $(FORKNAME) firmware"
444 $(V0) @echo ""
445 $(V0) @echo "Usage:"
446 $(V0) @echo " make [TARGET=<target>] [OPTIONS=\"<options>\"]"
447 $(V0) @echo "Or:"
448 $(V0) @echo " make <target> [OPTIONS=\"<options>\"]"
449 $(V0) @echo ""
450 $(V0) @echo "Valid TARGET values are: $(VALID_TARGETS)"
451 $(V0) @echo ""
452 $(V0) @sed -n 's/^## //p' $<
454 ## targets : print a list of all valid target platforms (for consumption by scripts)
455 targets:
456 $(V0) @echo "Valid targets: $(VALID_TARGETS)"
457 $(V0) @echo "Target: $(TARGET)"
458 $(V0) @echo "Base target: $(BASE_TARGET)"
459 $(V0) @echo "targets-group-1: $(GROUP_1_TARGETS)"
460 $(V0) @echo "targets-group-2: $(GROUP_2_TARGETS)"
461 $(V0) @echo "targets-group-3: $(GROUP_3_TARGETS)"
462 $(V0) @echo "targets-group-4: $(GROUP_4_TARGETS)"
463 $(V0) @echo "targets-group-rest: $(GROUP_OTHER_TARGETS)"
464 $(V0) @echo "Release targets: $(RELEASE_TARGETS)"
466 ## test : run the cleanflight test suite
467 test:
468 $(V0) cd src/test && $(MAKE) test
470 # rebuild everything when makefile changes
471 # Make the generated files and the build stamp order only prerequisites,
472 # so they will be generated before TARGET_OBJS but regenerating them
473 # won't cause all TARGET_OBJS to be rebuilt.
474 $(TARGET_OBJS) : Makefile | $(GENERATED_FILES) $(STAMP)
476 # include auto-generated dependencies
477 -include $(TARGET_DEPS)