1 # Copyright 2010 The Android Open-Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License 14 15 # NOTE: this Makefile is derived from an example included in Arduino 0017. 16 # That Makefile bore no license, but the rest of the Arduino is generally LGPL 17 # v2 with upgrade option. Since it was unclear what the license for the 18 # Makefile itself was intended to be, this version uses ASL2.0, as LGPL is 19 # an unusual license choice for a Makefile. ASL2.0 is compatible with LGPL v3 20 # so there should be no conflict (due to the upgrade option.) 21 22 # Theory of Operation 23 # 'Arduino' refers to a hardware platform, and a software IDE. The IDE is 24 # pretty simple, and boils down to a crude text editor and some build 25 # plumbing. An Arduino 'sketch' is the core of a C (or C++) program; the build 26 # plumbing wraps a bunch of boilerplate (like #includes and entry point stubs) 27 # around the user's core code, and handles running the gcc cross-compiler and 28 # linking in the appropriate goodies to target AVR. It also handles 29 # programming the Atmel part on the board, via USB. 30 # 31 # The function of this Makefile is simply to replicate all the boilerplate 32 # management. An Arduino 'sketch' is stored as a .pde file, but is essentially 33 # C code; so this Makefile cats together a full C/C++ file, compiles the 34 # standard Arduino libraries, and links them all together, using the AVR 35 # cross-compiler toolchain for gcc. (Ubuntu provides a pre-built avr-gcc 36 # package.) 37 38 # Path settings 39 TARGET = $(notdir $(CURDIR)) 40 ARDUINO_PATH=/usr/share/arduino 41 ARDUINO_VERSION=18 42 ARDUINO_CORES_PATH = $(ARDUINO_PATH)/hardware/arduino/cores/arduino 43 AVR_TOOLS_PATH = /usr/bin 44 AVRDUDE_PATH = /usr/bin 45 46 # Programming port information 47 PORT = /dev/ttyUSB0 48 UPLOAD_RATE = 57600 49 50 # Target information (settings below work for Duemilanove) 51 AVRDUDE_PROGRAMMER = stk500v1 52 MCU = atmega328p 53 F_CPU = 16000000 54 OUT_DIR = out 55 56 # C-language libraries to compile and link with all programs 57 ARDUINO_C_MODULES_SRC = \ 58 $(ARDUINO_CORES_PATH)/wiring_pulse.c \ 59 $(ARDUINO_CORES_PATH)/wiring_analog.c \ 60 $(ARDUINO_CORES_PATH)/pins_arduino.c \ 61 $(ARDUINO_CORES_PATH)/wiring.c \ 62 $(ARDUINO_CORES_PATH)/wiring_digital.c \ 63 $(ARDUINO_CORES_PATH)/WInterrupts.c \ 64 $(ARDUINO_CORES_PATH)/wiring_shift.c 65 ARDUINO_C_MODULES_OBJ = \ 66 $(OUT_DIR)/wiring_pulse.o \ 67 $(OUT_DIR)/wiring_analog.o \ 68 $(OUT_DIR)/pins_arduino.o \ 69 $(OUT_DIR)/wiring.o \ 70 $(OUT_DIR)/wiring_digital.o \ 71 $(OUT_DIR)/WInterrupts.o \ 72 $(OUT_DIR)/wiring_shift.o 73 74 # C++-language libraries to compile and link with all programs 75 ARDUINO_CPP_MODULES_SRC = \ 76 $(ARDUINO_CORES_PATH)/Tone.cpp \ 77 $(ARDUINO_CORES_PATH)/main.cpp \ 78 $(ARDUINO_CORES_PATH)/WMath.cpp \ 79 $(ARDUINO_CORES_PATH)/Print.cpp \ 80 $(ARDUINO_CORES_PATH)/HardwareSerial.cpp 81 ARDUINO_CPP_MODULES_OBJ = \ 82 $(OUT_DIR)/Tone.o \ 83 $(OUT_DIR)/main.o \ 84 $(OUT_DIR)/WMath.o \ 85 $(OUT_DIR)/Print.o \ 86 $(OUT_DIR)/HardwareSerial.o 87 88 TARGET_CPP_SRC = $(OUT_DIR)/$(TARGET).cpp 89 FORMAT = ihex 90 91 # Name of this Makefile (used for "make depend"). 92 MAKEFILE = Makefile 93 94 # Debugging format. 95 # Native formats for AVR-GCC's -g are stabs [default], or dwarf-2. 96 # AVR (extended) COFF requires stabs, plus an avr-objcopy run. 97 DEBUG = 98 OPT = s 99 100 # Place -D or -U options here 101 CDEFS = -DF_CPU=$(F_CPU)L -DARDUINO=$(ARDUINO_VERSION) 102 CXXDEFS = -DF_CPU=$(F_CPU)L -DARDUINO=$(ARDUINO_VERSION) 103 104 # Place -I options here 105 CINCS = -I$(ARDUINO_CORES_PATH) 106 CXXINCS = -I$(ARDUINO_CORES_PATH) 107 108 # toolchain flags 109 CDEBUG = -g$(DEBUG) 110 CWARN = -w # suppress all warnings 111 CTUNING = -ffunction-sections -fdata-sections 112 CXXTUNING = -fno-exceptions -ffunction-sections -fdata-sections 113 CFLAGS = $(CDEBUG) -O$(OPT) $(CWARN) $(CTUNING) $(CDEFS) $(CINCS) $(CSTANDARD) 114 CXXFLAGS = $(CDEBUG) -O$(OPT) $(CWARN) $(CXXTUNING) $(CDEFS) $(CINCS) 115 #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs 116 LDFLAGS = -O$(OPT) -lm -Wl,--gc-sections 117 118 # Programming support using avrdude. Settings and variables. 119 AVRDUDE_WRITE_FLASH = -U flash:w:$(OUT_DIR)/$(TARGET).hex 120 #AVRDUDE_FLAGS = -V -F -C $(ARDUINO_PATH)/hardware/tools/avrdude.conf \ 121 122 AVRDUDE_FLAGS = -V -F -p $(MCU) -P $(PORT) -c $(AVRDUDE_PROGRAMMER) -b $(UPLOAD_RATE) 123 124 # AVR cross-compiler toolchain binaries 125 CC = $(AVR_TOOLS_PATH)/avr-gcc 126 CXX = $(AVR_TOOLS_PATH)/avr-g++ 127 LD = $(AVR_TOOLS_PATH)/avr-gcc 128 OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy 129 OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump 130 AR = $(AVR_TOOLS_PATH)/avr-ar 131 SIZE = $(AVR_TOOLS_PATH)/avr-size 132 NM = $(AVR_TOOLS_PATH)/avr-nm 133 AVRDUDE = $(AVRDUDE_PATH)/avrdude 134 135 # General programs 136 REMOVE = rm -f 137 RMDIR = rmdir 138 MV = mv -f 139 140 # Combine all necessary flags and optional flags. 141 # Add target processor to flags. 142 ALL_CFLAGS = $(CFLAGS) -mmcu=$(MCU) 143 ALL_CXXFLAGS = $(CXXFLAGS) -mmcu=$(MCU) 144 ALL_ASFLAGS = -x assembler-with-cpp $(ASFLAGS) -mmcu=$(MCU) 145 ALL_LDFLAGS = $(LDFLAGS) -mmcu=$(MCU) 146 147 # Default target. 148 all: $(OUT_DIR)_files build sizeafter 149 build: elf hex 150 151 # Concatenates the 'sketch' .pde file with the usual Arduino boilerplate 152 $(OUT_DIR)/$(TARGET).cpp: $(TARGET).pde 153 @echo "Generate $(TARGET).cpp from $(TARGET).pde" 154 @test -d $(OUT_DIR) || mkdir $(OUT_DIR) 155 @echo '#include "WProgram.h"' > $(OUT_DIR)/$(TARGET).cpp 156 @echo 'void setup();' >> $(OUT_DIR)/$(TARGET).cpp 157 @echo 'void loop();' >> $(OUT_DIR)/$(TARGET).cpp 158 @cat $(TARGET).pde >> $(OUT_DIR)/$(TARGET).cpp 159 160 elf: $(OUT_DIR)/$(TARGET).elf 161 hex: $(OUT_DIR)/$(TARGET).hex 162 eep: $(OUT_DIR)/$(TARGET).eep 163 lss: $(OUT_DIR)/$(TARGET).lss 164 sym: $(OUT_DIR)/$(TARGET).sym 165 166 # Program the device. 167 upload: $(OUT_DIR)/$(TARGET).hex 168 # pulsedtr strobes the DTR line to tell arduino to enter pgming mode 169 python ./pulsedtr.py $(PORT) 170 $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) 171 172 173 # Display size of file. 174 HEXSIZE = $(SIZE) --target=$(FORMAT) $(OUT_DIR)/$(TARGET).hex 175 ELFSIZE = $(SIZE) $(OUT_DIR)/$(TARGET).elf 176 sizebefore: 177 @if [ -f $(OUT_DIR)/$(TARGET).elf ]; then echo $(MSG_SIZE_BEFORE); $(HEXSIZE); fi 178 179 sizeafter: 180 @if [ -f $(OUT_DIR)/$(TARGET).elf ]; then echo $(MSG_SIZE_AFTER); $(HEXSIZE); fi 181 182 183 # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. 184 COFFCONVERT=$(OBJCOPY) --debugging \ 185 --change-section-address .data-0x800000 \ 186 --change-section-address .bss-0x800000 \ 187 --change-section-address .noinit-0x800000 \ 188 --change-section-address .eeprom-0x810000 189 190 191 coff: $(OUT_DIR)/$(TARGET).elf 192 $(COFFCONVERT) -O coff-avr $(OUT_DIR)/$(TARGET).elf $(TARGET).cof 193 194 195 extcoff: $(TARGET).elf 196 $(COFFCONVERT) -O coff-ext-avr $(OUT_DIR)/$(TARGET).elf $(TARGET).cof 197 198 199 .SUFFIXES: .elf .hex .eep .lss .sym 200 201 .elf.hex: 202 $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ 203 204 .elf.eep: 205 $(OBJCOPY) -O $(FORMAT) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ 206 --no-change-warnings \ 207 --change-section-lma .eeprom=0 $< $@ 208 209 # Create extended listing file from ELF output file. 210 .elf.lss: 211 $(OBJDUMP) -h -S $< > $@ 212 213 # Create a symbol table from ELF output file. 214 .elf.sym: 215 $(NM) -n $< > $@ 216 217 # Link: create ELF output file from library. 218 $(OUT_DIR)/$(TARGET).elf: $(OUT_DIR)/$(TARGET).o $(OUT_DIR)/core.a 219 $(LD) $(ALL_LDFLAGS) -o $@ $(OUT_DIR)/$(TARGET).o $(OUT_DIR)/core.a 220 221 $(OUT_DIR)/core.a: $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ) 222 @for i in $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ); do echo $(AR) rcs $(OUT_DIR)/core.a $$i; $(AR) rcs $(OUT_DIR)/core.a $$i; done 223 224 $(ARDUINO_C_MODULES_OBJ): 225 $(CC) -c $(ALL_CFLAGS) $(ARDUINO_CORES_PATH)/$(patsubst %.o,%.c,$(patsubst $(OUT_DIR)/%,%,$@)) -o $@ 226 227 $(ARDUINO_CPP_MODULES_OBJ): 228 $(CXX) -c $(ALL_CXXFLAGS) $(ARDUINO_CORES_PATH)/$(patsubst %.o,%.cpp,$(patsubst $(OUT_DIR)/%,%,$@)) -o $@ 229 230 # Compile: create object files from C++ source files. 231 .cpp.o: 232 $(CXX) -c $(ALL_CXXFLAGS) $< -o $@ 233 234 # Compile: create object files from C source files. 235 .c.o: 236 $(CC) -c $(ALL_CFLAGS) $< -o $@ 237 238 239 # Compile: create assembler files from C source files. 240 .c.s: 241 $(CC) -S $(ALL_CFLAGS) $< -o $@ 242 243 244 # Assemble: create object files from assembler source files. 245 .S.o: 246 $(CC) -c $(ALL_ASFLAGS) $< -o $@ 247 248 249 # Automatic dependencies 250 %.d: %.c 251 $(CC) -M $(ALL_CFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@ 252 253 %.d: %.cpp 254 $(CXX) -M $(ALL_CXXFLAGS) $< | sed "s;$(notdir $*).o:;$*.o $*.d:;" > $@ 255 256 257 # Target: clean project. 258 clean: 259 $(REMOVE) $(OUT_DIR)/$(TARGET).hex $(OUT_DIR)/$(TARGET).eep \ 260 $(OUT_DIR)/$(TARGET).cof $(OUT_DIR)/$(TARGET).elf \ 261 $(OUT_DIR)/$(TARGET).map $(OUT_DIR)/$(TARGET).sym \ 262 $(OUT_DIR)/$(TARGET).lss $(OUT_DIR)/core.a \ 263 $(ARDUINO_C_MODULES_SRC:.c=.s) $(ARDUINO_C_MODULES_SRC:.c=.d) \ 264 $(ARDUINO_CPP_MODULES_SRC:.cpp=.s) $(ARDUINO_CPP_MODULES_SRC:.cpp=.d) \ 265 $(ARDUINO_C_MODULES_OBJ) $(ARDUINO_CPP_MODULES_OBJ) \ 266 $(OUT_DIR)/$(TARGET).cpp $(OUT_DIR)/$(TARGET).o 267 distclean: clean 268 $(RMDIR) $(OUT_DIR) 269 270 .PHONY: all build elf hex eep lss sym program coff extcoff clean $(OUT_DIR)_files sizebefore sizeafter 271 272 #include $(ARDUINO_C_MODULES_SRC:.c=.d) 273 #include $(ARDUINO_CPP_MODULES_SRC:.cpp=.d) 274 #include $(TARGET_CPP_SRC:.cpp=.d) 275