Merge pull request #84 from algernon/f/tools/keyboardio-builder

Add a new tool to help build the firmware
pull/87/head
Jesse Vincent 8 years ago committed by GitHub
commit 4dc3a9cb39

@ -0,0 +1,12 @@
# -*- mode: sh -*-
generate_keymaps () {
. ${ROOT}/tools/settings.sh
rm -f examples/KeyboardioFirmware/generated/keymaps.h
(cd examples/KeyboardioFirmware/layouts && \
( find . -type f | sort | xargs -n 1 -I % sh -c 'perl ../../../tools/generate_keymaps.pl < % >> ../generated/keymaps.h' ))
}
DEFAULT_SKETCH=KeyboardioFirmware
compile_HOOKS="generate_keymaps"

@ -1,165 +1,10 @@
# Shamelessly stolen from git's Makefile
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
DEVICE_PORT := `ls /dev/ttyACM*`
DEVICE_PORT_BOOTLOADER := `ls /dev/ttyACM*`
ARDUINO_PATH?=/usr/local/arduino
ARDUINO_LOCAL_LIB_PATH?=$(HOME)/Arduino
MD5 = md5sum
RESET_BOARD=stty -F $(DEVICE_PORT) 1200 hupcl
ifeq ($(uname_S),Darwin)
# Port locations
DEVICE_PORT := `ls /dev/cu.usbmodemHID?? /dev/cu.usbmodem14*`
DEVICE_PORT_BOOTLOADER := `ls /dev/cu.usbmodem14*`
# Tools
ARDUINO_PATH=/Applications/Arduino.app/Contents/Java/
ARDUINO_LOCAL_LIB_PATH=$(HOME)/Documents/Arduino
MD5 = md5
RESET_BOARD=stty -f $(DEVICE_PORT) 1200
endif
ARDUINO_TOOLS_PATH=$(ARDUINO_PATH)/hardware/tools
ARDUINO_BUILDER_PATH=$(ARDUINO_PATH)/arduino-builder
AVRDUDE_PATH=$(ARDUINO_TOOLS_PATH)/avr/bin/avrdude
AVRDUDE_CONF_PATH=$(ARDUINO_TOOLS_PATH)/avr/etc/avrdude.conf
AVR_SIZE_PATH=$(ARDUINO_TOOLS_PATH)/avr/bin/avr-size
AVR_NM_PATH=$(ARDUINO_TOOLS_PATH)/avr/bin/avr-nm
AVR_OBJDUMP_PATH=$(ARDUINO_TOOLS_PATH)/avr/bin/avr-objdump
#
#
# Device and sketch info
#
#
BOARD = model01
MCU = atmega32u4
FQBN=keyboardio:avr:model01
SKETCH=KeyboardioFirmware.ino
BOOTLOADER_PATH = $(ARDUINO_LOCAL_LIB_PATH)/hardware/keyboardio/avr/bootloaders/caterina/Caterina.hex
VERBOSE= #-verbose
ARDUINO_TOOLS_PARAM = -tools $(ARDUINO_TOOLS_PATH)
ifeq ($(ARDUINO_TOOLS_PATH),)
ARDUINO_TOOLS_PARAM =
endif
ifdef AVR_GCC_PREFIX
ARDUINO_AVR_GCC_PREFIX_PREF = -prefs "runtime.tools.avr-gcc.path=$(AVR_GCC_PREFIX)"
endif
#
#
# Build
#
#
BUILD_PATH := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'build')
OUTPUT_PATH=./output
ARDUINO_IDE_VERSION=100607
#
#
# Output
#
#
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always)
OUTPUT_FILE_PREFIX=$(SKETCH)-$(GIT_VERSION)
HEX_FILE_PATH=$(OUTPUT_PATH)/$(OUTPUT_FILE_PREFIX).hex
ELF_FILE_PATH=$(OUTPUT_PATH)/$(OUTPUT_FILE_PREFIX).elf
HEX_FILE_WITH_BOOTLOADER_PATH=$(OUTPUT_PATH)/$(OUTPUT_FILE_PREFIX)-with-bootloader.hex
# default action for `make` is `build`
build: compile size
build:
astyle:
find . -type f -name \*.cpp |xargs -n 1 astyle --style=google
find . -type f -name \*.ino |xargs -n 1 astyle --style=google
find . -type f -name \*.h |xargs -n 1 astyle --style=google
generate-keymaps:
-rm examples/KeyboardioFirmware/generated/keymaps.h
cd examples/KeyboardioFirmware/layouts && ( find . -type f | sort | xargs -n 1 -I % sh -c 'perl ../../../tools/generate_keymaps.pl < % >> ../generated/keymaps.h' )
dirs:
mkdir -p $(OUTPUT_PATH)
compile: dirs
$(ARDUINO_BUILDER_PATH) \
-hardware $(ARDUINO_PATH)/hardware \
-hardware $(ARDUINO_LOCAL_LIB_PATH)/hardware \
$(ARDUINO_TOOLS_PARAM) \
-tools $(ARDUINO_PATH)/tools-builder \
-fqbn $(FQBN) \
-libraries $(ARDUINO_LOCAL_LIB_PATH) \
-libraries . \
$(VERBOSE) \
-build-path $(BUILD_PATH) \
-ide-version $(ARDUINO_IDE_VERSION) \
$(ARDUINO_AVR_GCC_PREFIX_PREF) \
examples/KeyboardioFirmware/$(SKETCH)
@cp $(BUILD_PATH)/$(SKETCH).hex $(HEX_FILE_PATH)
@cp $(BUILD_PATH)/$(SKETCH).elf $(ELF_FILE_PATH)
@echo "Firmware is available at $(HEX_FILE_PATH)"
@echo "Have fun!\n"
size: compile
$(AVR_SIZE_PATH) -C --mcu=$(MCU) $(ELF_FILE_PATH)
size-map: compile
$(AVR_NM_PATH) --size-sort -C -r $(ELF_FILE_PATH)
decompile: compile
$(AVR_OBJDUMP_PATH) -d $(ELF_FILE_PATH)
hex-with-bootloader: compile
@cat $(HEX_FILE_PATH) | awk '/^:00000001FF/ == 0' > $(HEX_FILE_WITH_BOOTLOADER_PATH)
@echo "Using $(BOOTLOADER_PATH)"
@$(MD5) $(BOOTLOADER_PATH)
@cat $(BOOTLOADER_PATH) >> $(HEX_FILE_WITH_BOOTLOADER_PATH)
@echo "Combined firmware and bootloader are now at $(HEX_FILE_WITH_BOOTLOADER_PATH)"
@echo "Make sure you have the bootloader version you expect."
@echo "\n\nAnd TEST THIS ON REAL HARDWARE BEFORE YOU GIVE IT TO ANYONE\n\n"
reset-device:
$(RESET_BOARD)
flash: compile reset-device
sleep 3
$(AVRDUDE_PATH) \
-C$(AVRDUDE_CONF_PATH) \
-v \
-p$(MCU) \
-cavr109 \
-P$(DEVICE_PORT_BOOTLOADER) \
-b57600 \
-D \
-Uflash:w:$(HEX_FILE_PATH):i
program:
$(AVRDUDE_PATH) \
-C$(AVRDUDE_CONF_PATH) \
-v \
-p$(MCU) \
-cusbtiny \
-D \
-B 1 \
-Uflash:w:$(HEX_FILE_PATH):i
%:
@tools/keyboardio-builder $@

@ -0,0 +1,334 @@
#! /bin/sh
set -e
firmware_size () {
## This is a terrible hack, please don't hurt me. - algernon
MAX_PROG_SIZE=28672
output="$($@ | grep "\\(Program\\|Data\\):" | sed -e 's,^, - ,' && echo)"
PROGSIZE="$(echo "${output}" | grep Program: | cut -d: -f2 | awk '{print $1}')"
PERCENT="$(echo ${PROGSIZE} ${MAX_PROG_SIZE} | awk "{ printf \"%02.01f\", \$1 / \$2 * 100 }")"
echo "${output}" | sed -e "s,\(Program:.*\)(\([0-9\.]*%\) Full),\1(${PERCENT}% Full),"
}
submodule_update () {
cd $(dirname $0)/..
echo Syncing submodules...
git submodule --quiet sync --recursive
echo Updating submodules...
git submodule --quiet update --init --recursive
echo
for lib in hardware/keyboardio/avr/libraries/* lib/*; do
echo Updating $(basename ${lib})...
(cd $lib; git checkout -q master; git pull -q --ff)
done
}
find_sketch () {
if [ -e "${SOURCEDIR}/.keyboardio-builder.conf" ]; then
. "${SOURCEDIR}/.keyboardio-builder.conf"
fi
SKETCH="${SKETCH:-${DEFAULT_SKETCH}}"
LIBRARY="${LIBRARY:-${SKETCH}}"
for path in "hardware/keyboardio/avr/libraries/Akela-${LIBRARY}/examples/${SKETCH}" \
"examples/${LIBRARY}" \
"src"; do
if [ -f "${path}/${SKETCH}.ino" ]; then
echo "${path}"
return
fi
done
exit 1
}
flash () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
echo "Press ENTER when ready..."
read a
reset_device
sleep 3s
avrdude -q -q -p${MCU} -cavr109 -D -P ${DEVICE_PORT_BOOTLOADER} -b57600 "-Uflash:w:${HEX_FILE_PATH}:i"
}
program () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
echo "Press ENTER when ready..."
read a
avrdude -v \
-p${MCU} \
-cusbtiny \
-D \
-B 1 \
"-Uflash:w:${HEX_FILE_PATH}:i"
}
hex_with_bootloader () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
cat ${HEX_FILE_PATH} | awk '/^:00000001FF/ == 0' > ${HEX_FILE_WITH_BOOTLOADER_PATH}
echo "Using ${BOOTLOADER_PATH}"
${MD5} ${BOOTLOADER_PATH}
cat ${BOOTLOADER_PATH} >> ${HEX_FILE_WITH_BOOTLOADER_PATH}
cat <<EOF
Combined firmware and bootloader are now at ${HEX_FILE_WITH_BOOTLOADER_PATH}
Make sure you have the bootloader version you expect.
And TEST THIS ON REAL HARDWARE BEFORE YOU GIVE IT TO ANYONE
EOF
}
build () {
compile $@
size $@
}
compile () {
. ${ROOT}/tools/settings.sh
install -d "${OUTPUT_PATH}"
echo "Building ${OUTPUT_DIR}/${SKETCH} (${LIB_VERSION}) ..."
${compile_HOOKS}
if [ -d "${ARDUINO_LOCAL_LIB_PATH}/libraries" ]; then
local_LIBS="-libraries \"${ARDUINO_LOCAL_LIB_PATH}/libraries\""
fi
${ARDUINO_BUILDER} \
-compile \
-hardware "${ARDUINO_PATH}/hardware" \
-hardware "${BOARD_HARDWARE_PATH}" \
${ARDUINO_TOOLS_PARAM} \
-tools "${ARDUINO_PATH}/tools-builder" \
-fqbn "${FQBN}" \
${local_LIBS} \
-libraries "${BOARD_HARDWARE_PATH}/.." \
-libraries "${ROOT}" \
${EXTRA_BUILDER_ARGS} \
-build-path "${BUILD_PATH}" \
-ide-version "${ARDUINO_IDE_VERSION}" \
-warnings all \
${ARDUINO_VERBOSE} \
-prefs "compiler.cpp.extra_flags=-std=c++11 -Woverloaded-virtual -Wno-unused-parameter -Wno-unused-variable -Wno-ignored-qualifiers" \
${ARDUINO_AVR_GCC_PREFIX_PARAM} \
"$(find_sketch)/${SKETCH}.ino"
cp "${BUILD_PATH}/${SKETCH}.ino.hex" "${HEX_FILE_PATH}"
cp "${BUILD_PATH}/${SKETCH}.ino.elf" "${ELF_FILE_PATH}"
ln -sf "${OUTPUT_FILE_PREFIX}.hex" "${OUTPUT_PATH}/${SKETCH}-latest.hex"
ln -sf "${OUTPUT_FILE_PREFIX}.elf" "${OUTPUT_PATH}/${SKETCH}-latest.elf"
rm -rf "${BUILD_PATH}"
}
_find_all () {
for plugin in hardware/keyboardio/avr/libraries/Akela-*/examples/* \
examples/* \
src/*.ino; do
if [ -d "$(dirname ${plugin})" ] || [ -f "${plugin}" ]; then
p="$(basename "${plugin}" .ino)"
if [ "${p}" != '*' ]; then
echo "${p}"
fi
fi
done | sort
}
build_all () {
plugins="$(_find_all)"
for plugin in ${plugins}; do
export SKETCH="${plugin}"
export LIBRARY="${plugin}"
(build ${plugin})
done
}
size () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
echo "- Size: firmware/${LIBRARY}/${OUTPUT_FILE_PREFIX}.elf"
firmware_size "${AVR_SIZE}" -C --mcu="${MCU}" "${ELF_FILE_PATH}"
echo
}
size_map () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
"${AVR_NM}" --size-sort -C -r -l "${ELF_FILE_PATH}"
}
decompile () {
. ${ROOT}/tools/settings.sh
if [ ! -e "${HEX_FILE_PATH}" ]; then
compile
fi
"${AVR_OBJDUMP}" -d "${ELF_FILE_PATH}"
}
clean () {
. ${ROOT}/tools/settings.sh
rm -rf "${OUTPUT_PATH}"
}
reset_device () {
. ${ROOT}/tools/settings.sh
${RESET_DEVICE}
}
usage () {
cat <<EOF
Usage: $0 SKETCH commands...
Runs all of the commands in the context of the Sketch.
Available commands:
help
This help screen.
compile
Compiles the sketch.
size
Reports the size of the compiled sketch.
build
Runs compile and report-size.
clean
Cleans up the output directory.
size-map
Displays the size map for the sketch.
decomple
Decompile the sketch.
reset-device
Reset the device.
flash
Flashes the firmware using avrdude.
build-all
Build all Sketches we can find.
EOF
}
help () {
usage
}
if [ $# -lt 1 ]; then
usage
exit 1
fi
## Parse the command-line
## - anything that has a =, is an env var
## - from the remaining stuff, the first one is the Library/Sketch
## - everything else are commands
##
## - if there is only one argument, that's a command
ROOT="$(cd $(dirname $0)/..; pwd)"
export ROOT
export SOURCEDIR="$(pwd)"
if [ -e "${HOME}/.keyboardio-builder.conf" ]; then
. "${HOME}/.keyboardio-builder.conf"
fi
if [ -e "${SOURCEDIR}/.keyboardio-builder.conf" ]; then
. "${SOURCEDIR}/.keyboardio-builder.conf"
fi
cmds=""
## Export vars
for i in $(seq 1 $#); do
v="$1"
shift
case "${v}" in
*=*)
export ${v}
;;
*)
cmds="${cmds} ${v}"
;;
esac
done
set -- ${cmds}
if [ $# -eq 1 ]; then
cmd="$(echo $1 | tr '-' '_')"
${cmd}
exit $?
fi
SKETCH="$1"
shift
if [ "${SKETCH}" = "default" ]; then
SKETCH="${DEFAULT_SKETCH}"
fi
cmds=""
for i in $(seq 1 $#); do
cmds="${cmds} $(echo $1 | tr '-' '_')"
shift
done
LIBRARY="${SKETCH}"
export SKETCH
export LIBRARY
for cmd in ${cmds}; do
${cmd}
done

@ -0,0 +1,85 @@
## NEEDS: LIBRARY, SKETCH, ROOT, SOURCEDIR
## Should be included when the current directory is the dir of the Sketch.
case "$0" in
*/settings.sh)
echo "This file must be included, never run directly!" >&2
exit 1
;;
esac
SKETCH="${SKETCH:-${DEFAULT_SKETCH}}"
LIBRARY="${LIBRARY:-${SKETCH}}"
if [ -z "${SKETCH}" ] || [ -z "${LIBRARY}" ] || [ -z "${ROOT}" ] || [ -z "${SOURCEDIR}" ]; then
echo "SKETCH, LIBRARY, SOURCEDIR, and ROOT need to be set before including this file!" >&2
exit 1
fi
BOARD="model01"
MCU="atmega32u4"
FQBN="keyboardio:avr:model01"
DEVICE_PORT="$(ls /dev/ttyACM* 2>/dev/null || echo '')"
DEVICE_PORT_BOOTLOADER="$(ls /dev/ttyACM* 2>/dev/null || echo '')"
RESET_BOARD="stty -F ${DEVICE_PORT} 1200 hupcl"
ARDUINO_PATH="${ARDUINO_PATH:-/usr/local/arduino}"
ARDUINO_LOCAL_LIB_PATH="${ARDUINO_LOCAL_LIB_PATH:-${HOME}/Arduino}"
ARDUINO_TOOLS_PATH="${ARDUINO_TOOLS_PATH:-${ARDUINO_PATH}/hardware/tools}"
ARDUINO_BUILDER="${ARDUINO_BUILDER:-${ARDUINO_PATH}/arduino-builder}"
ARDUINO_IDE_VERSION="100607"
BOARD_HARDWARE_PATH="${BOARD_HARDWARE_PATH:-${ARDUINO_LOCAL_LIB_PATH}/hardware}"
BOOTLOADER_PATH="${BOARD_HARDWARE_PATH}/keyboardio/avr/bootloaders/caterina/Caterina.hex"
AVR_SIZE="${AVR_SIZE:-${ARDUINO_TOOLS_PATH}/avr/bin/avr-size}"
AVR_NM="${AVR_NM:-${ARDUINO_TOOLS_PATH}/avr/bin/avr-nm}"
AVR_OBJDUMP="${AVR_OBJDUMP:-${ARDUINO_TOOLS_PATH}/avr/bin/avr-objdump}"
MD5="md5sum"
BUILD_PATH="${BUILD_PATH:-$(mktemp -d 2>/dev/null || mktemp -d -t 'build')}"
OUTPUT_DIR="${OUTPUT_DIR:-output/${LIBRARY}}"
OUTPUT_PATH="${OUTPUT_PATH:-${SOURCEDIR}/${OUTPUT_DIR}}"
GIT_VERSION="$(cd $(find_sketch); git describe --abbrev=4 --dirty --always)"
LIB_VERSION="$(cd $(find_sketch); (grep version= ../../library.properties 2>/dev/null || echo version=0.0.0) | cut -d= -f2)-g${GIT_VERSION}"
OUTPUT_FILE_PREFIX="${SKETCH}-${LIB_VERSION}"
HEX_FILE_PATH="${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}.hex"
HEX_FILE_WITH_BOOTLOADER_PATH="${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}-with-bootloader.hex"
ELF_FILE_PATH="${OUTPUT_PATH}/${OUTPUT_FILE_PREFIX}.elf"
ARDUINO_TOOLS_PARAM="-tools ${ARDUINO_TOOLS_PATH}"
if [ -z "${ARDUINO_TOOLS_PATH}" ]; then
ARDUINO_TOOLS_PARAM=""
fi
if [ ! -z "${AVR_GCC_PREFIX}" ]; then
ARDUINO_AVR_GCC_PREFIX_PARAM="-prefs \"runtime.tools.avr-gcc.path=${AVR_GCC_PREFIX}\""
fi
if [ ! -z "${VERBOSE}" ] && [ "${VERBOSE}" -gt 0 ]; then
ARDUINO_VERBOSE="-verbose"
else
ARDUINO_VERBOSE="-quiet"
fi
## Platform-specific overrides
# Shamelessly stolen from git's Makefile
uname_S=$(uname -s 2>/dev/null || echo not)
if [ "${uname_S}" = "Darwin" ]; then
DEVICE_PORT="$(ls /dev/cu.usbmodemHID?? /dev/cu.usbmodem14*)"
DEVICE_PORT_BOOTLOADER="$(ls /dev/cu.usbmodem14*)"
ARDUINO_PATH="/Applications/Arduino.app/Contents/Java/"
ARDUINO_LOCAL_LIB_PATH="${HOME}/Documents/Arduino"
MD5="md5"
RESET_BOARD="stty -f ${DEVICE_PORT} 1200"
fi
Loading…
Cancel
Save