#------------------------------------------------- # # Basic Makefile to get rid of arduino's GUI (and .ino files) # # How it works: # - the user gives a list of .c/.cc /.cpp # CALLED USR_SRCS # - generate (once) a "core.a" lib containing all the necessary # code from arduino (comprizing the generic "main") # - compile our own code # - link all together to get a "elf" # - objcopy the "elf" to a "hex" file # - upload the hex # #------------------------------------------------- # Works for UNO or MEGA #------------------------------------------------- # MUST define this variable BEFORE including this makefile #ARDUINO_BOARD=SBC #ARDUINO_BOARD=MEGA ifeq ($(ARDUINO_BOARD),SBC) ########################################## # UNO SPECIFIC VARIANT=standard MCU=atmega328p F_CPU=16000000 PTCOMPAT=-D__PROG_TYPES_COMPAT__ LOADER_FLAGS=-carduino # SBC SPECIFIC TTYKIND=ttyUSB VENDOR=1a86 ########################################## else ifeq ($(ARDUINO_BOARD),MEGA) ########################################## # MEGA SPECIFIC VARIANT=mega MCU=atmega2560 F_CPU=16000000 RELAX=,--relax LOADER_FLAGS=-cwiring TTYKIND=ttyACM VENDOR=2341 ########################################## else $(error ARDUINO_BOARD must be set to SBC or MEGA) endif what: @echo "Make what ???? (compile,upload,clean)" #------------------------------------------------- # compilation #------------------------------------------------- # avr-xxx bin tools are installed in standard places (/usr/bin) CC=avr-gcc CPP=avr-g++ AR=avr-ar OBJ_COPY=avr-objcopy LOADER=avrdude # dev files are installed in /usr/share, and must be explicitely refered ifndef ARDUINO_TOP #default package install ARDUINO_TOP=/usr/share/arduino endif INCLS=\ -I$(ARDUINO_TOP)/hardware/arduino/cores/arduino \ -I$(ARDUINO_TOP)/hardware/arduino/variants/$(VARIANT) ifndef AVR_TOP #default is a system-wide install AVR_TOP=/ endif # C flags are used both to compile arduino and user code GENERAL_FLAGS=\ -c -g -Os -Wall -ffunction-sections -fdata-sections \ -mmcu=$(MCU) -DF_CPU=$(F_CPU)L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 $(PTCOMPAT) # UNO SPECIFIC (?) # GENERAL_FLAGS+= -D__PROG_TYPES_COMPAT__ CPP_FLAGS = $(GENERAL_FLAGS) -fno-exceptions CC_FLAGS = $(GENERAL_FLAGS) # Everything generated goes there, already defined when rots is used ifndef OBJDIR OBJDIR=./objs endif # User code, must be defined: # USR_TARGET = name for the bin # USR_SRCS = list of .c,.cc,.cpp ONLY define compile_c_rule USR_OBJS+=$(addprefix $(OBJDIR)/, $(notdir $(basename $(1)))).o $(addprefix $(OBJDIR)/, $(notdir $(basename $(1)))).o: $(1) $(CC) $(CC_FLAGS) $(USR_CFLAGS) $(INCLS) $(USR_INCLS) $$< -o $$@ endef define compile_cpp_rule USR_OBJS+=$(addprefix $(OBJDIR)/, $(notdir $(basename $(1)))).o $(addprefix $(OBJDIR)/, $(notdir $(basename $(1)))).o: $(1) $(CPP) $(CPP_FLAGS) $(USR_CPP_FLAGS) $(INCLS) $(USR_INCLS) $$< -o $$@ endef USR_C=$(filter %.c, $(USR_SRCS)) USR_CPP=$(filter %.cc %.cpp, $(USR_SRCS)) $(foreach src,$(USR_C),$(eval $(call compile_c_rule, $(src)))) $(foreach src,$(USR_CPP),$(eval $(call compile_cpp_rule, $(src)))) #all: $(OBJDIR) $(OBJS) compile: $(OBJDIR) $(OBJDIR)/$(TARGET).hex # link my code and the core.a # UNO SPECIFIC (?) no ",--relax" $(OBJDIR)/$(TARGET).elf: $(OBJDIR)/core.a $(USR_OBJS) $(USR_LIBS) $(CC) -Os -Wl,--gc-sections$(RELAX) -mmcu=$(MCU) -o $@ \ $(USR_OBJS) $(USR_LIBS) $(OBJDIR)/core.a -L$(OBJDIR) -lm # elf -> eep + hex $(OBJDIR)/$(TARGET).hex: $(OBJDIR)/$(TARGET).elf $(OBJ_COPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load \ --no-change-warnings --change-section-lma .eeprom=0 $< $(OBJDIR)/$(TARGET).eep $(OBJ_COPY) -O ihex -R .eeprom $< $@ # upload u: upload # SBC is attached to the first $(TTYKIND) available # N.B. ttyUSB (SBC) or ttyACM (MEGA) # probably ttyUSB0 or ttyACM0, but not completely sure ... # N.B. use the $(VENDOR) id (1a86 for SBC, 2341 for MEGA) # WARNING: fragile, wont support new vendor ! IDV=ID_VENDOR_ID IDVPFX=\#${IDV}= TTY=$(shell \ for x in `find /dev -name "${TTYKIND}*" 2>/dev/null`; do \ vv=$$(udevadm info -q property -n $$x | grep ${IDV}); \ vvv=$${vv${IDVPFX}}; \ if [ "$$vvv" = "${VENDOR}" ]; then echo $$x; break; fi; \ done ; \ echo -n "") checkusb: @echo TTY=${TTY} @if [ "$(TTY)" = "" ]; then echo "*** Bat Car not connected ***"; false; fi upload: checkusb $(OBJDIR)/$(TARGET).hex $(LOADER) -C$(AVR_TOP)/etc/avrdude.conf -v -p$(MCU) \ $(LOADER_FLAGS) -P${TTY} -b115200 -D -Uflash:w:$(OBJDIR)/$(TARGET).hex:i #/usr/share/arduino/hardware/tools/avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v -patmega328p -carduino -P/dev/ttyUSB0 -b115200 -D -Uflash:w:/tmp/build7150358604507498924.tmp/advance.cpp.hex:i #/usr/share/arduino/hardware/tools/avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -v -v -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/build1928257561581363585.tmp/led_arduino_puzzle_loop.cpp.hex:i $(OBJDIR): mkdir -p $@ $(OBJDIR)/%.o: %.cpp $(CPP) $(CPP_FLAGS) $(INCLS) $*.cpp -o $@ # # These are all the .o files for core.a # CORE_OBJS=\ $(OBJDIR)/malloc.o \ $(OBJDIR)/realloc.o \ $(OBJDIR)/WInterrupts.o \ $(OBJDIR)/wiring.o \ $(OBJDIR)/wiring_digital.o \ $(OBJDIR)/wiring_analog.o \ $(OBJDIR)/wiring_pulse.o \ $(OBJDIR)/wiring_shift.o \ $(OBJDIR)/CDC.o \ $(OBJDIR)/HardwareSerial.o \ $(OBJDIR)/HID.o \ $(OBJDIR)/IPAddress.o \ $(OBJDIR)/main.o \ $(OBJDIR)/new.o \ $(OBJDIR)/Print.o \ $(OBJDIR)/Stream.o \ $(OBJDIR)/Tone.o \ $(OBJDIR)/USBCore.o \ $(OBJDIR)/WMath.o \ $(OBJDIR)/WString.o \ COREDIR=$(ARDUINO_TOP)/hardware/arduino/cores/arduino # Sources are either .c or .cpp, in COREDIR or COREDIR/avr-libc, # let gmake find the right one, according to these 2 generic rules: $(OBJDIR)/%.o: $(COREDIR)/avr-libc/%.c $(CC) $(CC_FLAGS) $(INCLS) $< -o $@ $(OBJDIR)/%.o: $(COREDIR)/%.c $(CC) $(CC_FLAGS) $(INCLS) $< -o $@ $(OBJDIR)/%.o: $(COREDIR)/%.cpp $(CPP) $(CPP_FLAGS) $(INCLS) $< -o $@ # build the library $(OBJDIR)/core.a: $(CORE_OBJS) $(AR) rcs $@ $(CORE_OBJS) # minimal arduino code to link # #cores/arduino/avr-libc/malloc.c #cores/arduino/avr-libc/realloc.c #cores/arduino/WInterrupts.c #cores/arduino/wiring.c #cores/arduino/wiring_digital.c #cores/arduino/wiring_analog.c #cores/arduino/wiring_pulse.c #cores/arduino/wiring_shift.c #cores/arduino/CDC.cpp #cores/arduino/HardwareSerial.cpp #cores/arduino/HID.cpp #cores/arduino/IPAddress.cpp #cores/arduino/main.cpp #cores/arduino/new.cpp #cores/arduino/Print.cpp #cores/arduino/Stream.cpp #cores/arduino/Tone.cpp #cores/arduino/USBCore.cpp #cores/arduino/WMath.cpp #cores/arduino/WString.cpp t: checkusb xterm -e "minicom -b 9600 -D ${TTY}" & clean: /bin/rm -rf $(OBJDIR)/*