Bit of a tidyup, added arduino_make.sh for commandline builds on Linux
[KuttMonster.git] / arduino_make.sh
blobc11d50f50d602299ba3f30b8ac51dfa94e1e4886
1 #!/bin/sh
2 # ardmake: A command-line Arduino make/build environment. 2009-11-29
3 # For instructions, run with the argument "help"!
5 # This script is Copyright (c) 2009 Kimmo Kulovesi <http://arkku.com/>.
6 # Use at your own risk only. Released under GPL, see below for details.
7 # Please mark any modified copies as such, and retain the original
8 # copyright notice in all relevant files, usage, and documentation.
11 # This script runs the Makefile included with Arduino to compile and
12 # upload projects on the command-line. This script sets all
13 # board-specific variables automatically according to the board type,
14 # as well as detects and adds libraries automatically based on the
15 # used #include-directives. Burning bootloaders is supported, as
16 # are external programming devices.
18 # In short, this script can completely replace the Arduino IDE for
19 # typical Arduino/ATMega development.
22 # Last been tested with Arduino version 0017 on Ubuntu 9.04, with
23 # avr-gcc and avrdude installed from Ubuntu packages. While this script
24 # should run in non-Linux environments, there are some dependencies to
25 # GNU tools (e.g. GNU Make), so the Linux should be considered the
26 # intended environment.
29 # CHANGES:
31 # November 2009 - Major bugfix for boards with CPU frequency other
32 # than 16MHz.
33 # - Possibly fixed the __cxa_pure_virtual issue.
34 # - Forcing user to define ARDUINO_BOARD explicitly
35 # since using an incorrect board type can cause
36 # nasty hidden errors.
37 # - Added reset commands to upload and download
38 # when not using the Makefile.
39 # - Added dependency on the board type, i.e. if the
40 # board type is changed, everything gets rebuilt.
41 # - Added target "boards" to list available boards.
42 # - Changed default library path to include the
43 # "~/sketchbook/libraries" directory, similarly to
44 # the current Arduino IDE.
45 # - Made building locally the default and fixed
46 # the problem of dependency files being built in
47 # the core directory.
48 # - Implemented reading configuration from
49 # ~/.ardmake.conf and ardmake.conf in the
50 # sketch directory.
51 # - Fixed build dependencies with Sanguino.
52 # - Rewrote most of the help texts.
53 # - Fixed compatibility with mawk. Thanks to Tom
54 # Parkin for reporting this!
55 # October 2009 - Support AVRISP and burning bootloaders.
56 # - Support building object files into the
57 # applet directory instead of the core and
58 # library directories.
59 # - Generate automatic dependecies for libraries
60 # - Support uploading specified .hex or .bin
61 # directly without compiling anything
62 # - Support downloading flash memory from
63 # microcontroller to .hex or .bin file
64 # - Replace the slightly broken build target:
65 # - Proper dependencies
66 # - Show correct file name and line numbers for errors
67 # - Display program size compared to controller capacity
68 # September 2009 - Support Arduino 017
69 # March 2009 - Support Arduino 014
70 # February 2009 - Initial version
73 # FANCY ARDUINO DEVICE NODES ON LINUX
75 # The default port for the Arduino is set to "/dev/arduino", which
76 # requires udev rules (but avoids the problem of changing ttyUSB names).
77 # Alternatively, it can be changed in this file. The udev rule that
78 # works for the Arduino clone that I have is this:
80 # KERNEL=="ttyUSB*", ATTRS{product}=="FT232R USB UART", \
81 # ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", \
82 # SYMLINK+="arduino arduino_$attr{serial}", GROUP="avrprog", MODE="0660"
84 # You will probably want to change the group to "dialout", or create
85 # the "avrprog" group on your system (like I did). On Ubuntu Linux, place
86 # the rule in a file inside "/etc/udev/rules.d", e.g. "80-arduino.rules".
88 # If you have many devices with the same product and vendor ids,
89 # as may be the case with a popular chip like FT232R, you can
90 # add the condition "ATTRS{serial}" to your udev rules. You can
91 # see the serial if you first use the above rules and then look at
92 # the symlink "arduino_SERIAL" where SERIAL is the serial number
93 # of that particular device. Then create one rule for each of your
94 # devices' serial numbers (add ATTRS{serial}=="MySerial", right
95 # before SYMLINK in the above rules).
98 # COMPILER ERROR ABOUT __cxa_pure_virtual
100 # Some versions of Arduino and avr-gcc cause an error about a missing
101 # function "__cxa_pure_virtual" in programs where C++ classes are used.
102 # To fix this problem, add the following line anywhere in your program:
104 # extern "C" void __cxa_pure_virtual() {}
106 ###################################################################################
107 # This script is free software: you can redistribute it and/or modify
108 # it under the terms of the GNU General Public License as published by
109 # the Free Software Foundation, either version 2 of the License,
110 # or (at your option) any later version.
112 # This script is distributed in the hope that it will be useful,
113 # but WITHOUT ANY WARRANTY; without even the implied warranty of
114 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
115 # GNU General Public License for more details.
117 # You should have received a copy of the GNU General Public License
118 # along with this script. If not, see <http://www.gnu.org/licenses/>.
119 ###################################################################################
120 # Read the configuration file (if any):
122 CONFNAME="ardmake.conf"
123 for conf in "./$CONFNAME" "$HOME/.$CONFNAME"; do
124 if [ -r "$conf" ]; then
125 eval "$(awk -v FS== '{ sub(/^[ \t]*/, ""); sub(/^(set|export)[ ]*/, "");
126 if (/^A(RDUINO_|AVR)[A-Za-z0-9_]*=[^;<>`]*$/) {
127 print "[ -z \"$" $1 "\" ] && " $0
129 next }' "$conf")"
130 echo "Loaded configuration file \"$conf\"."
132 done
134 ###################################################################################
135 # Defaults configuration:
137 # Path to avr tools (/usr/bin if installed from Linux distribution packages)
138 [ -z "$AVR_TOOLS_PATH" ] && AVR_TOOLS_PATH=/usr/bin
140 # Path to avrdude (/usr/bin if installed from Linux distribution packages)
141 [ -z "$AVRDUDE_PATH" ] && AVRDUDE_PATH=/usr/bin
143 # Path to search for additional Arduino libraries (separated by : colons).
144 # The "official" script directory at hardware/libraries is always searched!
146 if [ -z "$ARDUINO_LIBRARY_PATH" ]; then
147 ARDUINO_LIBRARY_PATH="../libraries:$HOME/sketchbook/libraries"
150 # Try to figure out Arduino install directory (first from environment
151 # variable ARDUINO_DIR, then ~/arduino, then opt/arduino)
152 if [ -n "$ARDUINO_DIR" ]; then
153 INSTALL_DIR="$ARDUINO_DIR"
154 else
155 INSTALL_DIR="$HOME/arduino"
156 if [ ! -x "$INSTALL_DIR/arduino" -a -x '/opt/arduino/arduino' ]; then
157 INSTALL_DIR='/opt/arduino'
161 # Build locally unless a shared build is specifically requested:
162 if [ ! "$ARDUINO_BUILD" = "shared" ]; then
163 BUILD_LOCALLY=1
164 else
165 BUILD_LOCALLY=''
168 # The extension for Arduino program files (.pde at the time of writing, but
169 # this is the same as for Processing - .ade would be more fitting)
170 EXT='pde'
172 # Command to reset serial port:
173 RESET_COMMAND="stty hupcl; sleep 0.1; true"
175 ###################################################################################
177 basename="$(basename "$0")"
179 # Check the configuration:
181 BOARDFILE="$INSTALL_DIR/hardware/boards.txt"
182 if [ ! -r "$BOARDFILE" ]; then
183 cat >&2 <<EOF
184 ERROR: Could not read "$BOARDFILE".
186 Please set ARDUINO_DIR correctly so that \$ARDUINO_DIR/hardware/boards.txt
187 is the location of the boards.txt in your Arduino installation.
189 You can configure ARDUINO_DIR either in the environment, or in the
190 configuration file ~/.$CONFNAME, e.g.:
191 echo ARDUINO_DIR=$HOME/arduino-0017 >>~/.$CONFNAME
193 Run "$basename help" for instructions.
195 exit 1
198 [ ! -x "$AVRDUDE_PATH/avrdude" ] && AVRDUDE_PATH="$INSTALL_DIR/hardware/tools"
199 [ ! -x "$AVRDUDE_PATH/avrdude" ] && AVRDUDE_PATH="$(dirname $(which avrdude))"
200 if [ ! -x "$AVRDUDE_PATH/avrdude" ]; then
201 cat >&2 <<EOF
202 ERROR: Could not find an executable avrdude!
204 Please set AVRDUDE_PATH correctly so that \$AVRDUDE_PATH/avrdude is
205 the correct avrdude executable. If you do not have avrdude installed,
206 see if it's available in your system packages, e.g. on Ubuntu Linux
207 you should be able to use:
209 sudo apt-get install avrdude
211 exit 1
214 [ ! -x "$AVR_TOOLS_PATH/avr-gcc" ] && AVR_TOOLS_PATH="$INSTALL_DIR/hardware/tools"
215 [ ! -x "$AVR_TOOLS_PATH/AVR_TOOLS" ] && AVR_TOOLS_PATH="$(dirname $(which avr-gcc))"
216 if [ ! -x "$AVR_TOOLS_PATH/avr-gcc" ]; then
217 cat >&2 <<EOF
218 ERROR: Could not find an executable avr-gcc!
220 Please set AVR_TOOLS_PATH correctly so that \$AVR_TOOLS_PATH/avr-gcc is
221 the correct avr-gcc executable. Other avr build tools (binutils, etc)
222 should be installed at the same location. If you do not have avr-gcc
223 installed, see if it's available in your system packages, e.g. on
224 Ubuntu Linux you should be able to use:
226 sudo apt-get install gcc-avr
228 exit 1
231 # Usage:
233 if [ "$1" = 'help' -o "$1" = '--help' ]; then
234 cat | less <<EOF
235 Arduino command-line make-wrapper and library auto-detector,
236 copyright (c) 2009 Kimmo Kulovesi <http://arkku.com/>. This
237 is provided as free software under GPL with ABSOLUTELY NO WARRANTY.
239 Usage: $basename [target] [options for Make]
241 This script calls Make on the Arduino Makefile to build and/or upload
242 projects using the Arduino programming libraries without the Arduino
243 graphical user-interface. Unlike the Makefile, this script does
244 automatic detection of libraries (including support for user-installed
245 custom libararies), sets all parameters automatically according to
246 the type of board use, etc. This script also supports the use of
247 external ISP programmers for stand-alone microcontrollers.
250 Setup and installation:
251 1) Install Arduino, e.g.:
252 wget http://arduino.googlecode.com/files/arduino-0017.tgz
253 tar xvzf arduino-0017.tgz; ln -s arduino-0017 arduino
254 2) Install avrdude and GCC for AVR, e.g. on Ubuntu & Debian:
255 apt-get install avrdude gcc-avr
256 3) Configure your Arduino installation directory, e.g.
257 export ARDUINO_DIR=/path/to/arduino
258 3) Configure your Arduino board, e.g.:
259 export ARDUINO_BOARD=diecimila
260 4) Configure your Arduino serial port device, e.g.:
261 export ARDUINO_PORT=/dev/ttyUSB0
263 The variable ARDUINO_BOARD must be set to the short name of the
264 board you are using. To list available board types, use the
265 command "$basename boards".
267 By default, this script attempts to find an Arduino installation
268 in ~/arduino and /opt/arduino. If it's neither of these, specify
269 the environmental variable ARDUINO_DIR accordingly.
271 The serial port device defaults to /dev/corename (e.g. /dev/arduino),
272 and to /dev/ttyUSB0 if that is not available. A specific port may
273 be configured by setting the variable ARDUINO_PORT. Linux admins
274 may wish to specify udev rules so that the port device is constant
275 (e.g. /dev/arduino); for details on that, see the comments at the top
276 of this script file, i.e. "$0".
278 Configuring variables:
279 The configuration variables for this script (as detailed above)
280 can be set in the file ~/.$CONFNAME, e.g.:
281 echo ARDUINO_BOARD=atmega328 >~/.$CONFNAME
283 To override all or part of this global configuration, a
284 program-specific configuration file called $CONFNAME can be
285 created inside each sketch directory, if desired. Any settings
286 found in the sketch directory take precedence over the
287 settings in ~/.$CONFNAME.
289 You may also configure any or all of these variables in the
290 environment. Variables configured in the environment take
291 precedence over those in configuration files!
292 and settings in the environment take precedence over all of these.
294 To create and upload an Arduino sketch:
295 1) Create a directory for your program ("sketch"), e.g.
296 mkdir -p ~/sketchbook/Blink
297 2) Create your program .$EXT inside the directory, e.g.:
298 cd ~/sketchbook/Blink; vim Blink.$EXT
299 3) Compile your program by running this script:
300 $basename
301 4) After a succesful compilation, upload to your board:
302 $basename upload
304 Libraries are automatically detected from the #include-directives
305 used. The libraries installed together with your Arduino are
306 always available. Custom libraries are searched for in the
307 directory ~/sketchbook/libraries and in ../libraries (i.e. in
308 the directory libraries in the same directory as your sketch
309 directory is in).
311 The custom library locations can be overridden by specifying
312 the variable ARDUINO_LIBRARY_PATH as a colon-separated list of
313 directories, e.g.:
314 ARDUINO_LIBRARY_PATH=$HOME/arduino_libs:/opt/arduino_libs
317 There are also other make targets that you may use instead of
318 compile (the default) and upload. The target is specified as the first
319 command-line argument. Available targets are:
321 compile (default): Compile the applet (.hex file) ready for uploading.
322 Do this first after making changes to your program!
324 upload: Upload to Arduino/Freeduino/Sanguino. The default
325 port to upload to is /dev/arduino, and if that is
326 not available /dev/ttyUSB0. The port can be
327 overridden by setting ARDUINO_PORT in the environment.
328 The basic usage is:
329 $basename upload
331 To upload a pre-compiled file to the microcontroller,
332 you can specify a filename after upload on the
333 command line. The file must have the extension
334 .hex for Intel hex format, or the extension .bin
335 for raw binary format. For example:
336 $basename upload myprog.hex
338 isp:
339 dragon: Just like "upload", but an AVRISP (or clone) or
340 an AVRDragon device is used to upload instead. These
341 can be used to upload to a stand-alone microcontroller
342 in ISP mode.
344 The AVRDragon is an USB device and the port is
345 autodetected. For AVRISP and clones, the default
346 ports are /dev/avrisp and /dev/ttyUSB0, but the
347 port can be overridden by setting the
348 environmental variable AVRISP_PORT. The AVRISP
349 protocol can be set as AVRISP_PROTOCOL (default
350 is "stk500v2").
352 download: Download the microcontroller's flash memory to
353 the file specified as the next command line
354 parameter. The file name MUST have either the
355 extension .hex for Intel hex format, or the
356 extension .bin for raw binary format. For example:
357 $basename download backup.bin
359 boards: List available board types.
360 coff: Build an applet .cof file for debugging/etc.
361 lss: Build an applet .lss file to show annotated assembler.
364 Targets for burning a bootloader (requires a programming device!):
366 bootloader: Program the fuses and burn a bootloader. The
367 filenames and settings are obtained from the
368 file ARDUINO_DIR/harware/boards.txt according
369 to the board type (ARDUINO_BOARD).
371 The bootloader can only be burned with an external
372 programmer. If the settings in boards.txt are not
373 applicable to your programmer device (as is
374 probably the case), you can specify "isp" for
375 AVRISP or "dragon" for AVRDragon on the command
376 line after the target.
378 For example, to burn the ADABoot bootloader for
379 ATMega168 using an AVRISP device, you would set
380 ARDUINO_BOARD="ADABoot168" and then run:
381 $basename bootloader isp
383 You can also follow the bootloader target with
384 a .bin or .hex filename to burn a custom
385 bootloader without entering it into boards.txt, e.g.:
386 $basename bootloader myloader.hex isp
388 fuses: Just program the fuses and set the lock bits
389 to unlock. For example:
390 $basename fuses isp
393 exit 0
396 # Display list of available board types if requested:
398 if [ "$1" = "boards" ]; then
399 echo "Available boards (for ARDUINO_BOARD):"
400 awk -v FS== '$1 ~ /\.name/ {
401 sub(/\.name$/, "", $1)
402 printf("\t%-15s\t\"%s\"\n", $1, $2);
403 }' "$BOARDFILE"
404 cat <<EOF
406 To configure your board type, set the variable ARDUINO_BOARD
407 either in the environment or in ~/.$CONFNAME, or in the
408 file $CONFNAME inside your program's directory.
410 exit 0
413 # Die if no board type is set:
415 if [ -z "$ARDUINO_BOARD" ]; then
416 cat <<EOF >&2
417 ERROR: The variable ARDUINO_BOARD must be set to the type of Arduino
418 board you are using. Accepted values are those appearing in Arduino's
419 hardware/boards.txt, e.g. "diecimila", "mega", "lilypad", etc.
420 The names are case-sensitive.
422 To save a certain board type as your default, put the setting
423 in ~/.$CONFNAME, e.g.:
424 echo ARDUINO_BOARD=diecimila >>~/.$CONFNAME
426 To configure a project-specific board type, put the setting
427 in the file $CONFNAME in the sketch directory, e.g.:
428 cd ~/sketchbook/MyProg
429 echo ARDUINO_BOARD=mega >>$CONFNAME
431 Run "$basename help" for instructions.
433 exit 1
436 # Try to read the hardware configuration for this board:
438 eval $(awk -v FS== -v board="$ARDUINO_BOARD" '$1 ~ /\.name$/ {
439 if (found)
440 exit 0
441 sub(/\.name$/, "", $1)
442 if (board == $1 || board == $2) {
443 boardname = $2
444 found=1
446 speed=0; core=""; mcu=""; protocol=""; f_cpu=0;
447 lfuse=""; hfuse=""; efuse="";
448 unlock_bits=""; lock_bits="";
449 bootloader_dir=""; bootlader_file="";
450 next
452 $1 ~ /\.upload\.protocol$/ {
453 protocol = $2
454 next
456 $1 ~ /\.upload\.speed$/ {
457 speed = $2
458 next
460 $1 ~ /\.upload\.maximum_size$/ {
461 max_size = $2
462 next
464 $1 ~ /\.build\.core$/ {
465 core = $2
466 next
468 $1 ~ /\.build\.f_cpu$/ {
469 f_cpu = $2
470 next
472 $1 ~ /\.build\.mcu$/ {
473 mcu = $2
474 next
476 $1 ~ /\.bootloader\.low_fuses$/ {
477 lfuse = $2
478 next
480 $1 ~ /\.bootloader\.high_fuses$/ {
481 hfuse = $2
482 next
484 $1 ~ /\.bootloader\.extended_fuses$/ {
485 efuse = $2
486 next
488 $1 ~ /\.bootloader\.unlock_bits$/ {
489 unlock_bits = $2
490 next
492 $1 ~ /\.bootloader\.lock_bits$/ {
493 lock_bits = $2
494 next
496 $1 ~ /\.bootloader\.path$/ {
497 bootloader_dir = $2
498 next
500 $1 ~ /\.bootloader\.file$/ {
501 bootloader_file = $2
502 next
504 END {
505 if (found) {
506 if (speed) {
507 gsub(/[^0-9]/, "", speed)
508 print "UPLOAD_RATE=\"" speed "\""
510 if (f_cpu) {
511 gsub(/[^0-9]/, "", f_cpu)
512 print "F_CPU=\"" f_cpu "\""
514 if (core) {
515 gsub(/[^a-zA-Z0-9_.:-]/, "", core)
516 print "CORE=\"" core "\""
518 if (mcu) {
519 gsub(/[^a-zA-Z0-9_.:-]/, "", mcu)
520 print "MCU=\"" mcu "\""
522 if (protocol) {
523 gsub(/[^a-zA-Z0-9_.:-]/, "", protocol)
524 print "AVRDUDE_PROGRAMMER=\"" \
525 protocol "\""
527 if (max_size) {
528 gsub(/[^0-9]/, "", max_size)
529 print "MAX_SIZE=\"" max_size "\""
531 if (!boardname) {
532 boardname = board
534 if (hfuse != "") {
535 gsub(/[^0-9xA-Fa-f]/, "", hfuse)
536 print "BL_HFUSE=\"" hfuse "\""
538 if (lfuse != "") {
539 gsub(/[^0-9xA-Fa-f]/, "", lfuse)
540 print "BL_LFUSE=\"" lfuse "\""
542 if (efuse != "") {
543 gsub(/[^0-9xA-Fa-f]/, "", efuse)
544 print "BL_EFUSE=\"" efuse "\""
546 if (lock_bits != "") {
547 gsub(/[^0-9xA-Fa-f]/, "", lock_bits)
548 print "BL_LOCK=\"" lock_bits "\""
550 if (unlock_bits != "") {
551 gsub(/[^0-9xA-Fa-f]/, "", unlock_bits)
552 print "BL_UNLOCK=\"" unlock_bits "\""
554 if (bootloader_dir && bootloader_file) {
555 gsub(/["]/, "\\\"", bootloader_dir)
556 gsub(/["]/, "\\\"", bootloader_file)
557 print "BL_PATH=\"" bootloader_dir "/" \
558 bootloader_file "\""
560 print "BOARDNAME=\"" boardname "\""
562 }' "$BOARDFILE")
564 # Die if the board configuration was not found:
566 if [ -z "$F_CPU" ]; then
567 cat <<EOF >&2
568 ERROR: The board "$ARDUINO_BOARD" was not found in the configuration
569 file "$BOARDFILE". The variable ARDUINO_BOARD
570 must be set to the (case-sensitive) short name of the board,
571 e.g. "diecimila" or "atmega328".
573 Run "$basename boards" to list known board types, or
574 "$basename help" for general instructions.
576 exit 1
579 # Some defaults for board types, e.g. if the user has placed a custom
580 # board in boards.txt and didn't define everything:
582 [ -z "$CORE" ] && CORE=arduino
583 [ -z "$MAX_SIZE" ] && MAX_SIZE=14336
584 [ -z "$MCU" ] && MCU="$ARDUINO_BOARD"
585 [ -z "$AVRDUDE_PROGRAMMER" ] && AVRDUDE_PROGRAMMER=stk500v1
586 [ -z "$UPLOAD_RATE" ] && UPLOAD_RATE=19200
588 # Set some helper variables based on the Arduino location:
590 MAKEFILE="$INSTALL_DIR/hardware/cores/$CORE/Makefile"
591 [ ! -e "$MAKEFILE" ] && MAKEFILE="$INSTALL_DIR/hardware/cores/arduino/Makefile"
592 ARDUINO="$INSTALL_DIR/hardware/cores/$CORE"
593 LIBRARY_DIR="$INSTALL_DIR/hardware/libraries"
595 # Check for the wiring_serial.c bug in some versions of Arduino:
597 if grep -q -s -F 'wiring_serial.c' "$MAKEFILE"; then
598 if [ ! -e "$ARDUINO/wiring_serial.c" ]; then
599 echo '/* Empty file created due to bug in Arduino Makefile */' \
600 > "$ARDUINO/wiring_serial.c"
601 if [ ! -e "$ARDUINO/wiring_serial.c" ]; then
602 cat <<EOF >&2
604 WARNING: The file "$ARDUINO/wiring_serial.c" is referred to in the
605 Makefile ("$MAKEFILE"), but it does not exist. This is a bug in some
606 Arduino versions, and will probably lead to failed builds. To remedy,
607 please create the file (it can be empty) or remove the reference
608 from the Makefile.
615 # Correct the programmer "stk500" specified for pretty much every
616 # Arduino board to "stk500v1" (which is the correct, more specific
617 # option for avrdude):
618 [ "$AVRDUDE_PROGRAMMER" = "stk500" ] && AVRDUDE_PROGRAMMER='stk500v1'
620 # Configure the programmer port location:
622 if [ -n "$ARDUINO_PORT" ]; then
623 PORT="$ARDUINO_PORT"
624 else
625 PORT="/dev/$CORE"
626 if [ ! -e "$PORT" ]; then
627 PORT="/dev/$ARDUINO_BOARD"
628 if [ ! -e "$PORT" ]; then
629 PORT='/dev/avr'
630 [ ! -e "$PORT" ] && PORT='/dev/ttyUSB0'
635 # Display verification that the correct board was selected:
637 cat <<EOF
638 Read settings for ARDUINO_BOARD="$ARDUINO_BOARD":
639 $BOARDNAME
643 # Configure AVRDUDE here, since the Makefile included with Arduino
644 # has non-working paths hard-coded:
646 AVRDUDE_MCU=$(echo "$MCU" | awk '
647 $1 ~ /^atmega/ { sub(/^atmega/, "m", $1); print $1; exit }
648 $1 ~ /^attiny/ { sub(/^attiny/, "t", $1); print $1; exit }
649 $1 ~ /^at90s/ { sub(/^at90s/, "t", $1); print $1; exit }
650 $1 ~ /^at90pwm/ { sub(/^at90/, "t", $1); print $1; exit }')
652 AVRDUDE_CONFIG="$INSTALL_DIR/hardware/tools/avrdude.conf"
653 [ ! -e "$AVRDUDE_CONFIG" ] && AVRDUDE_CONFIG="/etc/avrdude.conf"
654 AVRDUDE_FLAGS="-F -D -p $AVRDUDE_MCU -v -v"
656 # Allow targets "bootloader" and "fuses" for burning the bootloader
657 # or setting the fuses, respectively, e.g. for preparing a DIY
658 # Arduino clone with a blank ATMega device.
660 burn_bootloader=''
661 program_fuses=''
662 if [ "$1" = "bootloader" -o "$1" = "fuses" ]; then
663 program_fuses='yes'
664 [ "$1" = "bootloader" ] && burn_bootloader='yes'
665 shift
666 [ ! -x "$AVRDUDE_PATH/avrdude" ] && AVRDUDE_PATH=''
668 if [ -z "$BL_HFUSE" -o -z "$BL_LFUSE" -o -z "$BL_EFUSE" -o \
669 -z "$BL_UNLOCK" -o -z "$BL_PATH" ]
670 then
671 cat >&2 <<EOF
672 ERROR: boards.txt did not define the information necessary for burning
673 a bootloader and/or setting the fuses. You must ensure that the file
674 $INSTALL_DIR/hardware/boards.txt is available and contains the following
675 settings for your board type (currently "$ARDUINO_BOARD"):
677 $ARDUINO_BOARD.bootloader.low_fuses=0x??
678 $ARDUINO_BOARD.bootloader.high_fuses=0x??
679 $ARDUINO_BOARD.bootloader.extended_fuses=0x??
680 $ARDUINO_BOARD.bootloader.unlock_bits=0x??
681 $ARDUINO_BOARD.bootloader.lock_bits=0x??
682 $ARDUINO_BOARD.bootloader.file=filename.hex
683 $ARDUINO_BOARD.bootloader.path=dirname
685 Aborting...
687 exit 1
689 BOOTLOADER_FILE="$INSTALL_DIR/hardware/bootloaders/$BL_PATH"
690 if [ -n "$1" -a -r "$1" ] && echo "$1" | grep -E -q -s '\.(hex|bin)$' ; then
691 BOOTLOADER_FILE="$1"
692 shift
693 elif [ ! -r "$BOOTLOADER_FILE" ]; then
694 echo "ERROR: Bootloader file "$BOOTLOADER_FILE" is not readable!" >&2
695 exit 1
697 cat <<EOF
698 This command line will set the following:
701 [ -n "$burn_bootloader" ] && echo "Bootloader: $BOOTLOADER_FILE"
702 cat <<EOF
703 Fuses: high=$BL_HFUSE low=$BL_LFUSE extended=$BL_EFUSE
705 WARNING!
707 Burning a bootloader and/or setting the fuse bits is potentially
708 dangerous and incorrect settings can make your device stop working!
709 Note that an external programmer is required for this operation,
710 i.e. you can't burn the bootloader via Arduino's own USB.
712 Press Return to continue (at your own risk), or Ctrl-C to cancel!
715 read press_enter >/dev/null 2>&1
718 # Change the target "dragon" to "upload", but perform the upload using
719 # the AVRDragon in ISP mode instead of the instead of the typical Arduino
720 # programming method (e.g. for DIY projects using the same microprocessor
721 # as an Arduino but not having the programming capability themselves).
723 # Similarly change the target "isp" to "upload", but perform the upload
724 # using an AVRISP (or clone thereof).
726 if [ -n "$1" ]; then
727 if [ "$1" = "dragon" ]; then
728 # Uploading with the AVR Dragon:
730 AVRDUDE_PROGRAMMER='dragon_isp'
731 PORT='usb'
732 UPLOAD_RATE=''
733 target='upload'
734 elif [ "$1" = "isp" ]; then
735 # Uploading via AVRISP with the stk500v2 protocol:
737 if [ -n "$AVRISP_PORT" ]; then
738 PORT="$AVRISP_PORT"
739 else
740 PORT='/dev/avrisp'
741 [ ! -e "$PORT" ] && PORT='/dev/ttyUSB0'
743 AVRDUDE_PROGRAMMER='stk500v2'
744 [ -n "$AVRISP_PROTOCOL" ] && AVRDUDE_PROGRAMMER="$AVRISP_PROTOCOL"
745 UPLOAD_RATE="$AVRISP_BAUD"
746 target='upload'
747 elif [ "$1" = "upload" ]; then
748 target='upload_autoreset'
749 else
750 target="$1"
752 shift
753 else
754 target='compile'
756 AVRDUDE_FLAGS="$AVRDUDE_FLAGS -P $PORT -c $AVRDUDE_PROGRAMMER${UPLOAD_RATE:+ -b $UPLOAD_RATE}"
758 # Show the configuration:
760 cat <<EOF
761 Core................... $CORE
762 Core directory......... $ARDUINO
763 Microcontroller........ $MCU ($AVRDUDE_MCU)
764 Clock frequency........ $(echo "$F_CPU" | sed 's/UL$//') Hz
765 Programming protocol... $AVRDUDE_PROGRAMMER
766 Port................... $PORT
767 Maximum upload size.... $MAX_SIZE bytes
771 # Program the fuses (usually as the first step for burning a bootloader):
773 if [ -n "$program_fuses" ]; then
774 "$AVRDUDE_PATH/avrdude" ${AVRDUDE_CONFIG:+-C }"${AVRDUDE_CONFIG:-}" \
775 $AVRDUDE_FLAGS -e -U "lock:w:$BL_UNLOCK:m" \
776 -U "efuse:w:$BL_EFUSE:m" -U "hfuse:w:$BL_HFUSE:m" \
777 -U "lfuse:w:$BL_LFUSE:m" || exit 1
778 cat <<EOF
780 Programmed fuses: high=$BL_HFUSE low=$BL_LFUSE extended=$BL_EFUSE
781 Setting lock bits to unlock: $BL_UNLOCK
785 # Burn the bootloader:
787 if [ -n "$burn_bootloader" ]; then
788 cat <<EOF
790 Burning bootloader: $BOOTLOADER_FILE
793 sleep 5
794 exec "$AVRDUDE_PATH/avrdude" ${AVRDUDE_CONFIG:+-C }"${AVRDUDE_CONFIG:-}" \
795 $AVRDUDE_FLAGS -e -U "flash:w:$BOOTLOADER_FILE:a" -U "lock:w:$BL_LOCK:m"
796 elif [ -n "$program_fuses" ]; then
797 exit 0
800 # Upload custom file (.hex or .bin) with compiling:
802 if [ "$target" = "upload" -o "$target" = "upload_autoreset" \
803 -a -r "$1" ] && echo "$1" | grep -E -q -s '\.(hex|bin)$' ; then
804 echo "Uploading file '$1' to microcontroller..."
805 ( eval "$RESET_COMMAND" ) <"$ARDUINO_PORT" 2>/dev/null
806 exec "$AVRDUDE_PATH/avrdude" ${AVRDUDE_CONFIG:+-C }"${AVRDUDE_CONFIG:-}" \
807 $AVRDUDE_FLAGS -U "flash:w:$1:a"
810 # Download flash to file (.hex or .bin, Intel Hex or raw binary format):
812 if [ "$target" = "download" -a -n "$1" ] && \
813 echo "$1" | grep -E -q -s '\.(hex|bin)$' ; then
814 echo "Downloading flash memory to file '$1'..."
815 ( eval "$RESET_COMMAND" ) <"$ARDUINO_PORT" 2>/dev/null
816 exec "$AVRDUDE_PATH/avrdude" ${AVRDUDE_CONFIG:+-C }"${AVRDUDE_CONFIG:-}" \
817 $AVRDUDE_FLAGS \
818 -U "flash:r:$1:$(echo "$1" | sed 's/^.*hex$/i/; s/^.*bin$/r/')"
821 # Escape AVRDUDE_CONFIG path for the Makefile:
823 [ -n "$AVRDUDE_CONFIG" ] && AVRDUDE_FLAGS="-C \"$AVRDUDE_CONFIG\" $AVRDUDE_FLAGS"
825 # Try to discover the program name:
827 TARGET=$(basename "$(pwd)")
828 for f in *.$EXT; do
829 TARGET=$(echo "$f" | sed "s/\.$EXT$//")
830 break
831 done
832 if [ ! -e "./$TARGET.$EXT" ]; then
833 cat >&2 <<EOF
834 ERROR: No sketch found! To create a program, make a directory with the
835 program name, e.g. MyProg, and write the program code inside that
836 directory in a file with the same name but with the extension ".$EXT".
837 For example:
838 mkdir MyProg; cd MyProg; vim MyProg.$EXT
839 $basename
841 Run "$basename help" for instructions!
843 exit 1
846 # Figure out what libraries are being used:
848 LIBRARIES_DIR="\$(INSTALL_DIR)/hardware/libraries"
849 LIBSRC=''
850 LIBASRC=''
851 LIBCXXSRC=''
852 CINCS=''
853 CXXINCS='$(CINCS)'
854 LIBCHECK_FILES=' '
856 ARDUINO_LIBRARY_PATH=$(echo "$ARDUINO_LIBRARY_PATH" | \
857 sed 's/ /\\ /g; s/[^+-9:=@A-Z_a-z!]//g; s/:/ /g')
859 echo 'Looking for libraries in these directories:'
860 for libpath in $ARDUINO_LIBRARY_PATH "$LIBRARY_DIR"; do
861 echo " $libpath/"
862 done
863 echo
865 # Check an included header for matching .c, .cpp and/or .S files
866 # (simply by filename) and add any of those to the sources.
868 check_header () {
869 local libname="$1"
870 local base="$2"
871 local inlib="$3"
872 local pfx="$base/$libname"
873 [ ! -e "$pfx.h" ] && return 1
875 check_for_libraries "$pfx.h"
877 local makepfx="$pfx"
878 if [ "$base" = "$ARDUINO" ]; then
879 # Beautify the Arduino directory path
880 makepfx="\$(ARDUINO)/$libname"
881 elif [ -n "$inlib" ]; then
882 # Beautify the Arduino library directory path
883 if echo "$base" | grep -q -s -F "$LIBRARY_DIR/$inlib/utility"
884 then
885 makepfx="\$(LIBRARIES_DIR)/$inlib/utility/$libname"
886 elif echo "$base" | grep -q -s -F "$LIBRARY_DIR/$inlib"
887 then
888 makepfx="\$(LIBRARIES_DIR)/$inlib/$libname"
892 if [ -e "$pfx.c" ]; then
893 check_for_libraries "$pfx.c" "$inlib" && \
894 LIBSRC="$LIBSRC $makepfx.c"
896 if [ -e "$pfx.cpp" ]; then
897 check_for_libraries "$pfx.cpp" "$inlib" && \
898 LIBCXXSRC="$LIBCXXSRC $makepfx.cpp"
900 [ -e "$pfx.S" ] && LIBASRC="$LIBASRC $makepfx.S"
902 return 0
905 # Check a file for new libraries we need to include. This is done simply
906 # by locating the #include-lines in the C/C++ sources. Obviously no
907 # pre-processor conditionals or such are supported, but for simple purposes
908 # this seems to work reasonably well. (All examples included with Arduino
909 # version 013 compile correctly.)
911 check_for_libraries () {
912 [ ! -r "$1" ] && return 1
913 if echo "$LIBCHECK_FILES" | grep -q -s -F " |$1| "; then
914 return 1
916 LIBCHECK_FILES="${LIBCHECK_FILES}|$1| "
917 local basedir=$(dirname "$1")
918 local inlib="$2"
920 # Note: Print.cpp is a standard dependency for Arduino programs, but
921 # the dependency was not included in the official Makefile up to and
922 # including version 0014. If this script is used with old versions of
923 # Arduino, compilation may fail due to missing Print.cpp. The suggested
924 # solution is to update Arduino, but if that is not possible you can
925 # add "Print" after the closing ")" on the line before "do":
927 for lib in $(awk -F '[<>"]' '/^[ ]*#include [<"]/ { sub(/\.h[p]*$/, "", $2);
928 gsub(/[^a-zA-Z0-9_.:/-]/, "", $2);
929 print $2; next }' "$1" 2>/dev/null)
931 local found=''
932 local libpath=''
933 local libname="$lib"
934 local header="$ARDUINO/$libname.h"
935 local base=''
937 for libpath in $ARDUINO_LIBRARY_PATH "$LIBRARY_DIR"; do
938 local libdir="$libpath/$libname"
940 if [ -e "$libdir" ]; then
941 if check_for_libraries "$libdir/$libname.h" "$libname"; then
942 if [ "$libpath" = "$LIBRARY_DIR" ]; then
943 echo "Including Arduino library: $libname"
944 CINCS="$CINCS -I\$(LIBRARIES_DIR)/$libname"
945 [ -e "$libdir/utility" ] && \
946 CINCS="$CINCS -I\$(LIBRARIES_DIR)/$libname/utility"
947 else
948 echo "Including local library: $libname"
949 CINCS="$CINCS -I$libdir"
950 [ -e "$libdir/utility" ] && \
951 CINCS="$CINCS -I$libdir/utility"
954 check_header "$libname" "$libdir" "$libname"
955 found=1
956 break
958 done
960 if [ -z "$found" ]; then
961 for base in "$ARDUINO" "$basedir" "$basedir/utility"; do
962 check_header "$libname" "$base" "$inlib" && break
963 done
965 done
966 return 0
969 check_for_libraries "$TARGET.$EXT"
971 # Ensure the applet directory exists:
973 [ ! -d applet ] && mkdir applet
975 if [ -e 'applet/board' -a ! "$BOARDFILE" -nt "applet/board" ]; then
976 configured_board="$(head -n 1 'applet/board')"
977 else
978 configured_board=''
980 [ ! "$configured_board" = "$ARDUINO_BOARD" ] && echo "$ARDUINO_BOARD" >'applet/board'
982 # Display library settings to the user:
984 old_CINCS="$CINCS"
985 CINCS="-I. -I./utility -I\$(ARDUINO)$CINCS"
986 if [ -n "$old_CINCS" ]; then
987 echo
988 echo "Includes = $CINCS"
989 [ -n "$LIBSRC" ] && echo "LIBSRC =$LIBSRC"
990 [ -n "$LIBASRC" ] && echo "LIBASRC =$LIBASRC"
991 [ -n "$LIBCXXSRC" ] && echo "LIBCXXSRC =$LIBCXXSRC"
993 unset old_CINCS
995 # Set the compiler options to better match the IDE:
997 CTUNING='-ffunction-sections -fdata-sections -fshort-enums'
998 CFLAGS='$(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CTUNING) $(CEXTRA) $(CDEBUG)'
999 CXXFLAGS='$(CDEFS) $(CINCS) -O$(OPT) -fno-exceptions $(CTUNING)'
1001 # Create the Makefile:
1003 if [ ! -e 'applet/Makefile' -o 'applet/board' -nt 'applet/Makefile' \
1004 -o "$0" -nt 'applet/Makefile' ]; then
1005 # Change the Make default target to our own:
1006 echo 'compile: do_compile' >applet/Makefile
1008 # Take the original Makefile, but remove the built-in dependency
1009 # includes (so we can override them) and the original .elf target
1010 # which we are replacing below:
1011 sed '/^include $[(][^)]*\.d[)]/ d;
1012 /^applet\/$[(]TARGET[)]\.elf: / d;
1013 /^[ \t]*#/ d;
1014 s/\.pde/\.$(EXT)/g' "$MAKEFILE" >>applet/Makefile
1016 # Now the dirty parts, featuring some rather explicit Make:
1017 echo -e 'do_compile: do_build show_size
1018 do_build: applet/$(TARGET).hex
1019 applet/$(TARGET).hex: applet/$(TARGET).elf
1021 ARDMAKE_BOARD=applet/board
1023 applet/$(TARGET).elf: applet/$(TARGET).cpp applet/core.a
1024 \t$(CXX) $(ALL_CXXFLAGS) -Wl,--gc-sections $(LDFLAGS) -L. -Lapplet/ -o $@ $< applet/core.a
1025 \t@chmod a-x $@ >/dev/null 2>&1 || true
1027 applet/$(TARGET).cpp: $(TARGET).$(EXT) $(ARDUINO)/main.cxx $(ARDUINO)/WProgram.h $(ARDMAKE_BOARD)
1028 \techo '\''#include "WProgram.h"'\'' >$@
1029 \t@echo '\''#line 1 "$<"'\'' >>$@
1030 \tcat $(TARGET).$(EXT) >>$@
1031 \t@echo '\''#line 1 "$(ARDUINO)/main.cxx"'\'' >>$@
1032 \tcat $(ARDUINO)/main.cxx >>$@
1034 show_size:
1035 \t@echo
1036 \t@echo Program size:
1037 \t@$(HEXSIZE) | awk -v m="$(MAX_SIZE)" '\''{print;if(NR^1){s=$$4}} \\
1038 END {printf("\\n%d/%d bytes (%.1f%% of capacity, %d bytes left)\\n\\n",\\
1039 s,m,s*100.0/m,m-s);}'\''
1041 upload_autoreset: do_autoreset upload unreset
1043 do_autoreset:
1044 \t@echo Sending reset to prepare for upload...
1045 \t( '"$RESET_COMMAND"' ) <$(PORT) 2>/dev/null
1046 \t@echo
1048 unreset:
1049 \t@stty -hupcl <$(PORT) 2>/dev/null || true
1051 $(OBJ): $(ARDMAKE_BOARD)
1052 $(DEPS): $(ARDMAKE_BOARD)
1054 $(APPC): applet/%.o: %.c
1055 \t$(CC) -c $(ALL_CFLAGS) -o $@ $<
1057 $(APPCXX): applet/%.o: %.cpp
1058 \t$(CXX) -c $(ALL_CXXFLAGS) -o $@ $<
1060 $(APPA): applet/%.o: %.S
1061 \t$(CC) -c $(ALL_ASFLAGS) -o $@ $<
1063 $(APPC:.o=.d): applet/%.d: %.c
1064 \t$(CC) -M $(ALL_CFLAGS) $< | sed '\''s;^[^:]*:;applet/$*.o applet/$*.d:;'\'' >$@
1066 $(APPCXX:.o=.d): applet/%.d: %.cpp
1067 \t$(CXX) -M $(ALL_CXXFLAGS) $< | sed '\''s;^[^:]*:;applet/$*.o applet/$*.d:;'\'' >$@
1069 $(APPA:.o=.d): applet/%.d: %.S
1070 \t$(CC) -M $(ALL_ASFLAGS) $< | sed '\''s;^[^:]*:;applet/$*.o applet/$*.d:;'\'' >$@
1072 applet/$(TARGET).d: applet/$(TARGET).cpp
1074 vpath %.c applet/ $(sort $(dir $(OBJC)))
1075 vpath %.cpp applet/ $(sort $(dir $(OBJCXX)))
1076 vpath %.S applet/ $(sort $(dir $(OBJA)))
1078 include $(DEPS)' >>applet/Makefile
1080 # Ensure applet/core.a gets re-built every time, because otherwise
1081 # we won't get the correct dependencies:
1082 if [ -z "$target" -o "$target" = "compile" -o "$target" = "all" ]; then
1083 if [ -w "applet/core.a" ]; then
1084 echo "rm -f applet/core.a"
1085 rm -f "applet/core.a"
1090 # Don't do autoreset if we don't have a serial port:
1092 [ "$target" = "upload_autoreset" -a ! -c "$PORT" ] && target=upload
1094 # Substitute the Makefile "clean" target:
1096 if [ "$target" = "clean" ]; then
1097 echo "Cleaning up..."
1098 for ext in d o cpp h elf hex a s S lss cof; do
1099 rm -f applet/*.$ext 2>/dev/null
1100 done
1101 rm -f applet/Makefile applet/board 2>/dev/null
1102 # If we are building locally, do not try to clean inside Arduino dir:
1103 [ -n "$BUILD_LOCALLY" ] && exit 0
1106 # Finally, execute Make:
1108 exec make -f applet/Makefile \
1109 MAKEFILE='applet/Makefile' LIBRARIES_DIR="$LIBRARIES_DIR" \
1110 AVRDUDE_FLAGS="$AVRDUDE_FLAGS" AVRDUDE_PROGRAMMER="$AVRDUDE_PROGRAMMER" \
1111 TARGET="$TARGET" PORT="$PORT" MCU="$MCU" F_CPU="$F_CPU" MAX_SIZE="$MAX_SIZE" \
1112 AVR_TOOLS_PATH="$AVR_TOOLS_PATH" INSTALL_DIR="$INSTALL_DIR" EXT="$EXT" \
1113 AVRDUDE_PATH="$AVRDUDE_PATH" UPLOAD_RATE="$UPLOAD_RATE" ARDUINO="$ARDUINO" \
1114 LIBSRC="$LIBSRC" LIBASRC="$LIBASRC" LIBCXXSRC="$LIBCXXSRC" \
1115 CINCS="$CINCS" CXXINCS="$CXXINCS" AVRDUDE='$(AVRDUDE_PATH)/avrdude' \
1116 CTUNING="$CTUNING" CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" \
1117 OBJC='$(sort $(SRC:.c=.o) $(abspath $(LIBSRC:.c=.o)))' \
1118 OBJCXX='$(sort $(CXXSRC:.cpp=.o) $(abspath $(LIBCXXSRC:.cpp=.o)))' \
1119 OBJA='$(sort $(ASRC:.S=.o) $(abspath $(LIBASRC:.S=.o)))' \
1120 OBJARDUINODIR='$(OBJC) $(OBJCXX) $(OBJA)' \
1121 APPC='$(addprefix applet/,$(notdir $(OBJC)))' \
1122 APPCXX='$(addprefix applet/,$(notdir $(OBJCXX)))' \
1123 APPA='$(addprefix applet/,$(notdir $(OBJA)))' \
1124 OBJAPPDIR='$(APPC) $(APPCXX) $(APPA)' \
1125 OBJ='$(if $(BUILD_LOCALLY),$(OBJAPPDIR),$(OBJARDUINODIR))' \
1126 DEPS='$(OBJ:.o=.d) applet/$(TARGET).d' LST='$(OBJ:.o=.lst)' \
1127 $target ${BUILD_LOCALLY:+BUILD_LOCALLY=1} "$@"