1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
include config.mk
CC ?= gcc
AVR_CC ?= avr-gcc
AVR_SIZE ?= avr-size
GDB ?= avr-gdb
OBJCOPY ?= avr-objcopy
AVRDUDE ?= avrdude
QEMU ?= qemu-system-avr
REAL_ELF = build/altimeter.elf
SIM_ELF = build/altimeter_sim.elf
# options for native (i.e. unit test)
UNITY_SRC ?= unity/src
TEST_RUNNER ?= unity-test-runner
CFLAGS += -Wall -Wextra -I$(UNITY_SRC) -I$(TEST_RUNNER) -g3
LDFLAGS += -lm
# options for cross-compile
MCU ?= atmega32u4
SIM_MCU ?= atmega2560
# Compiler flags for cross-compile
AVR_COMMON_CFLAGS += -Wall -Wextra -DF_CPU=16000000UL
AVR_CFLAGS += $(AVR_COMMON_CFLAGS) -mmcu=$(MCU) -O3
SIM_CFLAGS += $(AVR_COMMON_CFLAGS) -mmcu=$(SIM_MCU) -g3 -gdwarf-2 -DWDT_DISABLE
# Linker flags for cross-compile
AVR_COMMON_LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
AVR_LDFLAGS += $(AVR_COMMON_LDFLAGS) -mmcu=$(MCU)
SIM_LDFLAGS += $(AVR_COMMON_LDFLAGS) -mmcu=$(SIM_MCU)
$(shell mkdir -p build/{real,sim,native{,/$(UNITY_SRC),/$(TEST_RUNNER)}})
all: build/altimeter_sim.elf build/altimeter.hex test size
# Run the sim build software in qemu, halted ready for `make gdb` to attach and
# continue. Note that sim build mocks out some hardware components
emu: $(SIM_ELF)
$(QEMU) -s -S -nographic -machine mega2560 -bios $<
# Attach GDB session to qemu instance started with `make emu`
gdb:
$(GDB) -ex "target remote :1234" $(SIM_ELF)
# Flash AVR software to microcontroller with AVRdude
flash: build/altimeter.hex
$(AVRDUDE) -F -V -c avr109 -p $(MCU) -P $(PORT) -b 115200 -U flash:w:$<
clean:
rm -rf build/
BUILD_DIR = build
SIM_DIR = $(BUILD_DIR)/sim
REAL_DIR = $(BUILD_DIR)/real
NATIVE_DIR = $(BUILD_DIR)/native
TEST_OBJ = \
$(NATIVE_DIR)/$(UNITY_SRC)/unity.o \
$(NATIVE_DIR)/$(TEST_RUNNER)/test_runner.o \
$(NATIVE_DIR)/test_util.o \
$(NATIVE_DIR)/test_data_manager.o \
$(NATIVE_DIR)/data_manager.o \
$(NATIVE_DIR)/barometer_sim.o \
$(NATIVE_DIR)/timer_linux.o \
$(NATIVE_DIR)/util.o
REAL_OBJ = \
$(REAL_DIR)/barometer_sim.o \
$(REAL_DIR)/display_sim.o \
$(REAL_DIR)/altimeter.o \
$(REAL_DIR)/util.o \
$(REAL_DIR)/timer.o \
$(REAL_DIR)/ui.o \
$(REAL_DIR)/data_manager.o
SIM_OBJ = \
$(SIM_DIR)/barometer_sim.o \
$(SIM_DIR)/display_sim.o \
$(SIM_DIR)/altimeter.o \
$(SIM_DIR)/util.o \
$(SIM_DIR)/timer.o \
$(SIM_DIR)/ui.o \
$(SIM_DIR)/data_manager.o
ALL_OBJ = $(TEST_OBJ) $(REAL_OBJ) $(SIM_OBJ)
ALL_SOURCE = $(ALL_OBJ:.o=.c)
test: build/native/unity-test-runner/test_runner
./$^
build/native/unity-test-runner/test_runner: $(TEST_OBJ)
$(CC) $(LDFLAGS) -Wl,-T,$(TEST_RUNNER)/linker_list.lds -o $@ $^
# ELF for real hardware. No mock/sim hardware included (except barometer,
# haven't written that code yet)
$(REAL_ELF): $(REAL_OBJ)
$(AVR_CC) $(AVR_LDFLAGS) -o $@ $^
size: $(REAL_ELF)
$(AVR_SIZE) -C --mcu="$(MCU)" "$(REAL_ELF)"
# ELF for simulator/emu. Note that whever I/O is required, the *_sim.{o,c}
# versions of each component will provide a mocked interface. This allows for
# operation in QEMU (see `emu` recipe) without requring SPI, I²C and
# peripherals to be emulated. Useful for UI testing and development etc.
build/altimeter_sim.elf: $(SIM_OBJ)
$(AVR_CC) $(SIM_LDFLAGS) -o $@ $^
build/sim/%.o: %.c build/sim/%.d
$(AVR_CC) $(SIM_CFLAGS) -c -o $@ $<
build/real/%.o: %.c build/real/%.d
$(AVR_CC) $(AVR_CFLAGS) -c -o $@ $<
build/native/%.o: %.c build/native/%.d
$(CC) $(CFLAGS) -c -o $@ $<
build/%.hex: build/%.elf
$(OBJCOPY) -O ihex -R .eeprom $< $@
build/sim/%.d: %.c
@set -e; rm -f $@; \
$(AVR_CC) $(SIM_CFLAGS) -MM -MG $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
build/real/%.d: %.c
@set -e; rm -f $@; \
$(AVR_CC) $(AVR_CFLAGS) -MM -MG $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
build/native/%.d: %.c
@set -e; rm -f $@; \
$(CC) $(CFLAGS) -MM -MG $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
include $(ALL_SOURCE:.c=.d)
.PHONY: all emu gdb flash clean test size
|