Skip to content

Instantly share code, notes, and snippets.

@DNA64
Last active April 23, 2023 00:02
Show Gist options
  • Save DNA64/6117fb79aabdd126f0d5b4277a25c2ad to your computer and use it in GitHub Desktop.
Save DNA64/6117fb79aabdd126f0d5b4277a25c2ad to your computer and use it in GitHub Desktop.
[Request] Custom flash_multi.sh script that attempts to retry failed flash attempts 3x automatically without user interaction. -Untested/WIP
#!/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 <binary to flash> [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
# The system retries flashing failed chunks 3 times automatically, then 7 times with user input. It stops after 10 total attempts.
COUNT=10
AUTO_RETRY=3
for RETRY_COUNT in $(seq $COUNT); do
if [[ $RETRY_COUNT -gt 1 ]]; then
if [[ $RETRY_COUNT -le $AUTO_RETRY ]]; then
echo "Automatically retrying flashing chunk $i..."
${DIR}/flashapp.sh ${TMPFILE} ${ADDRESS_HEX} ${SIZE_HEX} ${ERASE} ${ERASE_BYTES} $((i + 1)) ${CHUNKS} && break
else
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
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 multiple tries."
echo_red "Please check your debugger and wires connecting to the target."
echo_red "Verify your chips status in the retro-go debug menu."
echo_red "or Run 'make flash_test' from the retro-go folder."
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 ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment