#!/bin/bash . ./scripts/common.sh if [[ "$VERBOSE" == "1" ]]; then set -ex else set -e fi DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" ELF=${DIR}/build/gw_base.elf if [[ $# -lt 1 ]]; then echo "Usage: flash_multi.sh [address=0] [chip_erase=0]" echo "" echo "address: The address to start writing to in the flash. Default is 0." echo "chip_erase: Forces the use of chip erase. Will erase the whole chip," echo " but may be faster for large flash chips." echo "" echo "Note! This will cut the binary in 832kB chunks and flash them to address and onwards" exit fi IMAGE="$1" ADDRESS=0 if [[ $# -gt 1 ]]; then ADDRESS=$2 fi CHIP_ERASE=0 if [[ $# -gt 2 ]]; then CHIP_ERASE=$3 fi # stat on macOS has different flags if [[ "$(uname -s)" == "Darwin" ]]; then FILESIZE=$(stat -f%z "${IMAGE}") else FILESIZE=$(stat -c%s "${IMAGE}") fi DEFAULT_CHUNK_SIZE_KB=$(( 832 )) DEFAULT_CHUNK_SIZE=$(( DEFAULT_CHUNK_SIZE_KB * 1024 )) CHUNKS=$(( (FILESIZE + DEFAULT_CHUNK_SIZE - 1) / (DEFAULT_CHUNK_SIZE) )) SIZE=$((FILESIZE)) SECTOR_SIZE=$(( 4 * 1024 )) ERASE_BYTES=0 ERASE=1 i=0 while [[ $SIZE -gt 0 ]]; do ADDRESS_HEX=$(printf "0x%08x" $(( ADDRESS + i * DEFAULT_CHUNK_SIZE ))) if [[ $SIZE -gt $(( DEFAULT_CHUNK_SIZE )) ]]; then CHUNK_SIZE=$(( DEFAULT_CHUNK_SIZE )) else CHUNK_SIZE=${SIZE} fi SIZE_HEX=$(printf "0x%08x" ${CHUNK_SIZE}) TMPFILE=$(mktemp /tmp/flash_chunk.XXXXXX) if [[ ! -e $TMPFILE ]]; then echo "Can't create tempfile!" exit 1 fi echo_green "Preparing chunk $((i + 1)) / ${CHUNKS} in file ${TMPFILE}" dd if="${IMAGE}" of="${TMPFILE}" bs=1024 count=$(( (CHUNK_SIZE + 1023) / 1024 )) skip=$(( i * DEFAULT_CHUNK_SIZE_KB )) 2> /dev/null if [[ $CHUNK_SIZE -le 8 ]]; then echo "Chunk size <= 8 bytes, padding with zeros" dd if=/dev/zero of=${TMPFILE} bs=1 count=$(( 9 - CHUNK_SIZE )) seek=${CHUNK_SIZE} 2> /dev/null fi echo_green "Flashing!" if [[ $CHIP_ERASE == 1 ]]; then ERASE_BYTES=0 else ERASE_BYTES=$(( (( SIZE + SECTOR_SIZE - 1 ) / SECTOR_SIZE) * SECTOR_SIZE )) fi # Try to flash 10 times, give up after that. COUNT=10 for RETRY_COUNT in $(seq $COUNT); do if [[ $RETRY_COUNT -gt 1 ]]; then echo_red "Flashing chunk $i failed... power cycle unit and retry? (y/n)" read -n 1 -r if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Aborted." exit 1 fi echo "" echo "Retry count $RETRY_COUNT/10" fi ${DIR}/flashapp.sh ${TMPFILE} ${ADDRESS_HEX} ${SIZE_HEX} ${ERASE} ${ERASE_BYTES} $((i + 1)) ${CHUNKS} && break done if [[ $RETRY_COUNT -eq 10 ]]; then echo "" echo "" echo_red "Programming of the external flash FAILED after 3 tries." echo_red "Please check your debugger and wires connecting to the target." echo "" echo "" exit 1 else echo "" echo "" echo_green "Programming of chunk $((i + 1)) / ${CHUNKS} succeeded." echo "" echo "" fi # Skip erase the following iterations ERASE=0 ERASE_BYTES=0 rm -f ${TMPFILE} SIZE=$(( SIZE - CHUNK_SIZE )) i=$(( i + 1 )) done echo_green "Programming of the external flash succeeded." echo "" echo ""