integrating avrlib-c 1.6.1 fuse feature into Linux makefile

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ideally, avrdude itself should be modified to read the new section and do the programming itself.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EW wrote:
Ideally, avrdude itself should be modified to read the new section and do the programming itself.
My understanding is avrdude doesn't deal with elf binaries. The typical input is an Intel hex file. I can't speak for the avrdude developers, but I would be surprised if they add elf support just to get hold of the three fuse bytes.

But this discussion just triggered another thought. The typical way to provide avrdude with an Intel hex file is to have a conversion target in the Makefile. That target uses objcopy to extract the data from the elf object into an Intel hex file. I'll play with objcopy and its -b and -i options to see if I can extract the .fuse section into three separate files, one byte each, and then load these files with three avrdude -U options.

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arnold,
One of the two project admins for avrdude, Joerg Wunsch, is also one of the three project admins for avr-libc.
Eric Weddington is also an admin for avr-libc, and a registered contributor to avrdude.

I'd place fairly high odds on their desire to eventually come up with a plan to introduce seamless compatibility for this new avr-libc API directly in avrdude.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, there are plans in the works to have avrdude read ELF files. IIRC, there's been some work done in this direction by Colin O'Flynn (another fellow Freak).