207 lines
6.6 KiB
Makefile
207 lines
6.6 KiB
Makefile
## This library is free software: you can redistribute it and/or modify
|
|
## it under the terms of the GNU Lesser General Public License as published by
|
|
## the Free Software Foundation, either version 3 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## This library is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU Lesser General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU Lesser General Public License
|
|
## along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
##
|
|
|
|
## the make file provide rule to compile and flash firmware for STM32F1 micro-controllers
|
|
## it uses libopencm3 and STM32duino-bootloader
|
|
|
|
# be silent per default, but 'make V=1' will show all compiler calls.
|
|
ifneq ($(V),1)
|
|
Q := @
|
|
NULL := 1> /dev/null 2> /dev/null
|
|
endif
|
|
|
|
# the final binary name (without extension)
|
|
BINARY = firmware
|
|
|
|
# which development board is used
|
|
# supported are: SYSTEM_BOARD, MAPLE_MINI, BLUE_PILL
|
|
BOARD = BLUE_PILL
|
|
|
|
# source files
|
|
CSRC = $(wildcard *.c)
|
|
CHDR = $(wildcard *.h)
|
|
OBJ = $(patsubst %.c,%.o,$(CSRC))
|
|
# figure out based on the includes which library files are used in the main CSRC files
|
|
DEPENDENCIES = $(patsubst %.c,%.inc,$(CSRC))
|
|
|
|
# my library collection
|
|
LIB = lib
|
|
# the library files to use
|
|
# this will be populated using includes based DEPENDENCIES
|
|
LIB_CSRC =
|
|
LIB_CHDR = $(patsubst %.c,%.h,$(LIB_CSRC))
|
|
LIB_OBJ = $(patsubst %.c,%.o,$(LIB_CSRC))
|
|
# populates LIB_CSRC based on the library files used
|
|
-include $(DEPENDENCIES)
|
|
|
|
# executables
|
|
PREFIX ?= arm-none-eabi
|
|
CC := $(PREFIX)-gcc
|
|
CXX := $(PREFIX)-g++
|
|
LD := $(PREFIX)-gcc
|
|
AR := $(PREFIX)-ar
|
|
AS := $(PREFIX)-as
|
|
OBJCOPY := $(PREFIX)-objcopy
|
|
OBJDUMP := $(PREFIX)-objdump
|
|
GDB := $(PREFIX)-gdb
|
|
|
|
# opencm3 libraries
|
|
OPENCM3_DIR := libopencm3
|
|
INCLUDE_DIR = $(OPENCM3_DIR)/include
|
|
LIB_DIR = $(OPENCM3_DIR)/lib
|
|
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
|
|
|
|
# verify if libopencm3 has been downloaded
|
|
OPENCM3_DIR_EXISTS = $(shell [ -d $(OPENCM3_DIR) ] && echo 1 || echo 0 )
|
|
ifeq ($(OPENCM3_DIR_EXISTS), 0)
|
|
$(info run "git submodule init" and "git submodule update" before runnig make)
|
|
$(error libopencm3 repository is not initialized)
|
|
endif
|
|
|
|
# device flags
|
|
DEFS += -DSTM32F1 -D$(BOARD)
|
|
|
|
# C flags
|
|
CFLAGS += -Os -g
|
|
CFLAGS += -std=c99 -Wpedantic -Wall -Werror -Wundef -Wextra -Wshadow -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes
|
|
CFLAGS += -fno-common -ffunction-sections -fdata-sections
|
|
CFLAGS += -I. -I$(INCLUDE_DIR) $(patsubst %,-I%,$(LIB))
|
|
CFLAGS += $(DEFS)
|
|
|
|
# linker script
|
|
ifeq ($(BOARD),SYSTEM_BOARD)
|
|
LDSCRIPT = stm32f103x8-dfu.ld
|
|
else ifeq ($(BOARD),BLUE_PILL)
|
|
LDSCRIPT = stm32f103x8-dfu.ld
|
|
else ifeq ($(BOARD),MAPLE_MINI)
|
|
LDSCRIPT = stm32f103xb-dfu.ld
|
|
endif
|
|
|
|
# linker flags
|
|
LDFLAGS += --static -nostartfiles
|
|
LDFLAGS += -L$(LIB_DIR)
|
|
LDFLAGS += -I. $(patsubst %,-I%,$(LIB))
|
|
LDFLAGS += -T$(LDSCRIPT)
|
|
LDFLAGS += -Wl,-Map=$(*).map
|
|
LDFLAGS += -Wl,--gc-sections
|
|
ifeq ($(V),99)
|
|
LDFLAGS += -Wl,--print-gc-sections
|
|
endif
|
|
|
|
# used libraries
|
|
LIBNAME = opencm3_stm32f1
|
|
LDLIBS += -lm -l$(LIBNAME)
|
|
LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
|
|
|
|
# device specific flags
|
|
FP_FLAGS ?= -msoft-float
|
|
ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd
|
|
|
|
# OpenOCD configuration
|
|
OOCD ?= openocd
|
|
OOCD_INTERFACE ?= stlink-v2
|
|
OOCD_TARGET ?= stm32f1x
|
|
|
|
# which USB CDC ACM port is used bu the device, so we can reset it
|
|
ACMPORT = /dev/ttyACM0
|
|
ACMPORT_EXISTS = $(shell [ -e $(ACMPORT) ] && echo 1 || echo 0 )
|
|
|
|
# board specific USB DFU bootloader
|
|
BOOTLOADERS = STM32duino-bootloader
|
|
ifeq ($(BOARD),SYSTEM_BOARD)
|
|
BOOTLOADER = $(BOOTLOADERS)/STM32F1/binaries/generic_boot20_pa1.bin
|
|
else ifeq ($(BOARD),BLUE_PILL)
|
|
BOOTLOADER = $(BOOTLOADERS)/STM32F1/binaries/generic_boot20_pc13.bin
|
|
else ifeq ($(BOARD),MAPLE_MINI)
|
|
BOOTLOADER = $(BOOTLOADERS)/STM32F1/binaries/maple_mini_boot20.bin
|
|
endif
|
|
|
|
# verify if STM32duino-bootloader has been downloaded
|
|
BOOTLOADER_EXISTS = $(shell [ -f $(BOOTLOADER) ] && echo 1 || echo 0 )
|
|
ifeq ($(BOOTLOADER_EXISTS), 0)
|
|
$(info run "git submodule init" and "git submodule update" before runnig make)
|
|
$(error STM32duino-bootloader repository is not initialized)
|
|
endif
|
|
|
|
# compile target rules
|
|
all: elf
|
|
|
|
elf: $(BINARY).elf
|
|
bin: $(BINARY).bin
|
|
hex: $(BINARY).hex
|
|
srec: $(BINARY).srec
|
|
list: $(BINARY).list
|
|
|
|
%.bin %.hex %.srec: %.elf
|
|
$(Q)$(OBJCOPY) -Osrec $(<) $(@)
|
|
|
|
%.map %.list: %.elf
|
|
$(Q)$(OBJDUMP) -S $(<) > $(@)
|
|
|
|
%.elf: $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a $(OBJ) $(LIB_OBJ)
|
|
$(info compiling $(@))
|
|
$(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJ) $(LIB_OBJ) $(LDLIBS) -o $(@)
|
|
$(Q)size $(@)
|
|
|
|
%.o: %.c $(CHDR) $(LIB_CHDR)
|
|
$(Q)$(CC) $(CFLAGS) $(ARCH_FLAGS) -o $(@) -c $(<)
|
|
|
|
# generate dependencies
|
|
%.d: %.c
|
|
@# check which libraries are used
|
|
$(Q)$(CC) $(CFLAGS) $(ARCH_FLAGS) -MM -MF $(@) -o /dev/null -c $(<)
|
|
|
|
# figure out which library source files are used for later inclusion
|
|
%.inc: %.d
|
|
$(Q)grep -o -e " ${LIB}\/[^ ]*\.h" $(<) | sed -e 's/\.h$$/.c/g' -e 's/^/LIB_CSRC +=/' > $(@)
|
|
|
|
# doxygen documentation
|
|
doc: Doxyfile README.md $(CSRC) $(CHDR) $(LIB_CSRC) $(LIB_CHDR)
|
|
$(Q)doxygen $(<)
|
|
|
|
clean:
|
|
$(Q)$(RM) $(BINARY).elf $(BINARY).bin $(BINARY).hex $(BINARY).map $(OBJ) $(LIB_OBJ) $(LIB)/*.o $(DEPENDENCIES)
|
|
|
|
# make libopencm3 if not done
|
|
$(LIB_DIR)/lib$(LIBNAME).a:
|
|
$(info compiling libopencm3 library)
|
|
$(Q)$(MAKE) -C $(OPENCM3_DIR)
|
|
|
|
bootloader: $(BOOTLOADER)
|
|
$(info flashing USB DFU bootloader $(<))
|
|
$(Q)$(OOCD) --file interface/$(OOCD_INTERFACE).cfg --file target/$(OOCD_TARGET).cfg --command "init" --command "reset init" --command "flash write_image erase $(<) 0x08000000" --command "reset" --command "shutdown" $(NULL)
|
|
|
|
flash: flash-dfu
|
|
|
|
flash-swd: $(BINARY).hex
|
|
$(info flashing $(<) using SWD)
|
|
$(Q)$(OOCD) --file interface/$(OOCD_INTERFACE).cfg --file target/$(OOCD_TARGET).cfg --command "init" --command "reset init" --command "flash write_image erase $(<)" --command "reset" --command "shutdown" $(NULL)
|
|
|
|
# reset device by setting the data width to 5 bis on the USB CDC ACM port
|
|
reset:
|
|
ifeq ($(ACMPORT_EXISTS), 1)
|
|
$(Q)stty --file $(ACMPORT) 115200 raw cs5
|
|
$(Q)sleep 0.5
|
|
endif
|
|
|
|
flash-dfu: $(BINARY).bin reset
|
|
$(info flashing $(<) using DFU)
|
|
$(Q)dfu-util --device 1eaf:0003 --cfg 1 --intf 0 --alt 2 --reset --download $(<) $(NULL)
|
|
|
|
# debug using jtag (openOCB+GDB)
|
|
debug: $(BINARY).elf
|
|
$(Q)$(GDB) --eval-command="target remote | $(OOCD) --file interface/stlink-v2.cfg --file target/stm32f1x.cfg --command \"gdb_port pipe; log_output /dev/null; init\"" --eval-command="monitor reset halt" --eval-command="load" --eval-command="monitor reset init" $(<)
|
|
|
|
.PHONY: clean elf bin hex srec list libraries bootloader $(BOOTLOADER) flash flash-swd reset flash-dfu
|