Being able to store all the information needed to program your AVR in single file, fuse bits included, is pretty convenient. The GCC toolchain supports declaring the fuse bits in the C source files, and stores this data in the generated ELF file. However the last step, generation of the .hex file and programming it with avrdude does not support this.
Hopefully ELF file support in avrdude will be ready soon, but in the meanwhile here's how to do it using a modified Makefile.
1) Declare the fuse bits in your C source file
You need to add the following code :
#includeFUSES = { .low = (FUSE_CKSEL0 & FUSE_CKSEL1 & FUSE_CKSEL3 & FUSE_SUT0 & FUSE_CKDIV8), .high = HFUSE_DEFAULT, .extended = EFUSE_DEFAULT, };
This declares 3 fuse bytes, lfuse, hfuse and efuse. hfuse and efuse have default values, while lfuse uses a custom configuration. Change this accordingly to your needs and the fuses supported by your microcontroller.
Complete documentation for fuses support in avr-libc can be found here : http://www.nongnu.org/avr-libc/u...
The list of all fuses constants can be found in the ioxxxx.h file corresponding to your microcontroller (look in [winavr install dir]/avr/include/avr).
2) Change the Makefile
Add a new FUSES variable to the Makefile :
FUSES = -U hfuse:w:hfuse.hex:i -U lfuse:w:lfuse.hex:i -U efuse:w:efuse.hex:i -u
Add a new goal to extract the fuse data from the elf file and program it :
fuse: $(TARGET).elf avr-objcopy -j .fuse -O ihex $(TARGET).elf fuses.hex --change-section-lma .fuse=0 srec_cat fuses.hex -Intel -crop 0x00 0x01 -offset 0x00 -O lfuse.hex -Intel srec_cat fuses.hex -Intel -crop 0x01 0x02 -offset -0x01 -O hfuse.hex -Intel srec_cat fuses.hex -Intel -crop 0x02 0x03 -offset -0x02 -O efuse.hex -Intel $(AVRDUDE) $(AVRDUDE_FLAGS) $(FUSES)
Look for the clean_list definition and add the intermediate hex files :
clean_list : @echo @echo $(MSG_CLEANING) $(REMOVE) $(TARGET).hex $(REMOVE) fuses.hex $(REMOVE) lfuse.hex $(REMOVE) hfuse.hex $(REMOVE) efuse.hex $(REMOVE) $(TARGET).eep $(REMOVE) $(TARGET).cof $(REMOVE) $(TARGET).elf $(REMOVE) $(TARGET).map $(REMOVE) $(TARGET).sym $(REMOVE) $(TARGET).lss $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o) $(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst) $(REMOVE) $(SRC:.c=.s) $(REMOVE) $(SRC:.c=.d) $(REMOVE) $(SRC:.c=.i) $(REMOVEDIR) .dep
The complete modified Makefile is attached to this post. Use it in place of the standard Makefile template. Again, if you do not use 3 fuse bytes, you'll need to modify the Makefile manually. There is probably a way to do this automatically in function of the MCU variable, but I'm not quite fluent enough in make-speak to do this. Ask if you need support.
3) Program the fuses :
The goal to program the fuses is 'fuse' :
make fuse
Or :
make program fuse
4) Done ! :-)