2022-01-29 06:53:38 -08:00
# Makefile for Rootloader project
.DEFAULT_GOAL := help
WHEREAMI := $( dir $( lastword $( MAKEFILE_LIST) ) )
ROOT_DIR := $( realpath $( WHEREAMI) / )
2022-02-27 21:55:47 -08:00
# Define a recursive wildcard function
# C.f. https://stackoverflow.com/a/18258352
rwildcard = $( foreach d,$( wildcard $( 1:= /*) ) ,$( call rwildcard,$d ,$2 ) $( filter $( subst *,%,$2 ) ,$d ) )
2021-11-14 21:32:00 -08:00
2022-02-27 21:55:47 -08:00
# Get the raw paths for all *.h files
2022-03-07 05:45:29 -08:00
RAW_TARGET_PATHS := $( call rwildcard,$( ROOT_DIR) /hwconf,*.h)
2022-02-27 21:55:47 -08:00
# Get the target paths by filtering out any core.h files, then stripping extra whitespace
TARGET_PATHS := $( strip $( filter-out %core.h,$( RAW_TARGET_PATHS) ) )
# Strip the paths down to just the names. Do this by first using `notdir` to remove the paths, then the prefix (hw_), then remove the suffix (.h). Finally, sort into lexical order.
ALL_BOARD_NAMES := $( sort $( subst .h,,$( subst hw_,,$( filter hw_%, $( notdir $( TARGET_PATHS) ) ) ) ) )
2021-11-14 21:32:00 -08:00
2022-01-29 06:53:38 -08:00
# configure some directories that are relative to wherever ROOT_DIR is located
TOOLS_DIR := $( ROOT_DIR) /tools
2021-11-15 10:16:39 -08:00
MAKE_DIR := $( ROOT_DIR) /make
2022-01-29 06:53:38 -08:00
BUILD_DIR := $( ROOT_DIR) /build
DL_DIR := $( ROOT_DIR) /downloads
2021-11-15 12:10:38 -08:00
# import macros common to all supported build systems
i n c l u d e $( ROOT_DIR ) / m a k e / s y s t e m - i d . m k
# import macros that are OS specific
i n c l u d e $( ROOT_DIR ) / m a k e / $( OSFAMILY ) . m k
2022-01-29 06:53:38 -08:00
# include the tools makefile
i n c l u d e $( ROOT_DIR ) / m a k e / t o o l s . m k
# Clean out undesirable variables from the environment and command-line
# to remove the chance that they will cause problems with our build
d e f i n e S A N I T I Z E _ V A R
$( if $ ( filter -out undefined ,$ ( origin $ ( 1) ) ) ,
$( info *NOTE* Sanitized $( 2) variable '$(1)' from $( origin $( 1) ) )
MAKEOVERRIDES = $( filter-out $( 1) = %,$( MAKEOVERRIDES) )
override $( 1) :=
unexport $( 1)
)
e n d e f
# These specific variables can influence gcc in unexpected (and undesirable) ways
SANITIZE_GCC_VARS := TMPDIR GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH
SANITIZE_GCC_VARS += CFLAGS CPATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH OBJC_INCLUDE_PATH DEPENDENCIES_OUTPUT
SANITIZE_GCC_VARS += ARCHFLAGS
$( foreach var , $ ( SANITIZE_GCC_VARS ) , $ ( eval $ ( call SANITIZE_VAR ,$ ( var ) ,disallowed ) ) )
# These specific variables used to be valid but now they make no sense
SANITIZE_DEPRECATED_VARS := FOO_BAR
$( foreach var , $ ( SANITIZE_DEPRECATED_VARS ) , $ ( eval $ ( call SANITIZE_VAR ,$ ( var ) ,deprecated ) ) )
# Decide on a verbosity level based on the V= parameter
export AT := @
i f n d e f V
export V0 :=
export V1 := $( AT)
e l s e i f e q ( $( V ) , 0 )
export V0 := $( AT)
export V1 := $( AT)
e l s e i f e q ( $( V ) , 1 )
e n d i f
##############################
#
# Help instructions
#
##############################
.PHONY : help
help :
@echo
@echo " This Makefile is known to work on Linux and Mac in a standard shell environment."
@echo
@echo " Here is a summary of the available targets:"
@echo
@echo " [Tool Installers]"
@echo " arm_sdk_install - Install the GNU ARM gcc toolchain"
2021-12-22 18:20:47 -08:00
@echo " qt_install - Install the all tools for Qt"
2022-01-29 06:53:38 -08:00
@echo
2021-11-15 08:26:16 -08:00
@echo " [Big Hammer]"
@echo " all_fw - Build firmware for all boards"
2022-03-07 05:34:08 -08:00
@echo " all_fw_package - Packaage firmware for boards in package list"
2021-11-15 08:26:16 -08:00
@echo
2021-10-07 23:53:58 -07:00
@echo " [Unit Tests]"
@echo " all_ut - Build all unit tests"
@echo " all_ut_xml - Run all unit tests and capture all XML output to files"
@echo " all_ut_run - Run all unit tests and dump XML output to console"
2022-01-29 06:53:38 -08:00
@echo
@echo " [Firmware]"
@echo " fw - Build firmware for default target"
2021-12-02 04:05:23 -08:00
@echo " supported boards are: $( ALL_BOARD_NAMES) "
2021-11-14 21:32:00 -08:00
@echo " fw_<board> - Build firmware for target <board>"
2022-01-29 06:53:38 -08:00
@echo " PROJECT=<target> fw - Build firmware for <target>"
2021-11-14 21:32:00 -08:00
@echo " fw_<board>_clean - Remove firmware for <board>"
2021-11-15 11:12:16 -08:00
@echo " fw_<board>_flash - Use OpenOCD + SWD/JTAG to write firmware to <target>"
2022-01-29 06:53:38 -08:00
@echo
@echo " Hint: Add V=1 to your command line to see verbose build output."
@echo
@echo " Note: All tools will be installed into $( TOOLS_DIR) "
@echo " All build output will be placed in $( BUILD_DIR) "
@echo
$(DL_DIR) :
2021-11-15 12:10:38 -08:00
$( V1) $( MKDIR) $@
2022-01-29 06:53:38 -08:00
$(TOOLS_DIR) :
2021-11-15 12:10:38 -08:00
$( V1) $( MKDIR) $@
2022-01-29 06:53:38 -08:00
##############################
#
# Build and Upload
#
##############################
2021-11-14 21:32:00 -08:00
2022-02-27 21:55:47 -08:00
# $(1) = Canonical board name all in lower case (e.g. 100_250)
# $(2) = Target hardware directory
d e f i n e F I N D _ T A R G E T _ C _ C O D E
2022-02-28 19:01:01 -08:00
# Remove `_no_limits`
$( eval ROOT_TARGET_NAME = $( subst _no_limits,,$( 1) ) )
2022-02-27 21:55:47 -08:00
# Look for `*_core.c` file
ifneq ( " $( wildcard $( 2) /hw_*_core.c) " ,"" )
# Good luck, there it is!
HW_SRC_FILE = $( wildcard $( 2) /hw_*_core.c)
else
# There isn't one, so let's hope for the sister `.c` file
2022-02-28 19:01:01 -08:00
HW_SRC_FILE = $( 2) /hw_$( ROOT_TARGET_NAME) .c
2022-02-27 21:55:47 -08:00
endif
e n d e f
2021-11-14 21:32:00 -08:00
# $(1) = Canonical board name all in lower case (e.g. 100_250)
2021-11-15 11:12:16 -08:00
# $(2) = firmware build directory
# $(3) = firmware name
2022-03-06 16:03:32 -08:00
# $(4) = git branch name
# $(5) = git hash (and dirty flag)
# $(6) = compiler version
2021-11-14 21:32:00 -08:00
d e f i n e F W _ T E M P L A T E
.PHONY : $( 1) fw_ $( 1)
$(1) : fw_ $( 1) _vescfw
fw_$(1) : fw_ $( 1) _vescfw
2022-02-27 21:55:47 -08:00
fw_$(1)_vescfw : $( eval HW_DIR = $ ( dir $ ( filter %/hw_ $ ( 1) .h , $ ( TARGET_PATHS ) ) ) ) # Find the directory for this header file
fw_$(1)_vescfw : $( eval HW_SRC_FILE = $ ( call FIND_TARGET_C_CODE ,$ ( 1) ,$ ( HW_DIR ) ) ) # Find the c code associated to this header file
2021-11-14 21:32:00 -08:00
fw_$(1)_vescfw :
2021-11-15 08:30:23 -08:00
@echo " ********* BUILD: $( 1) ********** "
2021-11-15 12:10:38 -08:00
$( V1) $( MKDIR) $( BUILD_DIR) /$( 1)
2022-03-13 09:21:07 -07:00
$( V1) $$ ( MAKE) -f $( MAKE_DIR) /fw.mk \
2022-01-29 06:53:38 -08:00
TCHAIN_PREFIX = " $( ARM_SDK_PREFIX) " \
2021-11-15 11:12:16 -08:00
BUILDDIR = " $( 2) " \
PROJECT = " $( 3) " \
2022-03-06 16:03:32 -08:00
build_args = '-DHW_SOURCE=\"$(HW_SRC_FILE)\" -DHW_HEADER=\"$(HW_DIR)/hw_$(1).h\" -DGIT_BRANCH_NAME=\"$(4)\" -DGIT_COMMIT_HASH=\"$(5)\" -DARM_GCC_VERSION=\"$(6)\"' USE_VERBOSE_COMPILE = no
2021-11-14 21:32:00 -08:00
2021-11-15 11:12:16 -08:00
$(1)_flash : fw_ $( 1) _flash
fw_$(1)_flash : fw_ $( 1) _vescfw fw_ $( 1) _flash_only
$(1)_flash_only : fw_ $( 1) _flash_only
fw_$(1)_flash_only :
@echo " ********* PROGRAM: $( 1) ********** "
$( V1) openocd -f board/stm32f4discovery.cfg -c "reset_config trst_only combined" -c " program $( 2) / $( 3) .elf verify reset exit "
2021-11-14 21:32:00 -08:00
.PHONY : $( 1) _clean
$(1)_clean : fw_ $( 1) _clean
fw_$(1)_clean : TARGET =fw_ $( 1)
fw_$(1)_clean : OUTDIR =$( BUILD_DIR ) /$$( TARGET )
fw_$(1)_clean :
$( V0) @echo " CLEAN $$ @ "
2021-11-15 12:10:38 -08:00
i f n e q ( $( OSFAMILY ) , w i n d o w s )
2021-11-15 10:16:39 -08:00
$( V1) [ ! -d " $( BUILD_DIR) / $( 1) " ] || $( RM) -r " $( BUILD_DIR) / $( 1) "
2022-03-18 05:24:41 -07:00
$( V1) [ ! -d " $( ROOT_DIR) /.dep " ] || $( RM) -r " $( ROOT_DIR) /.dep "
2021-11-15 12:10:38 -08:00
e l s e
2022-03-21 05:12:57 -07:00
$( V1) powershell -noprofile -command " & {if (Test-Path $( BUILD_DIR) / $( 1) ) {Remove-Item -Recurse $( BUILD_DIR) / $( 1) }} "
$( V1) powershell -noprofile -command " & {if (Test-Path $( ROOT_DIR) /.dep) {Remove-Item -Recurse $( ROOT_DIR) /.dep}} "
2021-11-15 12:10:38 -08:00
e n d i f
2021-11-14 21:32:00 -08:00
e n d e f
2022-01-29 06:53:38 -08:00
clear_option_bytes :
$( V1) openocd -f board/stm32f4discovery.cfg -c "init" -c "stm32f2x unlock 0" -c "mww 0x40023C08 0x08192A3B; mww 0x40023C08 0x4C5D6E7F; mww 0x40023C14 0x0fffaaed" -c "exit"
#program with olimex arm-usb-tiny-h and jtag-swd adapter board. needs openocd>=0.9
upload-olimex : fw
$( V1) openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f interface/ftdi/olimex-arm-jtag-swd.cfg -c "set WORKAREASIZE 0x2000" -f target/stm32f4x.cfg -c " program build/ $( PROJECT) .elf verify reset "
upload-pi : fw
$( V1) openocd -f pi_stm32.cfg -c "reset_config trst_only combined" -c " program build/ $( PROJECT) .elf verify reset exit "
upload-pi-remote : fw
$( V1) ./upload_remote_pi build/$( PROJECT) .elf ted 10.42.0.199 22
debug-start :
$( V1) openocd -f stm32-bv_openocd.cfg
2021-11-13 23:32:43 -08:00
size : build /$( PROJECT ) .elf
@$( SZ) $<
2021-11-15 08:26:16 -08:00
# Generate the targets for whatever boards are in each list
2021-12-02 04:05:23 -08:00
FW_TARGETS := $( addprefix fw_, $( ALL_BOARD_NAMES) )
2021-11-15 08:26:16 -08:00
.PHONY : all_fw all_fw_clean
all_fw : $( addsuffix _vescfw , $ ( FW_TARGETS ) )
all_fw_clean : $( addsuffix _clean , $ ( FW_TARGETS ) )
2021-11-14 21:32:00 -08:00
# Expand the firmware rules
2022-03-06 16:03:32 -08:00
$( foreach board , $ ( ALL_BOARD_NAMES ) , $ ( eval $ ( call FW_TEMPLATE ,$ ( board ) ,$ ( BUILD_DIR ) /$ ( board ) ,$ ( board ) ,$ ( GIT_BRANCH_NAME ) ,$ ( GIT_COMMIT_HASH ) $ ( GIT_DIRTY_LABEL ) ,$ ( ARM_GCC_VERSION ) ) ) )
2021-10-07 23:53:58 -07:00
2022-03-07 05:34:08 -08:00
##############################
#
# Packaging
#
##############################
.PHONY : all_fw_package
2022-03-07 06:12:59 -08:00
all_fw_package : all_fw all_fw_package_clean
2022-03-07 06:13:58 -08:00
$( V0) @echo " PACKAGE $( ROOT_DIR) /package/* "
# Place all firmware files into `./package` directory
2022-03-12 10:23:01 -08:00
$( V1) $( PYTHON) package_firmware.py
2022-03-07 05:34:08 -08:00
2022-03-07 06:13:58 -08:00
# Find all the leftover object and lst files
2022-03-07 05:34:08 -08:00
$( eval BUILD_CRUFT := $( call rwildcard,$( ROOT_DIR) /build,*.lst *.o) )
2022-03-07 06:13:58 -08:00
# Delete the cruft files, so as not to unnecessarily consume GB of space
2022-03-07 05:34:08 -08:00
i f n e q ( $( OSFAMILY ) , w i n d o w s )
$( V1) $( RM) $( BUILD_CRUFT)
e l s e
2022-03-21 05:12:57 -07:00
$( V1) powershell -noprofile -command " & {Remove-Item $( BUILD_CRUFT) } "
2022-03-07 05:34:08 -08:00
e n d i f
2022-03-07 06:12:59 -08:00
.PHONY : all_fw_package_clean
all_fw_package_clean :
$( V0) @echo " CLEAN $( ROOT_DIR) /package/* "
i f n e q ( $( OSFAMILY ) , w i n d o w s )
2022-03-07 07:21:08 -08:00
$( V1) [ ! -d " $( ROOT_DIR) /package/ " ] || $( RM) -rf $( ROOT_DIR) /package/*
2022-03-07 06:12:59 -08:00
e l s e
2022-03-21 05:12:57 -07:00
$( V1) powershell -noprofile -command " & {if (Test-Path $( ROOT_DIR) /package/*) {Remove-Item -Recurse $( ROOT_DIR) /package/*}} "
2022-03-07 06:12:59 -08:00
e n d i f
2022-03-07 05:34:08 -08:00
2021-10-07 23:53:58 -07:00
##############################
#
# Unit Tests
#
##############################
2022-03-16 10:45:17 -07:00
ALL_UNITTESTS := utils_math
2021-10-07 23:53:58 -07:00
UT_OUT_DIR := $( BUILD_DIR) /unit_tests
$(UT_OUT_DIR) :
2022-03-14 08:06:38 -07:00
$( V1) $( MKDIR) $@
2021-10-07 23:53:58 -07:00
.PHONY : all_ut
all_ut : $( addsuffix _elf , $ ( addprefix ut_ , $ ( ALL_UNITTESTS ) ) ) $( ALL_PYTHON_UNITTESTS )
.PHONY : all_ut_xml
all_ut_xml : $( addsuffix _xml , $ ( addprefix ut_ , $ ( ALL_UNITTESTS ) ) )
.PHONY : all_ut_run
all_ut_run : $( addsuffix _run , $ ( addprefix ut_ , $ ( ALL_UNITTESTS ) ) ) $( ALL_PYTHON_UNITTESTS )
.PHONY : all_ut_gcov
all_ut_gcov : | $( addsuffix _gcov , $ ( addprefix ut_ , $ ( ALL_UNITTESTS ) ) )
.PHONY : all_ut_clean
all_ut_clean :
$( V0) @echo " CLEAN $@ "
$( V1) [ ! -d " $( UT_OUT_DIR) " ] || $( RM) -r " $( UT_OUT_DIR) "
# $(1) = Unit test name
d e f i n e U T _ T E M P L A T E
.PHONY : ut_ $( 1)
ut_$(1) : ut_ $( 1) _run
ut_$(1)_gcov : | ut_ $( 1) _xml
ut_$(1)_% : TARGET =$( 1)
ut_$(1)_% : OUTDIR =$( UT_OUT_DIR ) /$$( TARGET )
ut_$(1)_% : UT_ROOT_DIR =$( ROOT_DIR ) /tests /$( 1)
ut_$(1)_% : $$( UT_OUT_DIR )
2022-03-14 08:06:38 -07:00
$( V1) $( MKDIR) $( UT_OUT_DIR) /$( 1)
2021-10-07 23:53:58 -07:00
$( V1) cd $$ ( UT_ROOT_DIR) && \
$$ ( MAKE) -r --no-print-directory \
BUILD_TYPE = ut \
TCHAIN_PREFIX = "" \
REMOVE_CMD = " $( RM) " \
\
MAKE_INC_DIR = $( MAKE_INC_DIR) \
ROOT_DIR = $( ROOT_DIR) \
TARGET = $$ ( TARGET) \
OUTDIR = $$ ( OUTDIR) \
\
GTEST_DIR = $( GTEST_DIR) \
\
$$ *
.PHONY : ut_ $( 1) _clean
ut_$(1)_clean : TARGET =$( 1)
ut_$(1)_clean : OUTDIR =$( UT_OUT_DIR ) /$$( TARGET )
ut_$(1)_clean :
$( V0) @echo " CLEAN $( 1) "
$( V1) [ ! -d " $$ (OUTDIR) " ] || $( RM) -r " $$ (OUTDIR) "
e n d e f
# Expand the unittest rules
$( foreach ut , $ ( ALL_UNITTESTS ) , $ ( eval $ ( call UT_TEMPLATE ,$ ( ut ) ) ) )
# Disable parallel make when the all_ut_run target is requested otherwise the TAP/XML
# output is interleaved with the rest of the make output.
i f n e q ( $( strip $ ( filter all_ut_run ,$ ( MAKECMDGOALS ) ) ) , )
.NOTPARALLEL :
$( info *NOTE * Parallel make disabled by all_ut_run target so we have sane console output )
e n d i f