I am playing around with the new avrlib-c 1.6.1 feature that makes it possible to specify fuse settings in the source code.
The idea is to make use of this feature from within a project's Makefile under Linux (and later to do the same for lock bits). I want to do it in two steps:
1) Have a script that extracts the fuse data from an .elf file and generates an avrdude command line from that data
2) Call the above script from within a Makefile target.
I couldn't find much documentation about the feature's implementation details, only what is in the avrlib-c documentation. So I'd like to check if I am on the right track with the following script.
out2dude-fuse:
#!/bin/bash # # Extracts information from .fuse section in elf # binaries and generates corresponding avrdude # command to set, get, or verify these fuse settings. # OBJDUMP=avr-objdump FUSE_SECTION=.fuse dude=avrdude dudeopt="" dudemode="w" file="a.out" MyName=$(basename "$0") usage() { cat <<! usage: $MyName [-Wd]* [-m ] [-p ] [ ] ! } while [ $# -gt 0 ] ; do case "$1" in -Wd) [ $# -lt 2 ] && { usage; exit 1; } dudeopt="$dudeopt $2" shift ;; -m) [ $# -lt 2 ] && { usage; exit 1; } dudemode="$2" shift ;; -p) [ $# -lt 2 ] && { usage; exit 1; } dude="$2" shift ;; -h) usage exit 0 ;; --) shift break ;; -*) usage exit 1 ;; *) break ;; esac shift done [ $# -eq 1 ] && { file="$1"; shift; } [ $# -ne 0 ] && { usage; exit 1; } $OBJDUMP --full-contents --section=$FUSE_SECTION "$file" | \ awk -v "program=$dude" \ -v "options=$dudeopt" \ -v "mode=$dudemode" \ -v "file=$file" \ -v "myname=$MyName" \ ' /\.fuse:/ { p++; next } p && /^ [0-9A-Fa-f]/ { low = substr($2, 1, 2) high = substr($2, 3, 2) ext = substr($2, 5, 2) exit } END { if(low == "") { out = "echo \"" myname ": " file ": no fuse data found.\"; exit 0" } else { out = program " " options if(high == "") { out = out " -U fuse:" mode ":0x" low ":m" } else { out = out " -U lfuse:" mode ":0x" low ":m -U hfuse:" mode ":0x" high ":m" if(ext != "") { out = out " -U efuse:" mode ":0x" ext ":m" } } } print out print myname ": command assembled: " out > "/dev/stderr" } ' #
For those unfamiliar with awk, I check for the start of the .fuse section. Inside the section I ignore the section address. I split the data into a maximum of three parts: First byte the low fuse (or just the fuse) byte, second byte (if any) the high fuse byte, third data byte (if any) the extended fuse byte. I verified this order empirically, but I'd like to get some confirmation that this is how things are done.
And here is a fragment of a makefile, showing how I gonna call the script:
OUT2DUDE_FUSE=out2dude-fuse program-fuse: $(TARGET).elf exec $$($(OUT2DUDE_FUSE) -p $(AVRDUDE) -Wd "$(AVRDUDE_BASIC) $(AVRDUDE_VERBOSE)" $(TARGET).elf) .PHONY: program-fuse