avrmakelib.mk 9.9 KB

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