diff --git a/.gitignore b/.gitignore index b0ad30c..759a4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ /*.bin /*.hex *.d +downloads/ +tools/ diff --git a/make/system-id.mk b/make/system-id.mk new file mode 100644 index 0000000..1fd42ed --- /dev/null +++ b/make/system-id.mk @@ -0,0 +1,46 @@ +# shared.mk +# +# environment variables common to all operating systems supported by the make system + +# Make sure we know a few things about the architecture +UNAME := $(shell uname) +ARCH := $(shell uname -m) +ifneq (,$(filter $(ARCH), x86_64 amd64)) + X86-64 := 1 + X86_64 := 1 + AMD64 := 1 + ARCHFAMILY := x86_64 +else + ARCHFAMILY := $(ARCH) +endif + +# configure some variables dependent upon what type of system this is + +# Linux +ifeq ($(UNAME), Linux) + OSFAMILY := linux +endif + +# Mac OSX +ifeq ($(UNAME), Darwin) + OSFAMILY := macosx +endif + +# Windows using MinGW shell +ifeq (MINGW, $(findstring MINGW,$(UNAME))) + OSFAMILY := windows + MINGW := 1 +endif + +# Windows using Cygwin shell +ifeq (CYGWIN ,$(findstring CYGWIN,$(UNAME))) + OSFAMILY := windows + CYGWIN := 1 +endif + +# report an error if we couldn't work out what OS this is running on +ifndef OSFAMILY + $(info uname reports $(UNAME)) + $(info uname -m reports $(ARCH)) + $(error failed to detect operating system) +endif diff --git a/make/tools.mk b/make/tools.mk new file mode 100644 index 0000000..7b65029 --- /dev/null +++ b/make/tools.mk @@ -0,0 +1,319 @@ +############################################################### +# +# Installers for tools +# +# NOTE: These are not tied to the default goals +# and must be invoked manually +# +############################################################### + +############################## +# +# Check that environmental variables are sane +# +############################## + +# Set up ARM (STM32) SDK +ARM_SDK_DIR ?= $(TOOLS_DIR)/gcc-arm-none-eabi-9-2020-q2-update +# Checked below, Should match the output of $(shell arm-none-eabi-gcc -dumpversion) +GCC_REQUIRED_VERSION ?= 9.3.1 + +.PHONY: arm_sdk_version + +arm_sdk_version: + $(V1) $(ARM_SDK_PREFIX)gcc --version + +## arm_sdk_install : Install Arm SDK +.PHONY: arm_sdk_install + +ARM_SDK_URL_BASE := https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update + +# source: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads +ifeq ($(OSFAMILY), linux) + ARM_SDK_URL := $(ARM_SDK_URL_BASE)-x86_64-linux.tar.bz2 +endif + +ifeq ($(OSFAMILY), macosx) + ARM_SDK_URL := $(ARM_SDK_URL_BASE)-mac.tar.bz2 +endif + +ifeq ($(OSFAMILY), windows) + ARM_SDK_URL := $(ARM_SDK_URL_BASE)-win32.zip +endif + +ARM_SDK_FILE := $(notdir $(ARM_SDK_URL)) + +SDK_INSTALL_MARKER := $(ARM_SDK_DIR)/bin/arm-none-eabi-gcc-$(GCC_REQUIRED_VERSION) + +# order-only prereq on directory existance: +arm_sdk_install: | $(TOOLS_DIR) + +arm_sdk_install: arm_sdk_download $(SDK_INSTALL_MARKER) + +$(SDK_INSTALL_MARKER): +ifneq ($(OSFAMILY), windows) + # binary only release so just extract it + $(V1) tar -C $(TOOLS_DIR) -xjf "$(DL_DIR)/$(ARM_SDK_FILE)" +else + $(V1) unzip -q -d $(ARM_SDK_DIR) "$(DL_DIR)/$(ARM_SDK_FILE)" +endif + +.PHONY: arm_sdk_download +arm_sdk_download: | $(DL_DIR) +arm_sdk_download: $(DL_DIR)/$(ARM_SDK_FILE) +$(DL_DIR)/$(ARM_SDK_FILE): + # download the source only if it's newer than what we already have + $(V1) curl -L -k -o "$(DL_DIR)/$(ARM_SDK_FILE)" -z "$(DL_DIR)/$(ARM_SDK_FILE)" "$(ARM_SDK_URL)" + + +## arm_sdk_clean : Uninstall Arm SDK +.PHONY: arm_sdk_clean +arm_sdk_clean: + $(V1) [ ! -d "$(ARM_SDK_DIR)" ] || $(RM) -r $(ARM_SDK_DIR) + $(V1) [ ! -d "$(DL_DIR)" ] || $(RM) -r $(DL_DIR) + +.PHONY: openocd_win_install + +openocd_win_install: | $(DL_DIR) $(TOOLS_DIR) +openocd_win_install: OPENOCD_URL := git://git.code.sf.net/p/openocd/code +openocd_win_install: OPENOCD_REV := cf1418e9a85013bbf8dbcc2d2e9985695993d9f4 +openocd_win_install: OPENOCD_OPTIONS := + +ifeq ($(OPENOCD_FTDI), yes) +openocd_win_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ft2232_ftd2xx --with-ftd2xx-win32-zipdir=$(FTD2XX_DIR) +endif + +openocd_win_install: openocd_win_clean libusb_win_install ftd2xx_install + # download the source + @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_REV)" + $(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)" + $(V1) mkdir -p "$(OPENOCD_BUILD_DIR)" + $(V1) git clone --no-checkout $(OPENOCD_URL) "$(DL_DIR)/openocd-build" + $(V1) ( \ + cd $(OPENOCD_BUILD_DIR) ; \ + git checkout -q $(OPENOCD_REV) ; \ + ) + + # apply patches + @echo " PATCH $(OPENOCD_BUILD_DIR)" + $(V1) ( \ + cd $(OPENOCD_BUILD_DIR) ; \ + git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0003-freertos-cm4f-fpu-support.patch ; \ + git apply < $(ROOT_DIR)/flight/Project/OpenOCD/0004-st-icdi-disable.patch ; \ + ) + + # build and install + @echo " BUILD $(OPENOCD_WIN_DIR)" + $(V1) mkdir -p "$(OPENOCD_WIN_DIR)" + $(V1) ( \ + cd $(OPENOCD_BUILD_DIR) ; \ + ./bootstrap ; \ + ./configure --enable-maintainer-mode --prefix="$(OPENOCD_WIN_DIR)" \ + --build=i686-pc-linux-gnu --host=i586-mingw32msvc \ + CPPFLAGS=-I$(LIBUSB_WIN_DIR)/include \ + LDFLAGS=-L$(LIBUSB_WIN_DIR)/lib/gcc \ + $(OPENOCD_OPTIONS) \ + --disable-werror \ + --enable-stlink ; \ + $(MAKE) ; \ + $(MAKE) install ; \ + ) + + # delete the extracted source when we're done + $(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)" + +.PHONY: openocd_win_clean +openocd_win_clean: + @echo " CLEAN $(OPENOCD_WIN_DIR)" + $(V1) [ ! -d "$(OPENOCD_WIN_DIR)" ] || $(RM) -r "$(OPENOCD_WIN_DIR)" + +# Set up openocd tools +OPENOCD_DIR := $(TOOLS_DIR)/openocd +OPENOCD_WIN_DIR := $(TOOLS_DIR)/openocd_win +OPENOCD_BUILD_DIR := $(DL_DIR)/openocd-build + +.PHONY: openocd_install + +openocd_install: | $(DL_DIR) $(TOOLS_DIR) +openocd_install: OPENOCD_URL := git://git.code.sf.net/p/openocd/code +openocd_install: OPENOCD_TAG := v0.9.0 +openocd_install: OPENOCD_OPTIONS := --enable-maintainer-mode --prefix="$(OPENOCD_DIR)" --enable-buspirate --enable-stlink + +ifeq ($(OPENOCD_FTDI), yes) +openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --enable-ftdi +endif + +ifeq ($(UNAME), Darwin) +openocd_install: OPENOCD_OPTIONS := $(OPENOCD_OPTIONS) --disable-option-checking +endif + +openocd_install: openocd_clean + # download the source + @echo " DOWNLOAD $(OPENOCD_URL) @ $(OPENOCD_TAG)" + $(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)" + $(V1) mkdir -p "$(OPENOCD_BUILD_DIR)" + $(V1) git clone --no-checkout $(OPENOCD_URL) "$(OPENOCD_BUILD_DIR)" + $(V1) ( \ + cd $(OPENOCD_BUILD_DIR) ; \ + git checkout -q tags/$(OPENOCD_TAG) ; \ + ) + + # build and install + @echo " BUILD $(OPENOCD_DIR)" + $(V1) mkdir -p "$(OPENOCD_DIR)" + $(V1) ( \ + cd $(OPENOCD_BUILD_DIR) ; \ + ./bootstrap ; \ + ./configure $(OPENOCD_OPTIONS) ; \ + $(MAKE) ; \ + $(MAKE) install ; \ + ) + + # delete the extracted source when we're done + $(V1) [ ! -d "$(OPENOCD_BUILD_DIR)" ] || $(RM) -rf "$(OPENOCD_BUILD_DIR)" + +.PHONY: openocd_clean +openocd_clean: + @echo " CLEAN $(OPENOCD_DIR)" + $(V1) [ ! -d "$(OPENOCD_DIR)" ] || $(RM) -r "$(OPENOCD_DIR)" + +STM32FLASH_DIR := $(TOOLS_DIR)/stm32flash + +.PHONY: stm32flash_install +stm32flash_install: STM32FLASH_URL := http://stm32flash.googlecode.com/svn/trunk +stm32flash_install: STM32FLASH_REV := 61 +stm32flash_install: stm32flash_clean + # download the source + @echo " DOWNLOAD $(STM32FLASH_URL) @ r$(STM32FLASH_REV)" + $(V1) svn export -q -r "$(STM32FLASH_REV)" "$(STM32FLASH_URL)" "$(STM32FLASH_DIR)" + + # build + @echo " BUILD $(STM32FLASH_DIR)" + $(V1) $(MAKE) --silent -C $(STM32FLASH_DIR) all + +.PHONY: stm32flash_clean +stm32flash_clean: + @echo " CLEAN $(STM32FLASH_DIR)" + $(V1) [ ! -d "$(STM32FLASH_DIR)" ] || $(RM) -r "$(STM32FLASH_DIR)" + +# Set up uncrustify tools +UNCRUSTIFY_DIR := $(TOOLS_DIR)/uncrustify-0.61 +UNCRUSTIFY_BUILD_DIR := $(DL_DIR)/uncrustify + +.PHONY: uncrustify_install +uncrustify_install: | $(DL_DIR) $(TOOLS_DIR) +uncrustify_install: UNCRUSTIFY_URL := http://downloads.sourceforge.net/project/uncrustify/uncrustify/uncrustify-0.61/uncrustify-0.61.tar.gz +uncrustify_install: UNCRUSTIFY_FILE := uncrustify-0.61.tar.gz +uncrustify_install: UNCRUSTIFY_OPTIONS := prefix=$(UNCRUSTIFY_DIR) +uncrustify_install: uncrustify_clean +ifneq ($(OSFAMILY), windows) + @echo " DOWNLOAD $(UNCRUSTIFY_URL)" + $(V1) curl -L -k -o "$(DL_DIR)/$(UNCRUSTIFY_FILE)" "$(UNCRUSTIFY_URL)" +endif + # extract the src + @echo " EXTRACT $(UNCRUSTIFY_FILE)" + $(V1) tar -C $(TOOLS_DIR) -xf "$(DL_DIR)/$(UNCRUSTIFY_FILE)" + + @echo " BUILD $(UNCRUSTIFY_DIR)" + $(V1) ( \ + cd $(UNCRUSTIFY_DIR) ; \ + ./configure --prefix="$(UNCRUSTIFY_DIR)" ; \ + $(MAKE) ; \ + $(MAKE) install ; \ + ) + # delete the extracted source when we're done + $(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)" + +.PHONY: uncrustify_clean +uncrustify_clean: + @echo " CLEAN $(UNCRUSTIFY_DIR)" + $(V1) [ ! -d "$(UNCRUSTIFY_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_DIR)" + @echo " CLEAN $(UNCRUSTIFY_BUILD_DIR)" + $(V1) [ ! -d "$(UNCRUSTIFY_BUILD_DIR)" ] || $(RM) -r "$(UNCRUSTIFY_BUILD_DIR)" + +# ZIP download URL +zip_install: ZIP_URL := http://pkgs.fedoraproject.org/repo/pkgs/zip/zip30.tar.gz/7b74551e63f8ee6aab6fbc86676c0d37/zip30.tar.gz + +zip_install: ZIP_FILE := $(notdir $(ZIP_URL)) + +ZIP_DIR = $(TOOLS_DIR)/zip30 + +# order-only prereq on directory existance: +zip_install : | $(DL_DIR) $(TOOLS_DIR) +zip_install: zip_clean + $(V1) curl -L -k -o "$(DL_DIR)/$(ZIP_FILE)" "$(ZIP_URL)" + $(V1) tar --force-local -C $(TOOLS_DIR) -xzf "$(DL_DIR)/$(ZIP_FILE)" +ifneq ($(OSFAMILY), windows) + $(V1) cd "$(ZIP_DIR)" && $(MAKE) -f unix/Makefile generic_gcc +else + $(V1) cd "$(ZIP_DIR)" && $(MAKE) -f win32/makefile.gcc +endif + +.PHONY: zip_clean +zip_clean: + $(V1) [ ! -d "$(ZIP_DIR)" ] || $(RM) -rf $(ZIP_DIR) + +############################## +# +# Set up paths to tools +# +############################## + +ifeq ($(shell [ -d "$(ARM_SDK_DIR)" ] && echo "exists"), exists) + ARM_SDK_PREFIX := $(ARM_SDK_DIR)/bin/arm-none-eabi- +else ifeq (,$(findstring _install,$(MAKECMDGOALS))) + GCC_VERSION = $(shell arm-none-eabi-gcc -dumpversion) + ifeq ($(GCC_VERSION),) + $(error **ERROR** arm-none-eabi-gcc not in the PATH. Run 'make arm_sdk_install' to install automatically in the tools folder of this repo) + else ifneq ($(GCC_VERSION), $(GCC_REQUIRED_VERSION)) + $(error **ERROR** your arm-none-eabi-gcc is '$(GCC_VERSION)', but '$(GCC_REQUIRED_VERSION)' is expected. Override with 'GCC_REQUIRED_VERSION' in make/local.mk or run 'make arm_sdk_install' to install the right version automatically in the tools folder of this repo) + endif + + # ARM tookchain is in the path, and the version is what's required. + ARM_SDK_PREFIX ?= arm-none-eabi- +endif + +ifeq ($(shell [ -d "$(ZIP_DIR)" ] && echo "exists"), exists) + export ZIPBIN := $(ZIP_DIR)/zip +else + export ZIPBIN := zip +endif + +ifeq ($(shell [ -d "$(OPENOCD_DIR)" ] && echo "exists"), exists) + OPENOCD := $(OPENOCD_DIR)/bin/openocd +else + # not installed, hope it's in the path... + OPENOCD ?= openocd +endif + +ifeq ($(shell [ -d "$(UNCRUSTIFY_DIR)" ] && echo "exists"), exists) + UNCRUSTIFY := $(UNCRUSTIFY_DIR)/bin/uncrustify +else + # not installed, hope it's in the path... + UNCRUSTIFY ?= uncrustify +endif + +# Google Breakpad +DUMP_SYMBOLS_TOOL := $(TOOLS_DIR)/breakpad/$(OSFAMILY)-$(ARCHFAMILY)/dump_syms +BREAKPAD_URL := http://dronin.tracer.nz/tools/breakpad.zip +BREAKPAD_DL_FILE := $(DL_DIR)/$(notdir $(BREAKPAD_URL)) +BREAKPAD_DIR := $(TOOLS_DIR)/breakpad + +.PHONY: breakpad_install +breakpad_install: | $(DL_DIR) $(TOOLS_DIR) +breakpad_install: breakpad_clean + @echo " DOWNLOAD $(BREAKPAD_URL)" + $(V1) $(V1) curl -L -k -z "$(BREAKPAD_DL_FILE)" -o "$(BREAKPAD_DL_FILE)" "$(BREAKPAD_URL)" + @echo " EXTRACT $(notdir $(BREAKPAD_DL_FILE))" + $(V1) mkdir -p "$(BREAKPAD_DIR)" + $(V1) unzip -q -d $(BREAKPAD_DIR) "$(BREAKPAD_DL_FILE)" +ifeq ($(OSFAMILY), windows) + $(V1) ln -s "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-i686" "$(TOOLS_DIR)/breakpad/$(OSFAMILY)-x86_64" +endif + +.PHONY: breakpad_clean +breakpad_clean: + @echo " CLEAN $(BREAKPAD_DIR)" + $(V1) [ ! -d "$(BREAKPAD_DIR)" ] || $(RM) -rf $(BREAKPAD_DIR) + @echo " CLEAN $(BREAKPAD_DL_FILE)" + $(V1) $(RM) -f $(BREAKPAD_DL_FILE) diff --git a/makefile b/makefile index 0c54a2c..c88fad4 100644 --- a/makefile +++ b/makefile @@ -33,8 +33,6 @@ CFLAGS = $(MCU) $(VALUES) $(INCLUDES) -O2 -Wall -fdata-sections -ffunction-secti CFLAGS += -DUSE_$(TARGET) CFLAGS += -MMD -MP -MF $(@:%.bin=%.d) -ARM_SDK_PREFIX ?= arm-none-eabi- - # Targets by signal input pin: # PB4: iFlight # PA2: all others @@ -43,6 +41,20 @@ TARGET_PREFIX := BOOTLOADER_ VERSION := $(shell grep "#define BOOTLOADER_VERSION" Core/Src/main.c | awk '{print $$3}' ) +# Working directories +ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) + +# Build tools, so we all share the same versions +# import macros common to all supported build systems +include $(ROOT)/make/system-id.mk + +# configure some directories that are relative to wherever ROOT_DIR is located +ifndef TOOLS_DIR +TOOLS_DIR := $(ROOT)/tools +endif +BUILD_DIR := $(ROOT)/build +DL_DIR := $(ROOT)/downloads + .PHONY : clean all version all : $(TARGETS) clean : @@ -57,3 +69,13 @@ $(TARGETS:%=$(TARGET_PREFIX)%.bin) : clean $(OBJ) $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET_PREFIX)$(TARGET)_$(VERSION).elf $(OBJ) $(CP) -O binary $(TARGET_PREFIX)$(TARGET)_$(VERSION).elf $(TARGET_PREFIX)$(TARGET)_$(VERSION).bin $(CP) $(TARGET_PREFIX)$(TARGET)_$(VERSION).elf -O ihex $(TARGET_PREFIX)$(TARGET)_$(VERSION).hex + +# mkdirs +$(DL_DIR): + mkdir -p $@ + +$(TOOLS_DIR): + mkdir -p $@ + +# include the tools makefile +include $(ROOT)/make/tools.mk