Home | History | Annotate | Download | only in arduino-helper
      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