avrmakelib.mk 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. ######################################################
  2. # AVR make library #
  3. # Copyright (c) 2015-2020 Michael Buesch <m@bues.ch> #
  4. # Version 1.12 #
  5. ######################################################
  6. ifeq ($(NAME),)
  7. $(error NAME not defined)
  8. endif
  9. ifeq ($(SRCS),)
  10. $(error SRCS not defined)
  11. endif
  12. ifeq ($(F_CPU),)
  13. $(error F_CPU not defined)
  14. endif
  15. ifeq ($(GCC_ARCH),)
  16. $(error GCC_ARCH not defined)
  17. endif
  18. ifeq ($(AVRDUDE_ARCH),)
  19. $(error AVRDUDE_ARCH not defined)
  20. endif
  21. _uppercase = $(shell echo $(1) | tr a-z A-Z)
  22. _lowercase = $(shell echo $(1) | tr A-Z a-z)
  23. _streq = $(and $(filter 1,$(words $2)),$(filter $1,$(firstword $2)))
  24. # The toolchain definitions
  25. CC := avr-gcc
  26. OBJCOPY := avr-objcopy
  27. OBJDUMP := avr-objdump
  28. SIZE := avr-size
  29. MKDIR := mkdir
  30. MV := mv
  31. RM := rm
  32. CP := cp
  33. SED := sed
  34. ECHO := echo
  35. GREP := grep
  36. TRUE := true
  37. TEST := test
  38. AVRDUDE := avrdude
  39. MYSMARTUSB := mysmartusb.py
  40. DOXYGEN := doxygen
  41. PYTHON2 := python2
  42. PYTHON3 := python3
  43. SPARSE := sparse
  44. # Verbose build: make V=1
  45. V := @
  46. # Sparsechecker build: make C=1
  47. C := $(shell $(SPARSE) --help >/dev/null 2>&1 && $(ECHO) 1 || $(ECHO) 0)
  48. # Debug build: make DEBUG=1
  49. DEBUG := 0
  50. # Optimize flag: make O=0/1/2/3/s
  51. O := s
  52. # Link time optimization: make LTO=1
  53. LTO := 1
  54. Q := $(V:1=)
  55. QUIET_CC = $(Q:@=@$(ECHO) ' CC '$@;)$(CC)
  56. QUIET_DEPEND = $(Q:@=@$(ECHO) ' DEPEND '$@;)$(CC)
  57. QUIET_OBJCOPY = $(Q:@=@$(ECHO) ' OBJCOPY '$@;)$(OBJCOPY)
  58. QUIET_OBJDUMP = $(Q:@=@$(ECHO) ' OBJDUMP '$@;)$(OBJDUMP)
  59. QUIET_SIZE = $(Q:@=@$(ECHO) ' SIZE '$@;)$(SIZE)
  60. QUIET_PYTHON2 = $(Q:@=@$(ECHO) ' PYTHON2 '$@;)$(PYTHON2)
  61. QUIET_PYTHON3 = $(Q:@=@$(ECHO) ' PYTHON3 '$@;)$(PYTHON3)
  62. QUIET_RM = $(Q:@=@$(ECHO) ' RM '$@;)$(RM)
  63. QUIET_SED = $(Q:@=@$(ECHO) ' SED '$@;)$(SED)
  64. ifeq ($(C),1)
  65. QUIET_SPARSE = $(Q:@=@$(ECHO) ' SPARSE '$@;)$(SPARSE)
  66. else
  67. QUIET_SPARSE = @$(TRUE)
  68. endif
  69. BIN := $(NAME).bin
  70. HEX := $(NAME).hex
  71. MAP := $(NAME).map
  72. DASM := $(NAME).dasm
  73. EEP := $(NAME).eep.hex
  74. BOOT_BIN := $(NAME).bootloader.bin
  75. BOOT_HEX := $(NAME).bootloader.hex
  76. BOOT_MAP := $(NAME).bootloader.map
  77. BOOT_DASM := $(NAME).bootloader.dasm
  78. OBJ_DIR := obj
  79. DEP_DIR := dep
  80. BOOT_OBJ_DIR := obj-boot
  81. BOOT_DEP_DIR := dep-boot
  82. FUNC_STACK_LIMIT ?= 128
  83. WARN_CFLAGS := -Wall \
  84. -Wextra \
  85. -Wno-unused-parameter \
  86. -Wswitch-enum \
  87. -Wsuggest-attribute=noreturn \
  88. -Wundef \
  89. -Wpointer-arith \
  90. $(if $(FUNC_STACK_LIMIT),-Wstack-usage=$(FUNC_STACK_LIMIT)) \
  91. -Wcast-qual \
  92. -Wlogical-op \
  93. -Wshadow \
  94. -Wconversion
  95. OPTIMIZE_CFLAGS := -O$(O) \
  96. -maccumulate-args \
  97. -mcall-prologues \
  98. -mrelax \
  99. -mstrict-X \
  100. -fno-inline-small-functions \
  101. -fno-move-loop-invariants \
  102. -fno-split-wide-types \
  103. -fshort-enums \
  104. $(if $(call _streq,$(LTO),1),-flto=jobserver -fuse-linker-plugin -fno-fat-lto-objects,-fno-lto)
  105. DEFINE_CFLAGS := -DF_CPU=$(F_CPU) \
  106. $(if $(BOOT_OFFSET),-DBOOT_OFFSET=$(BOOT_OFFSET)) \
  107. $(if $(DEBUG),-DDEBUG=$(DEBUG))
  108. MAIN_CFLAGS := -mmcu=$(GCC_ARCH) \
  109. -std=gnu11 \
  110. -g \
  111. -ffunction-sections \
  112. -fdata-sections \
  113. $(OPTIMIZE_CFLAGS) \
  114. $(WARN_CFLAGS) \
  115. $(DEFINE_CFLAGS)
  116. MAIN_LDFLAGS := -Wl,-gc-sections \
  117. $(if $(call _streq,$(LTO),1),,-fwhole-program)
  118. INSTRUMENT_CFLAGS := -DINSTRUMENT_FUNCTIONS=1 \
  119. -finstrument-functions \
  120. -finstrument-functions-exclude-file-list=.h
  121. MAIN_SPARSEFLAGS := -gcc-base-dir=/usr/lib/avr \
  122. -I/usr/lib/avr/include \
  123. -D__STDC_HOSTED__=1 \
  124. -D__AVR_ARCH__=5 \
  125. -D__AVR_$(subst TINY,tiny,$(subst MEGA,mega,$(call _uppercase,$(GCC_ARCH))))__=1 \
  126. -Wsparse-all
  127. CFLAGS := $(MAIN_CFLAGS) \
  128. $(if $(INSTRUMENT_FUNC),$(INSTRUMENT_CFLAGS)) \
  129. $(CFLAGS) \
  130. -include sparse.h
  131. BOOT_CFLAGS := $(MAIN_CFLAGS) -DBOOTLOADER \
  132. $(if $(BOOT_INSTRUMENT_FUNC),$(INSTRUMENT_CFLAGS)) \
  133. $(BOOT_CFLAGS) \
  134. -include sparse.h
  135. LDFLAGS := $(MAIN_LDFLAGS) \
  136. -Wl,-Map,$(MAP) \
  137. $(LDFLAGS)
  138. BOOT_LDFLAGS := $(MAIN_LDFLAGS) \
  139. -Wl,--section-start=.text=$(BOOT_OFFSET) \
  140. -Wl,-Map,$(BOOT_MAP) \
  141. $(BOOT_LDFLAGS)
  142. SPARSEFLAGS := $(subst gnu11,gnu99,$(CFLAGS)) \
  143. $(MAIN_SPARSEFLAGS) $(SPARSEFLAGS)
  144. BOOT_SPARSEFLAGS := $(subst gnu11,gnu99,$(BOOT_CFLAGS)) \
  145. $(MAIN_SPARSEFLAGS) $(BOOT_SPARSEFLAGS)
  146. .SUFFIXES:
  147. .DEFAULT_GOAL := all
  148. # Programmer parameters
  149. AVRDUDE_SPEED ?= 1
  150. AVRDUDE_SLOW_SPEED ?= 200
  151. AVRDUDE_PROGRAMMER :=
  152. ifeq ($(PROGRAMMER),mysmartusb)
  153. AVRDUDE_PROGRAMMER := avr910
  154. PROGPORT := /dev/ttyUSB0
  155. endif
  156. ifeq ($(PROGRAMMER),avrisp2)
  157. AVRDUDE_PROGRAMMER := avrisp2
  158. PROGPORT := usb
  159. endif
  160. ifeq ($(AVRDUDE_PROGRAMMER),)
  161. $(error Invalid PROGRAMMER specified)
  162. endif
  163. define _programmer_cmd_pwrcycle
  164. $(if $(filter mysmartusb,$(PROGRAMMER)), \
  165. $(MYSMARTUSB) -p0 $(PROGPORT) && \
  166. sleep 1 && \
  167. $(MYSMARTUSB) -p1 $(PROGPORT) \
  168. )
  169. endef
  170. define _programmer_cmd_prog_enter
  171. $(if $(filter mysmartusb,$(PROGRAMMER)), \
  172. $(MYSMARTUSB) -mp $(PROGPORT) \
  173. )
  174. endef
  175. define _programmer_cmd_prog_leave
  176. $(if $(filter mysmartusb,$(PROGRAMMER)), \
  177. $(MYSMARTUSB) -md $(PROGPORT) \
  178. )
  179. endef
  180. DEPS = $(sort $(patsubst %.c,$(2)/%.d,$(1)))
  181. OBJS = $(sort $(patsubst %.c,$(2)/%.o,$(1)))
  182. # Generate dependencies
  183. $(call DEPS,$(SRCS),$(DEP_DIR)): $(DEP_DIR)/%.d: %.c
  184. @$(MKDIR) -p $(dir $@)
  185. @$(MKDIR) -p $(OBJ_DIR)
  186. $(QUIET_DEPEND) -o $@.tmp -MM $(if $(GEN_SRCS),-MG) -MT "$@ $(patsubst $(DEP_DIR)/%.d,$(OBJ_DIR)/%.o,$@)" $(CFLAGS) $<
  187. @$(MV) -f $@.tmp $@
  188. ifneq ($(BOOT_SRCS),)
  189. $(call DEPS,$(BOOT_SRCS),$(BOOT_DEP_DIR)): $(BOOT_DEP_DIR)/%.d: %.c
  190. @$(MKDIR) -p $(dir $@)
  191. @$(MKDIR) -p $(BOOT_OBJ_DIR)
  192. $(QUIET_DEPEND) -o $@.tmp -MM $(if $(BOOT_GEN_SRCS),-MG) -MT "$@ $(patsubst $(BOOT_DEP_DIR)/%.d,$(BOOT_OBJ_DIR)/%.o,$@)" $(BOOT_CFLAGS) $<
  193. @$(MV) -f $@.tmp $@
  194. endif
  195. -include $(call DEPS,$(SRCS),$(DEP_DIR))
  196. ifneq ($(BOOT_SRCS),)
  197. -include $(call DEPS,$(BOOT_SRCS),$(BOOT_DEP_DIR))
  198. endif
  199. # Generate object files
  200. $(call OBJS,$(SRCS),$(OBJ_DIR)): $(OBJ_DIR)/%.o: %.c
  201. @$(MKDIR) -p $(dir $@)
  202. $(QUIET_CC) -o $@ -c $(CFLAGS) $<
  203. $(QUIET_SPARSE) $(SPARSEFLAGS) $<
  204. ifneq ($(BOOT_SRCS),)
  205. $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR)): $(BOOT_OBJ_DIR)/%.o: %.c
  206. @$(MKDIR) -p $(dir $@)
  207. $(QUIET_CC) -o $@ -c $(BOOT_CFLAGS) $<
  208. $(QUIET_SPARSE) $(BOOT_SPARSEFLAGS) $<
  209. endif
  210. all: $(HEX) $(if $(BOOT_SRCS),$(BOOT_HEX))
  211. %.s: %.c
  212. $(QUIET_CC) $(CFLAGS) -fno-lto -S $*.c
  213. $(BIN): $(call OBJS,$(SRCS),$(OBJ_DIR))
  214. +$(QUIET_CC) $(CFLAGS) -o $(BIN) $(call OBJS,$(SRCS),$(OBJ_DIR)) $(LDFLAGS)
  215. +$(QUIET_OBJDUMP) -S $(BIN) > $(DASM)
  216. $(BOOT_BIN): $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR))
  217. +$(QUIET_CC) $(BOOT_CFLAGS) -o $(BOOT_BIN) $(call OBJS,$(BOOT_SRCS),$(BOOT_OBJ_DIR)) $(BOOT_LDFLAGS)
  218. +$(QUIET_OBJDUMP) -S $(BOOT_BIN) > $(BOOT_DASM)
  219. $(HEX): $(BIN)
  220. $(QUIET_OBJCOPY) -R.eeprom -O ihex $(BIN) $(HEX)
  221. @$(OBJDUMP) -h $(BIN) | $(GREP) -qe .eeprom && \
  222. $(OBJCOPY) -j.eeprom --set-section-flags=.eeprom="alloc,load" \
  223. --change-section-lma .eeprom=0 -O ihex $(BIN) $(EEP) \
  224. || $(TRUE)
  225. $(QUIET_SIZE) --format=SysV $(BIN)
  226. $(BOOT_HEX): $(BOOT_BIN)
  227. $(QUIET_OBJCOPY) -R.eeprom -O ihex $(BOOT_BIN) $(BOOT_HEX)
  228. $(QUIET_SIZE) --format=SysV $(BOOT_BIN)
  229. define _avrdude_interactive
  230. $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
  231. -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) -t
  232. endef
  233. define _avrdude_reset
  234. $(AVRDUDE) -B $(AVRDUDE_SLOW_SPEED) -p $(AVRDUDE_ARCH) \
  235. -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
  236. -U signature:r:/dev/null:i -q -q
  237. endef
  238. define _avrdude_write_flash
  239. $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
  240. -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
  241. $(if $(BOOT_SRCS),-U flash:w:$(BOOT_HEX)) \
  242. -U flash:w:$(HEX)
  243. endef
  244. define _avrdude_write_eeprom
  245. $(TEST) -r $(EEP) && ( \
  246. $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
  247. -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) \
  248. -U eeprom:w:$(EEP) \
  249. ) || $(TRUE)
  250. endef
  251. define _avrdude_write_fuse
  252. $(AVRDUDE) -B $(AVRDUDE_SLOW_SPEED) -p $(AVRDUDE_ARCH) \
  253. -c $(AVRDUDE_PROGRAMMER) -P $(PROGPORT) -q -q \
  254. -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m $(if $(EFUSE),-U efuse:w:$(EFUSE):m)
  255. endef
  256. write_flash: all
  257. $(call _programmer_cmd_prog_enter)
  258. $(call _avrdude_write_flash)
  259. $(call _programmer_cmd_pwrcycle)
  260. $(call _programmer_cmd_prog_leave)
  261. writeflash: write_flash
  262. write_eeprom: all
  263. $(call _programmer_cmd_prog_enter)
  264. $(call _avrdude_write_eeprom)
  265. $(call _programmer_cmd_pwrcycle)
  266. $(call _programmer_cmd_prog_leave)
  267. writeeeprom: write_eeprom
  268. write_mem: all
  269. $(call _programmer_cmd_prog_enter)
  270. $(call _avrdude_write_flash)
  271. $(call _avrdude_write_eeprom)
  272. $(call _programmer_cmd_pwrcycle)
  273. $(call _programmer_cmd_prog_leave)
  274. writemem: write_mem
  275. install: write_mem
  276. write_fuses:
  277. $(call _programmer_cmd_prog_enter)
  278. $(call _avrdude_write_fuse)
  279. $(call _programmer_cmd_pwrcycle)
  280. $(call _programmer_cmd_prog_leave)
  281. write_fuse: write_fuses
  282. writefuse: write_fuses
  283. writefuses: write_fuses
  284. print_fuses:
  285. @$(if $(LFUSE),echo "LFUSE (low fuse) = $(LFUSE)",$(TRUE))
  286. @$(if $(HFUSE),echo "HFUSE (high fuse) = $(HFUSE)",$(TRUE))
  287. @$(if $(EFUSE),echo "EFUSE (extended fuse) = $(EFUSE)",$(TRUE))
  288. printfuses: print_fuses
  289. reset:
  290. $(call _programmer_cmd_prog_enter)
  291. $(call _avrdude_reset)
  292. $(call _programmer_cmd_pwrcycle)
  293. avrdude:
  294. $(call _programmer_cmd_prog_enter)
  295. $(call _avrdude_interactive)
  296. $(call _programmer_cmd_pwrcycle)
  297. $(call _programmer_cmd_prog_leave)
  298. doxygen:
  299. $(DOXYGEN) Doxyfile
  300. clean:
  301. -$(QUIET_RM) -rf \
  302. $(OBJ_DIR) $(DEP_DIR) \
  303. $(BOOT_OBJ_DIR) $(BOOT_DEP_DIR) \
  304. $(BIN) $(BOOT_BIN) \
  305. $(MAP) $(BOOT_MAP) \
  306. $(DASM) $(BOOT_DASM) \
  307. *.pyc *.pyo __pycache__ \
  308. $(GEN_SRCS) $(BOOT_GEN_SRCS) \
  309. $(CLEAN_FILES)
  310. distclean: clean
  311. -$(QUIET_RM) -f \
  312. $(HEX) $(BOOT_HEX) \
  313. $(EEP) \
  314. *.s \
  315. $(DISTCLEAN_FILES)