#!/usr/bin/env bash # published under GNU General Public License, version 3 (GPL-3.0) # authors Hans Eirik Bull and Stefan Rueger, 2024 progname=$(basename "$0") tfiles=$(dirname "$0")/test_files tfiles=$(printf "%q" "$tfiles") # Quote directory string in case there are spaces etc benchmark=0 # If set to 1 does benchmark testing only avrdude_conf='' # Configuration for every run, eg, '-C path_to_avrdude_conf' delay=0.75 # Some programmers need a delay between AVRDUDE calls avrdude_bin=avrdude # Executable list_only=0 # Normal run declare -a pgm_and_target=() # Array with test option strings, eg, "-c dryrun -p m328p" skip_eeprom=0 # Do not skip EEPROM tests for bootloaders by default tmp=/dev/shm # Temporary RAM directory addtests=0 # Add dryrun/dryboot test cases? verbose=0 # Do not show AVRDUDE errors and warnings by default Usage() { cat <} Function: test AVRDUDE for certain programmer and part combinations Options: -b carry out four benchmark tests and summarise them -c additional configuration options used for all runs -d delay between test commands (default $delay seconds) -e set path of AVRDUDE executable (default $avrdude_bin) -l list test commands but do not execute them -p can be used multiple times, overrides default tests -s skip EEPROM tests for bootloaders -t temporary directory (default $tmp) -T Add dryrun/dryboot test cases to test $progname -v verbose: show AVRDUDE error and warning messages -? or -h show this help text Note: some Windows environments require the option -t . or similar Examples: \$ $progname -s -p "-c dryboot -p t13" -p "-c dryrun -p m4809" \$ $progname -d 2 -p "-cjtag2updi -patmega4809 -Pusb:2341:0058 -r" END } while getopts ":\?hbc:d:e:lp:st:Tv" opt; do case ${opt} in b) benchmark=1 ;; c) avrdude_conf="$OPTARG" ;; d) delay="$OPTARG" ;; e) avrdude_bin="$OPTARG" ;; l) list_only=1 ;; p) pgm_and_target+=("$OPTARG") ;; s) skip_eeprom=1 ;; t) tmp="$OPTARG" ;; T) addtests=1 ;; v) verbose=1 ;; --) shift; break ;; [h?]) Usage; exit 0 ;; \?) echo "Invalid option: -$OPTARG" 1>&2 Usage; exit 1 ;; : ) echo "Invalid option: -$OPTARG requires an argument" 1>&2 Usage; exit 1 ;; esac done shift $((OPTIND -1)) if [[ $addtests -eq 1 ]]; then pgm_and_target+=( "-c dryrun -p at89s51" "-c dryrun -p at89s52" "-c dryboot -p at90can32" "-c dryrun -p at90can32" "-c dryboot -p at90s1200" "-c dryboot -p at90s2313" "-c dryrun -p at90s2313" "-c dryboot -p at90s4414" "-c dryrun -p at90s4414" "-c dryboot -p at90s8515" "-c dryrun -p at90s8515" "-c dryboot -p atmega103" "-c dryrun -p atmega103" "-c dryboot -p atmega128rfr2" "-c dryrun -p atmega128rfr2" "-c dryboot -p atmega163" "-c dryrun -p atmega163" "-c dryboot -p atmega16" "-c dryrun -p atmega16" "-c dryboot -p atmega16hva" "-c dryrun -p atmega16hva" "-c dryboot -p atmega2560" "-c dryrun -p atmega2560" "-c dryboot -p atmega256rfr2" "-c dryrun -p atmega256rfr2" "-c dryboot -p atmega406" "-c dryrun -p atmega406" "-c dryboot -p atmega4808" "-c dryrun -p atmega4808" "-c dryboot -p atmega640" "-c dryrun -p atmega640" "-c dryboot -p atmega64" "-c dryrun -p atmega64" "-c dryboot -p atmega64hve2" "-c dryrun -p atmega64hve2" "-c dryboot -p atmega64rfr2" "-c dryrun -p atmega64rfr2" "-c dryboot -p atmega808" "-c dryrun -p atmega808" "-c dryboot -p atmega8" "-c dryrun -p atmega8" "-c dryrun -p attiny11" "-c dryboot -p attiny13" "-c dryrun -p attiny13" "-c dryboot -p attiny1604" "-c dryrun -p attiny1604" "-c dryboot -p attiny202" "-c dryrun -p attiny202" "-c dryrun -p attiny20" "-c dryboot -p attiny261" "-c dryrun -p attiny26" "-c dryrun -p attiny28" "-c dryboot -p attiny3216" "-c dryrun -p attiny3216" "-c dryboot -p attiny3224" "-c dryrun -p attiny3224" "-c dryboot -p attiny402" "-c dryrun -p attiny402" "-c dryrun -p attiny40" "-c dryboot -p attiny461" "-c dryrun -p attiny461" "-c dryboot -p attiny48" "-c dryrun -p attiny48" "-c dryrun -p attiny4" "-c dryboot -p attiny804" "-c dryrun -p attiny804" "-c dryboot -p attiny828" "-c dryrun -p attiny828" "-c dryboot -p attiny88" "-c dryrun -p attiny88" "-c dryrun -p attiny9" "-c dryboot -p atxmega128a4" "-c dryrun -p atxmega128a4" "-c dryboot -p atxmega128a4u" "-c dryrun -p atxmega128a4u" "-c dryboot -p atxmega128c3" "-c dryrun -p atxmega128c3" "-c dryboot -p atxmega16a4u" "-c dryrun -p atxmega16a4u" "-c dryboot -p atxmega16e5" "-c dryrun -p atxmega16e5" "-c dryboot -p atxmega192a1" "-c dryrun -p atxmega192a1" "-c dryboot -p atxmega192c3" "-c dryrun -p atxmega192c3" "-c dryboot -p atxmega256a1" "-c dryrun -p atxmega256a1" "-c dryboot -p atxmega256c3" "-c dryrun -p atxmega256c3" "-c dryboot -p atxmega32a4u" "-c dryrun -p atxmega32a4u" "-c dryboot -p atxmega32e5" "-c dryrun -p atxmega32e5" "-c dryboot -p atxmega384c3" "-c dryrun -p atxmega384c3" "-c dryboot -p atxmega64a4" "-c dryrun -p atxmega64a4" "-c dryboot -p atxmega64a4u" "-c dryrun -p atxmega64a4u" "-c dryboot -p atxmega8e5" "-c dryrun -p atxmega8e5" "-c dryboot -p avr128da28" "-c dryrun -p avr128da28" "-c dryboot -p avr16ea28" "-c dryrun -p avr16ea28" "-c dryboot -p avr32da28" "-c dryrun -p avr32da28" "-c dryboot -p avr32ea28" "-c dryrun -p avr32ea28" "-c dryboot -p avr64da28" "-c dryrun -p avr64da28" "-c dryboot -p avr64dd14" "-c dryrun -p avr64dd14" "-c dryboot -p avr64du28" "-c dryrun -p avr64du28" "-c dryboot -p avr64ea28" "-c dryrun -p avr64ea28" "-c dryboot -p avr8ea28" "-c dryrun -p avr8ea28" "-c dryboot -p lgt8f328p" "-c dryrun -p lgt8f328p" ) fi if [[ ${#pgm_and_target[@]} -eq 0 ]]; then # Default tests in absence of -p pgm_and_target+=( "-cpkobn_updi -B1 -patmega3208" "-cpkobn_updi -B1 -patmega3209" "-cpkobn_updi -B1 -patmega4808" "-cjtag2updi -patmega4809 -Pusb:2341:0058 -r" "-cpkobn_updi -B1 -pattiny3217" "-cpkobn_updi -B1 -pavr128da48" "-cpkobn_updi -B1 -pavr128db48" "-cpkobn_updi -B1 -pavr64dd32" "-cpkobn_updi -B1 -pavr64ea48" "-cpkobn_updi -B1 -pavr16eb32" "-cxplainedmini_isp -patmega328pb" "-cxplainedmini_updi -pattiny1616" "-cxplainedmini_updi -pattiny3217" "-cxplainedpro_updi -B1 -pattiny817" "-cxplainedpro_pdi -B0.5 -patxmega128a1u" "-cxplainedpro -B4MHz -patmega256rfr2" ) fi arraylength=${#pgm_and_target[@]} if ! type "$avrdude_bin" >/dev/null 2>&1; then echo "$progname: cannot execute $avrdude_bin" type "$avrdude_bin" exit 1 fi [[ -d $tmp && -w $tmp ]] || tmp=/tmp # Fall back to /tmp if tmp directory unusable status=$(mktemp "$tmp/$progname.status.XXXXXX") logfile=$(mktemp "$tmp/$progname.log.XXXXXX") outfile=$(mktemp "$tmp/$progname.out.XXXXXX") tmpfile=$(mktemp "$tmp/$progname.tmp.XXXXXX") resfile=$(mktemp "$tmp/$progname.res.XXXXXX") trap "rm -f $status $logfile $outfile $tmpfile $resfile" EXIT echo -n "Testing $(type -p "$avrdude_bin")" $avrdude_bin -v 2>&1 | grep '[vV]ersion' | sed 's/^.* [Vv]ersion//' | head -n1 > "$outfile" if test -s "$outfile"; then cat "$outfile" else echo ": error obtaining version from '$avrdude_bin -v'" $avrdude_bin -v exit 1 fi devnull=$tmpfile # Cannot use /dev/null as file in Windows avrdude TIMEFORMAT=%R # time built-in only returns elapsed wall-clock time elapsed=-1 # Global variable holding time of last execute command in seconds bench_t=-1 # Copy of global variable holding time of last execute command command=(sleep 0.1) # Array with AVRDUDE command emulated=0 # Is programmer dryrun or dryboot, ie, programming is emulated? # Execute args as command, set $elapsed and return exit value of command; don't call in a subshell execute () { if [[ $list_only -eq 1 ]]; then echo "\$ ${command[@]}" | sed "s/ -l [^ ]* / /" | tr -s " " return 0; fi [[ $emulated -eq 0 && $elapsed != -1 ]] && sleep "$delay" # These shenanigans keep stdout, stderr and the exit code of the command { read elapsed < <({ time { eval "$@"; echo $? >"$status"; } 2>&4 4>&-; } 4>&2 2>&1 >&3 3>&-); } 3>&1 return $(cat "$status") } # Evaluate condition, print execution time and success or failure result () { local ret; eval "$@" && ret=0 || ret=1 if [[ $list_only -eq 0 ]]; then if [[ $ret -eq 0 ]]; then echo ✅ "$(printf '%7.3f s' $elapsed): $specify" bench_t=$(printf '%5.2f s' $elapsed) else echo ❌ "$(printf '%7.3f s' $elapsed): $specify (failed command below)" echo "\$ ${command[@]}" | sed "s/ -l [^ ]* / /" | tr -s " " fail=true bench_char="❌" bench_t=error exitstate=1 [[ $emulated -eq 0 ]] && sleep 4 # Let the hw settle down before next test fi [[ $verbose -eq 1 ]] && { cat $logfile $outfile; } else cat $outfile fi cp /dev/null $outfile; cp /dev/null $logfile; elapsed=-999; specify="unknown"; command=(sleep 0.1) return $ret } nofusetest=(-pattiny11/ -pt11/ -pattiny12/ -pt12/ -pattiny15/ -pt15/ -pat89s51/ -p89s51/ -pat89s52/ -p89s52/ -pat90s1200/ -p1200/ -pat90s4414/ -p4414/ -pat90s2313/ -p2313/ -pat90s2333/ -p2333/ -pat90s2343/ -p2343/ -pat90s2323/ -p2323/ -pattiny22/ -pt22/ -pat90s4433/ -p4433/ -pat90s8515/ -p8515/ -pat90s8535/ -p8535/ -pat90s4434/ -p4434/ -patmega163/ -pm163/ -patmega161/ -pm161/ -pattiny28/ -pt28/ -patxmega64a4/ -px64a4/ -patxmega128a4/ -px128a4/ -patxmega192a1/ -px192a1/ -patxmega256a1/ -px256a1/ -pat32uc3a0512/ -puc3a0512/ -pavr8ea28/ -pavr8ea28/ -pavr8ea32/ -pavr8ea32/ -plgt8f88p/ -plgt8f88p/ -plgt8f168p/ -plgt8f168p/ -plgt8f328p/ -plgt8f328p/) if [[ $benchmark -eq 1 ]]; then echo echo The benchmark shows the wall clock time of avrdude carrying out the following tasks echo " -" Fl-ewv: erase flash, then write a sketch with three sections separated by holes, and verify echo " -" Fl-r: read the entire flash memory and write to file echo " -" EE-wv: write data to EEPROM with two data sections separated by a hole, and verify echo " -" EE-r: read the entire EEPROM memory and write to file echo echo The sketch and data payload is roughly one sixth of the respective memory size echo echo '| | `-c pgm` | `-p part` | Fl-ewv | Fl-r | EE-wv | EE-r | Comments |' echo '|:-:|--:|--:|--:|--:|--:|--:|:--|' fi exitstate=0 for (( p=0; p<$arraylength; p++ )); do # Isolate programmer and part (assumes -c prog or -cprog but not sth more tricky such as -qc prog) programmer=$(echo ${pgm_and_target[$p]} | sed 's/.* *-c *\([^ ]*\) *.*/\1/g' | tr A-Z a-z) part=$(echo ${pgm_and_target[$p]} | sed 's/.* *-p *\([^ ]*\) *.*/\1/g') lpart=$(echo $part | tr A-Z a-z) rest=$(echo ${pgm_and_target[$p]} | sed -e's/ *-[cpP] *[^ ]* */ /g' -e's/ */ /g') emulated=0 [[ "$programmer" == dryrun || "$programmer" == dryboot ]] && emulated=1 if [[ $list_only -eq 1 ]]; then [[ p -ne 0 ]] && echo echo "# ${pgm_and_target[$p]}" key='' else echo "Prepare \"${pgm_and_target[$p]}\" and press 'enter' or 'space' to continue. Press any other key to skip" read -n1 -s -r -p $'' key [[ $emulated -eq 0 ]] && sleep 0.15 # Debounce key when not using dryrun/dryboot fi bench_char="✅"; bench_t_flwr=--; bench_t_flrd=--; bench_t_eewr=--; bench_t_eerd=-- if [ "$key" == '' ]; then fail=false avrdude=($avrdude_bin -l $logfile $avrdude_conf -qq ${pgm_and_target[$p]}) # Get flash and EEPROM size in bytes and make sure the numbers are in dec form flash_size=$($avrdude_bin $avrdude_conf -c dryrun -p $part -T 'part -m' 2>/dev/null | grep flash | awk '{print $2}') bench_flwr_size=$((flash_size/6)) # Approximate(!) size of file holes_rjmp_loops_${flash_size}B.hex ee_size=$($avrdude_bin $avrdude_conf -c dryrun -p $part -T 'part -m' 2>/dev/null | grep eeprom | awk '{print $2}') bench_eewr_size=$((ee_size/6)) # Approximate(!) size of file holes_pack_my_box_${ee_size}B.hex if [[ -z "$flash_size" ]]; then echo "Cannot detect flash; check that \"${pgm_and_target[$p]}\" are valid avrdude options; skipping this test" continue fi # Memories that may or may not be present usersig_size=$(${avrdude[@]} -cdryrun -T 'part -m' 2>/dev/null | grep usersig | awk '{print $2}') # R/W # Is the to be tested programmer for a bootloader? is_bootloader=0 if [ -n "$programmer" ]; then ($avrdude_bin $avrdude_conf -c"$programmer"/At 2>/dev/null | grep -q prog_modes.PM_SPM) && is_bootloader=1 fi # Should we test fuses? fusetest=1 [[ -n "$lpart" && "${nofusetest[@]}" =~ -p"$lpart/" ]] && fusetest=0 # Should EEPROM test be carried out? check_eeprom=1 [[ -z "$ee_size" ]] && check_eeprom=0 [[ $is_bootloader -eq 1 && $skip_eeprom -eq 1 ]] && check_eeprom=0 ##### # Dryrun tests for high-level progrmmer-independent tests (only for -m2560 or similar) # if [[ "$programmer" == dryrun && $flash_size -eq 262144 && $benchmark -eq 0 ]]; then # Raw test specify="flash raw format -T/-U write/verify cola-vending-machine.raw" command=(${avrdude[@]} -T '"erase flash; write flash -512 0xc0cac01a 0xcafe \"secret Coca .bin recipe\""' -U flash:w:$tfiles/cola-vending-machine.raw -T '"write flash -1024 \"Hello World\""') execute "${command[@]}" > $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] specify="flash extended address and hole test" command=(${avrdude[@]} -U flash:w:$tfiles/blink-mega2560+lext-test.hex) execute "${command[@]}" result [ $? == 0 ] # Test binary, octal, decimal, hexadecimal and R number lists for I/O numsys() { # this function replaces constant associative array, as # macos bash does not support associative arrays. case "$1" in b) echo "binary" ;; o) echo "octal" ;; d) echo "decimal" ;; h) echo "hexadecimal" ;; R) echo "R" ;; esac } for fmt in b o d h R; do specify="flash writing $(numsys "$fmt") numbers" command=(${avrdude[@]} -U $tfiles/urboot_m2560_1s_x16m0_115k2_uart0_rxe0_txe1_led+b7_pr_ee_ce.hex -T '"write flash 0x3fd00 0xc0cac01a 0xcafe \"secret Coca Cola recipe\""' -U flash:w:$tfiles/cola-vending-machine.raw -U flash:r:$tmpfile:$fmt) execute "${command[@]}" result [ $? == 0 ] specify="flash reading and verifying $(numsys "$fmt") numbers" command=(${avrdude[@]} -U flash:w:$tmpfile:$fmt -U flash:r:$resfile:r) execute "${command[@]}" result cmp -s $resfile $tfiles/expected-flash-m2560.raw cp /dev/null $tmpfile; cp /dev/null $resfile done specify="flash writing srec format" command=(${avrdude[@]} -U $tfiles/urboot_m2560_1s_x16m0_115k2_uart0_rxe0_txe1_led+b7_pr_ee_ce.hex -T '"write flash 0x3fd00 0xc0cac01a 0xcafe \"secret Coca Cola recipe\""' -U flash:w:$tfiles/cola-vending-machine.raw -U flash:r:$tmpfile:s) execute "${command[@]}" result [ $? == 0 ] specify="flash reading and verifying srec format file" command=(${avrdude[@]} -U flash:w:$tmpfile:s -U flash:v:$tfiles/expected-flash-m2560.raw:r) execute "${command[@]}" result [ $? == 0 ] cp /dev/null $tmpfile fi ##### # Fuse test (bootloaders usually cannot set fuses) # if [[ $is_bootloader -ne 1 && $fusetest -eq 1 && $benchmark -eq 0 ]]; then if [ -n "$ee_size" ]; then specify="fuse access: clear, set and read eesave fuse bit" command=(${avrdude[@]} -T '"config eesave=0; config eesave=1; config eesave"') else specify="fuse access: clear, set and read wdton fuse bit" command=(${avrdude[@]} -T '"config wdton=0; config wdton=1; config wdton"') fi execute "${command[@]}" > $outfile fusebit=$(grep ^config $outfile | awk '{print $4}') sed -e/^config/d -e/"> "/d $outfile > ${outfile}-2 mv ${outfile}-2 $outfile result [[ '"$fusebit"' == 1 '&&' ! -s $outfile '&&' ! -s $logfile ]] if [ -n "$ee_size" ]; then specify="fuse access: set eesave fusebit to delete EEPROM on chip erase" command=(${avrdude[@]} -T '"config eesave=ee*erased"') execute "${command[@]}" > $outfile sed -e/^config/d -e/"> "/d $outfile > ${outfile}-2 mv ${outfile}-2 $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] fi fi ###### # Chip erase for defined initial state # if [ $benchmark -eq 0 ]; then specify="chip erase" # Emulated chip erase needs a tiny file be uploaded command=(${avrdude[@]} -e -FAU flash:w:0xff:m) execute "${command[@]}" result [ $? == 0 ] fi ##### # Flash test: a relatively difficult file with two code blocks and one data block with holes # specify="flash -U write/verify holes_rjmp_loops_${flash_size}B.hex" command=(${avrdude[@]} -Uflash:w:$tfiles/holes_rjmp_loops_${flash_size}B.hex) execute "${command[@]}" result [ $? == 0 ] if [[ $? != 0 && $benchmark -eq 0 ]]; then # Not working? try a file without holes specify="flash -U write/verify rjmp_loops_for_bootloaders_${flash_size}B.hex" command=(${avrdude[@]} -Uflash:w:$tfiles/rjmp_loops_for_bootloaders_${flash_size}B.hex) execute "${command[@]}" result [ $? == 0 ] fi bench_t_flwr=$bench_t if [[ $benchmark -eq 1 ]]; then specify="flash -U read all flash" command=(${avrdude[@]} -Uflash:r:$devnull) execute "${command[@]}" result [ $? == 0 ] bench_t_flrd=$bench_t fi if [[ $benchmark -eq 0 ]]; then specify="flash -T write/verify holes_rjmp_loops_${flash_size}B.hex" command=(${avrdude[@]} -T '"write flash '$tfiles/holes_rjmp_loops_${flash_size}B.hex:a'"') execute "${command[@]}" > $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] if [ $? != 0 ]; then # Not working? try a file without holes specify="flash -T write/verify rjmp_loops_for_bootloaders_${flash_size}B.hex" command=(${avrdude[@]} -T '"write flash '$tfiles/rjmp_loops_for_bootloaders_${flash_size}B.hex:a'"') execute "${command[@]}" > $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] fi fi ###### # EEPROM tests # if [ $check_eeprom -eq 1 ]; then if [ $benchmark -eq 1 ]; then specify="eeprom -U write/verify holes_pack_my_box_${ee_size}B.hex" command=(${avrdude[@]} -Ueeprom:w:$tfiles/holes_pack_my_box_${ee_size}B.hex) execute "${command[@]}" result [ $? == 0 ] bench_t_eewr=$bench_t specify="eeprom -U read all" command=(${avrdude[@]} -Ueeprom:r:$devnull) execute "${command[@]}" result [ $? == 0 ] bench_t_eerd=$bench_t else # -U cannot cope with EEPROMs that are unable to set cleared bits but # the terminal can if the eesave fuse makes chip erase erase EEPROM specify="eeprom check whether programmer can flip 0s to 1s" command=(${avrdude[@]} -Ueeprom:w:0x55:m -Ueeprom:w:0xaa:m) execute "${command[@]}" result [ $? == 0 ] if [ $? == 0 ]; then # OK, try a file with holes specify="eeprom -U write/verify holes_pack_my_box_${ee_size}B.hex" command=(${avrdude[@]} -Ueeprom:w:$tfiles/holes_pack_my_box_${ee_size}B.hex) execute "${command[@]}" result [ $? == 0 ] if [ $? != 0 ]; then # Not working? try a file without holes specify="eeprom -U write/verify the_quick_brown_fox_${ee_size}B.hex" command=(${avrdude[@]} -Ueeprom:w:$tfiles/the_quick_brown_fox_${ee_size}B.hex) execute "${command[@]}" result [ $? == 0 ] fi else echo "# ... the next test may therefore take longer" fi specify="eeprom -T write/verify holes_{the_five_boxing_wizards,pack_my_box}_${ee_size}B.hex" command=(${avrdude[@]} -T '"write eeprom '$tfiles/holes_the_five_boxing_wizards_${ee_size}B.hex:a'"' -T flush -T '"write eeprom '$tfiles/holes_pack_my_box_${ee_size}B.hex:a'"') execute "${command[@]}" > $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] if [ $? != 0 ]; then # Not working? try a file without holes specify="eeprom -T write/verify lorem_ipsum_${ee_size}B.srec" command=(${avrdude[@]} -T '"write eeprom '$tfiles/lorem_ipsum_${ee_size}B.srec:a'"') execute "${command[@]}" > $outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] fi fi fi ###### # Chip erase and verify # if [[ $benchmark -eq 0 ]]; then specify="chip erase and spot check flash is actually erased" command=(${avrdude[@]} -e -FAU flash:w:0xff:m -U flash:v:$tfiles/holes_flash_0xff_${flash_size}B.hex) execute "${command[@]}" result [ $? == 0 ] if [[ $? == 0 && $check_eeprom -eq 1 && $is_bootloader -eq 0 ]]; then specify="spot check eeprom is erased, too" command=(${avrdude[@]} -Ueeprom:v:$tfiles/holes_eeprom_0xff_${ee_size}B.hex) execute "${command[@]}" result [ $? == 0 ] fi fi ###### # Write and verify random data to usersig if present # if [[ -n "$usersig_size" && $is_bootloader -ne 1 && $benchmark -eq 0 ]]; then specify="usersig -T/-U write/read random_data_${usersig_size}B.bin" command=(${avrdude[@]} -T '"erase usersig; write usersig '$tfiles/random_data_${usersig_size}B.bin'"' -T flush -U usersig:r:$tmpfile:r -U usersig:v:$tmpfile:r -T '"erase usersig"' -T flush -U usersig:v:$tfiles/0xff_${usersig_size}B.hex:i) execute "${command[@]}" >$outfile result [[ ! -s $outfile '&&' ! -s $logfile ]] '&&' cmp -s "$tfiles/random_data_${usersig_size}B.bin" "$tmpfile" cp /dev/null $tmpfile fi if [ $benchmark -eq 1 ]; then echo "|$bench_char|$programmer|$part|$bench_t_flwr|$bench_t_flrd|$bench_t_eewr|$bench_t_eerd|$rest|" fi if [ $fail == true ]; then echo '' read -rep "One or more AVRDUDE \"${pgm_and_target[$p]}\" tests failed. Do you want to retry this particular test? (y/n): " choice case "$choice" in [yY]) p=$p-1; # Re-run the same for-loop iterator ;; *) # Continue with the next hardware setup in the list ;; esac fi fi #key done #for exit $exitstate