123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- ######################################################
- # AVR make library #
- # Copyright (c) 2015-2022 Michael Buesch <m@bues.ch> #
- # #
- # Licensed under the Apache License version 2.0 #
- # or the MIT license, at your option. #
- # SPDX-License-Identifier: Apache-2.0 OR MIT #
- ######################################################
- ifeq ($(NAME),)
- $(error NAME not defined)
- endif
- ifeq ($(SRCS),)
- $(error SRCS not defined)
- endif
- ifeq ($(F_CPU),)
- $(error F_CPU not defined)
- endif
- ifeq ($(GCC_ARCH),)
- $(error GCC_ARCH not defined)
- endif
- ifeq ($(AVRDUDE_ARCH),)
- $(error AVRDUDE_ARCH not defined)
- endif
- _uppercase = $(shell echo $(1) | tr a-z A-Z)
- _lowercase = $(shell echo $(1) | tr A-Z a-z)
- _streq = $(and $(filter 1,$(words $2)),$(filter $1,$(firstword $2)))
- # The toolchain definitions
- CC := avr-gcc
- OBJCOPY := avr-objcopy
- OBJDUMP := avr-objdump
- SIZE := avr-size
- MKDIR := mkdir
- MV := mv
- RM := rm
- CP := cp
- SED := sed
- ECHO := echo
- GREP := grep
- TRUE := true
- TEST := test
- AVRDUDE := avrdude
- MYSMARTUSB := avrmakelib/mysmartusb.py
- DOXYGEN := doxygen
- PYTHON3 := python3
- SPARSE := sparse
- # Verbose build: make V=1
- V := @
- # Sparsechecker build: make C=1
- C := $(shell $(SPARSE) --help >/dev/null 2>&1 && $(ECHO) 1 || $(ECHO) 0)
- # Debug build: make DEBUG=1
- DEBUG := 0
- # Optimize flag: make O=0/1/2/3/s
- O := s
- # Link time optimization: make LTO=1
- LTO := 1
- Q := $(V:1=)
- QUIET_CC = $(Q:@=@$(ECHO) ' CC '$@;)$(CC)
- QUIET_DEPEND = $(Q:@=@$(ECHO) ' DEPEND '$@;)$(CC)
- QUIET_OBJCOPY = $(Q:@=@$(ECHO) ' OBJCOPY '$@;)$(OBJCOPY)
- QUIET_OBJDUMP = $(Q:@=@$(ECHO) ' OBJDUMP '$@;)$(OBJDUMP)
- QUIET_SIZE = $(Q:@=@$(ECHO) ' SIZE '$@;)$(SIZE)
- QUIET_PYTHON3 = $(Q:@=@$(ECHO) ' PYTHON3 '$@;)$(PYTHON3)
- QUIET_RM = $(Q:@=@$(ECHO) ' RM '$@;)$(RM)
- QUIET_SED = $(Q:@=@$(ECHO) ' SED '$@;)$(SED)
- ifeq ($(C),1)
- QUIET_SPARSE = $(Q:@=@$(ECHO) ' SPARSE '$@;)$(SPARSE)
- else
- QUIET_SPARSE = @$(TRUE)
- endif
- BIN := $(NAME).bin
- HEX := $(NAME).hex
- MAP := $(NAME).map
- DASM := $(NAME).dasm
- EEP := $(NAME).eep.hex
- BOOT_BIN := $(NAME).bootloader.bin
- BOOT_HEX := $(NAME).bootloader.hex
- BOOT_MAP := $(NAME).bootloader.map
- BOOT_DASM := $(NAME).bootloader.dasm
- OBJ_DIR := obj
- DEP_DIR := dep
- BOOT_OBJ_DIR := obj-boot
- BOOT_DEP_DIR := dep-boot
- FUNC_STACK_LIMIT ?= 128
- WARN_CFLAGS := -Wall \
- -Wextra \
- -Wno-unused-parameter \
- -Wswitch-enum \
- -Wsuggest-attribute=noreturn \
- -Wundef \
- -Wpointer-arith \
- $(if $(FUNC_STACK_LIMIT),-Wstack-usage=$(FUNC_STACK_LIMIT)) \
- -Wcast-qual \
- -Wlogical-op \
- -Wshadow \
- -Wconversion
- OPTIMIZE_CFLAGS := -O$(O) \
- -maccumulate-args \
- -mcall-prologues \
- -mrelax \
- -mstrict-X \
- -fno-inline-small-functions \
- -fno-move-loop-invariants \
- -fno-split-wide-types \
- -fshort-enums \
- $(if $(call _streq,$(LTO),1),-flto=jobserver -fuse-linker-plugin -fno-fat-lto-objects,-fno-lto)
- DEFINE_CFLAGS := -DF_CPU=$(F_CPU) \
- $(if $(BOOT_OFFSET),-DBOOT_OFFSET=$(BOOT_OFFSET)) \
- $(if $(DEBUG),-DDEBUG=$(DEBUG))
- MAIN_CFLAGS := -mmcu=$(GCC_ARCH) \
- -std=gnu11 \
- -g \
- -ffunction-sections \
- -fdata-sections \
- $(OPTIMIZE_CFLAGS) \
- $(WARN_CFLAGS) \
- $(DEFINE_CFLAGS)
- MAIN_LDFLAGS := -Wl,-gc-sections \
- $(if $(call _streq,$(LTO),1),,-fwhole-program)
- INSTRUMENT_CFLAGS := -DINSTRUMENT_FUNCTIONS=1 \
- -finstrument-functions \
- -finstrument-functions-exclude-file-list=.h
- MAIN_SPARSEFLAGS := -gcc-base-dir=/usr/lib/avr \
- -I/usr/lib/avr/include \
- -D__STDC_HOSTED__=1 \
- -D__AVR_ARCH__=5 \
- -D__AVR_$(subst TINY,tiny,$(subst MEGA,mega,$(call _uppercase,$(GCC_ARCH))))__=1 \
- -Wsparse-all
- CFLAGS := $(MAIN_CFLAGS) \
- $(if $(INSTRUMENT_FUNC),$(INSTRUMENT_CFLAGS)) \
- $(CFLAGS) \
- -include sparse.h
- BOOT_CFLAGS := $(MAIN_CFLAGS) -DBOOTLOADER \
- $(if $(BOOT_INSTRUMENT_FUNC),$(INSTRUMENT_CFLAGS)) \
- $(BOOT_CFLAGS) \
- -include sparse.h
- LDFLAGS := $(MAIN_LDFLAGS) \
- -Wl,-Map,$(MAP) \
- $(LDFLAGS)
- BOOT_LDFLAGS := $(MAIN_LDFLAGS) \
- -Wl,--section-start=.text=$(BOOT_OFFSET) \
- -Wl,-Map,$(BOOT_MAP) \
- $(BOOT_LDFLAGS)
- SPARSEFLAGS := $(subst gnu11,gnu99,$(CFLAGS)) \
- $(MAIN_SPARSEFLAGS) $(SPARSEFLAGS)
- BOOT_SPARSEFLAGS := $(subst gnu11,gnu99,$(BOOT_CFLAGS)) \
- $(MAIN_SPARSEFLAGS) $(BOOT_SPARSEFLAGS)
- .SUFFIXES:
- .DEFAULT_GOAL := all
- # Programmer parameters
- AVRDUDE_SPEED ?= 1
- AVRDUDE_SLOW_SPEED ?= 200
- ifeq ($(PROGRAMMER),mysmartusb)
- AVRDUDE_PROGRAMMER := avr910
- else
- AVRDUDE_PROGRAMMER := $(PROGRAMMER)
- endif
- ifeq ($(PROGPORT),)
- ifeq ($(AVRDUDE_PROGRAMMER),avr910)
- PROGPORT := /dev/ttyUSB0
- endif
- ifeq ($(AVRDUDE_PROGRAMMER),avrisp2)
- PROGPORT := usb
- endif
- ifeq ($(AVRDUDE_PROGRAMMER),usbasp)
- PROGPORT := usb
- endif
- ifeq ($(AVRDUDE_PROGRAMMER),usbasp-clone)
- PROGPORT := usb
- endif
- endif
- define _programmer_cmd_pwrcycle
- $(if $(filter mysmartusb,$(PROGRAMMER)), \
- $(MYSMARTUSB) -p0 $(PROGPORT) && \
- sleep 1 && \
- $(MYSMARTUSB) -p1 $(PROGPORT) \
- )
- endef
- define _programmer_cmd_prog_enter
- $(if $(filter mysmartusb,$(PROGRAMMER)), \
- $(MYSMARTUSB) -mp $(PROGPORT) \
- )
- endef
- define _programmer_cmd_prog_leave
- $(if $(filter mysmartusb,$(PROGRAMMER)), \
- $(MYSMARTUSB) -md $(PROGPORT) \
- )
- endef
- DEPS = $(sort $(patsubst %.c,$(2)/%.d,$(1)))
- OBJS = $(sort $(patsubst %.c,$(2)/%.o,$(1)))
- # Generate dependencies
- $(call DEPS,$(SRCS),$(DEP_DIR)): $(DEP_DIR)/%.d: %.c
- @$(MKDIR) -p $(dir $@)
- @$(MKDIR) -p $(OBJ_DIR)
- $(QUIET_DEPEND) -o $@.tmp -MM $(if $(GEN_SRCS),-MG) -MT "$@ $(patsubst $(DEP_DIR)/%.d,$(OBJ_DIR)/%.o,$@)" $(CFLAGS) $<
- @$(MV) -f $@.tmp $@
- ifneq ($(BOOT_SRCS),)
- $(call DEPS,$(BOOT_SRCS),$(BOOT_DEP_DIR)): $(BOOT_DEP_DIR)/%.d: %.c
- @$(MKDIR) -p $(dir $@)
- @$(MKDIR) -p $(BOOT_OBJ_DIR)
- $(QUIET_DEPEND) -o $@.tmp -MM $(if $(BOOT_GEN_SRCS),-MG) -MT "$@ $(patsubst $(BOOT_DEP_DIR)/%.d,$(BOOT_OBJ_DIR)/%.o,$@)" $(BOOT_CFLAGS) $<
- @$(MV) -f $@.tmp $@
- endif
- -include $(call DEPS,$(SRCS),$(DEP_DIR))
- ifneq ($(BOOT_SRCS),)
- -include $(call DEPS,$(BOOT_SRCS),$(BOOT_DEP_DIR))
- endif
- # Generate object files
- $(call OBJS,$(SRCS),$(OBJ_DIR)): $(OBJ_DIR)/%.o: %.c
- @$(MKDIR) -p $(dir $@)
- $(QUIET_CC) -o $@ -c $(CFLAGS) $<
- $(QUIET_SPARSE) $(SPARSEFLAGS) $<
- ifneq ($(BOOT_SRCS),)
- $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR)): $(BOOT_OBJ_DIR)/%.o: %.c
- @$(MKDIR) -p $(dir $@)
- $(QUIET_CC) -o $@ -c $(BOOT_CFLAGS) $<
- $(QUIET_SPARSE) $(BOOT_SPARSEFLAGS) $<
- endif
- all: $(HEX) $(if $(BOOT_SRCS),$(BOOT_HEX))
- %.s: %.c
- $(QUIET_CC) $(CFLAGS) -fno-lto -S $*.c
- $(BIN): $(call OBJS,$(SRCS),$(OBJ_DIR))
- +$(QUIET_CC) $(CFLAGS) -o $(BIN) $(call OBJS,$(SRCS),$(OBJ_DIR)) $(LDFLAGS)
- +$(QUIET_OBJDUMP) -S $(BIN) > $(DASM)
- $(BOOT_BIN): $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR))
- +$(QUIET_CC) $(BOOT_CFLAGS) -o $(BOOT_BIN) $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR)) $(BOOT_LDFLAGS)
- +$(QUIET_OBJDUMP) -S $(BOOT_BIN) > $(BOOT_DASM)
- $(HEX): $(BIN)
- $(QUIET_OBJCOPY) -R.eeprom -O ihex $(BIN) $(HEX)
- @$(OBJDUMP) -h $(BIN) | $(GREP) -qe .eeprom && \
- $(OBJCOPY) -j.eeprom --set-section-flags=.eeprom="alloc,load" \
- --change-section-lma .eeprom=0 -O ihex $(BIN) $(EEP) \
- || $(TRUE)
- $(QUIET_SIZE) --format=SysV $(BIN)
- $(BOOT_HEX): $(BOOT_BIN)
- $(QUIET_OBJCOPY) -R.eeprom -O ihex $(BOOT_BIN) $(BOOT_HEX)
- $(QUIET_SIZE) --format=SysV $(BOOT_BIN)
- define _avrdude_interactive
- $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
- -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) -t
- endef
- define _avrdude_reset
- $(AVRDUDE) -B $(AVRDUDE_SLOW_SPEED) -p $(AVRDUDE_ARCH) \
- -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
- -U signature:r:/dev/null:i -q -q
- endef
- define _avrdude_write_flash
- $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
- -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
- $(if $(BOOT_SRCS),-U flash:w:$(BOOT_HEX)) \
- -U flash:w:$(HEX)
- endef
- define _avrdude_write_eeprom
- $(TEST) -r $(EEP) && ( \
- $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
- -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
- -U eeprom:w:$(EEP) \
- ) || $(TRUE)
- endef
- define _avrdude_write_fuse
- $(AVRDUDE) -B $(AVRDUDE_SLOW_SPEED) -p $(AVRDUDE_ARCH) \
- -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) -q -q \
- -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m $(if $(EFUSE),-U efuse:w:$(EFUSE):m)
- endef
- write_flash: all
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_write_flash)
- $(call _programmer_cmd_pwrcycle)
- $(call _programmer_cmd_prog_leave)
- writeflash: write_flash
- write_eeprom: all
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_write_eeprom)
- $(call _programmer_cmd_pwrcycle)
- $(call _programmer_cmd_prog_leave)
- writeeeprom: write_eeprom
- write_mem: all
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_write_flash)
- $(call _avrdude_write_eeprom)
- $(call _programmer_cmd_pwrcycle)
- $(call _programmer_cmd_prog_leave)
- writemem: write_mem
- install: write_mem
- write_fuses:
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_write_fuse)
- $(call _programmer_cmd_pwrcycle)
- $(call _programmer_cmd_prog_leave)
- write_fuse: write_fuses
- writefuse: write_fuses
- writefuses: write_fuses
- print_fuses:
- @$(if $(LFUSE),echo "LFUSE (low fuse) = $(LFUSE)",$(TRUE))
- @$(if $(HFUSE),echo "HFUSE (high fuse) = $(HFUSE)",$(TRUE))
- @$(if $(EFUSE),echo "EFUSE (extended fuse) = $(EFUSE)",$(TRUE))
- printfuses: print_fuses
- reset:
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_reset)
- $(call _programmer_cmd_pwrcycle)
- avrdude:
- $(call _programmer_cmd_prog_enter)
- $(call _avrdude_interactive)
- $(call _programmer_cmd_pwrcycle)
- $(call _programmer_cmd_prog_leave)
- doxygen:
- $(DOXYGEN) Doxyfile
- clean:
- -$(QUIET_RM) -rf \
- $(OBJ_DIR) $(DEP_DIR) \
- $(BOOT_OBJ_DIR) $(BOOT_DEP_DIR) \
- $(BIN) $(BOOT_BIN) \
- $(MAP) $(BOOT_MAP) \
- $(DASM) $(BOOT_DASM) \
- *.pyc *.pyo __pycache__ \
- $(GEN_SRCS) $(BOOT_GEN_SRCS) \
- $(CLEAN_FILES)
- distclean: clean
- -$(QUIET_RM) -f \
- $(HEX) $(BOOT_HEX) \
- $(EEP) \
- *.s \
- $(DISTCLEAN_FILES)
|