September 15, 2024

The AVR toolchain and the Podkalicki projects

The idea here is to get some simple code for the ATtiny13, build it, flash it into a DIP package ATtiny13 and run it.

This will test the toolchain, the USBasp dongle, and the entire process from code in C, so something running on the chip. Sort of a "hello world" exercise.

The Podkalicki projects

This fellow (L Podkalicki) is at the Warsaw University of Technology in Warsaw, Poland and worked up a very nice set of projects, all targetting the ATtiny13. These are a great source of information and understanding.

I found a collection of his projects back when there were 56 of them. He is now up to 65, with a goal of 100.

There is a Github repository, but it is old (2016 or so) and has only 12 of the projects.

The first project is "001_blinky_with_delay_function". It consists of just a Makefile and a single file of C source. The file main.c is 26 lines.

When I worked with this back in 2016, I had failed to install the avr-libc package, being unaware of what it was and that it existed at all. Because of this I was missing vital include files and ended up hacking together a mess to get this to work (but I did manage it). With this package installed, the demos work "out of the box".

I only have had to make one change to the Makefile. I have had to add the "-c" option to the gcc line. I have no idea how this used to work without it.

Amazingly, no assembly language startup is needed for the ATtiny13! However this is all managed by things magically pulled in from avr-libc. The accurate statement would be that "I don't need to write any assembly startup code". So far I am unaware of the details, but when I do the following to get a disassembly of the entire linked code (all 37 bytes of it), I see that nothing surprising has been added.

avr-objdump -d main.elf >main.dump

Development tools (software>

To get set up to run "make" for these projects, we need to do this on my Fedora 40 system:
su
dnf install avr-gcc
dnf install avr-libc
dnf install avrdude
The "avr-libc" package gives us things "/usr/avr/include/avr/io.h" which gets pulled in as "avr/io.h" Apparently it also gives us util/delay.h and things just work.

Flash this into a chip

This involves the "avrdude" program, my USBasp dongle, and an adapter board I soldered together 5 years ago. I expect to have to fool with udev rules, but when I plug it in, I see:
Sep 16 16:06:29 trona kernel: usb 1-1.2: new low-speed USB device number 3 using ehci-pci
Sep 16 16:06:29 trona kernel: usb 1-1.2: New USB device found, idVendor=16c0, idProduct=05dc, bcdDevice= 1.04
Sep 16 16:06:29 trona kernel: usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Sep 16 16:06:29 trona kernel: usb 1-1.2: Product: USBasp
Sep 16 16:06:29 trona kernel: usb 1-1.2: Manufacturer: www.fischl.de
How about that? It seems to just get recognized. And there are no special rules in /etc/udev from my previous work. Very nice.

But now we encounter our first problem:

make flash
avrdude -p attiny13 -c usbasp -B10 -U flash:w:main.hex
Set SCK frequency to 93750 Hz
Warning: no flash data found in Intel Hex file main.hex
Reading 0 bytes for flash from input file main.hex
Indeed, an examination of "main.hex" shows just an end of file record in the Intel hex file. I have the hex file from back in 2019 when I first worked on this and it has contents. So, something in the toolchain has changed.

I make the following change to the Makefile, build again, and it works:

    #${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.o ${TARGET}.hex
    ${OBJCOPY} -O ihex ${TARGET}.o ${TARGET}.hex
The flashing process looks like this:
avrdude -p attiny13 -c usbasp -B10 -U flash:w:main.hex
Set SCK frequency to 93750 Hz
Set SCK frequency to 93750 Hz
Reading 34 bytes for flash from input file main.hex
Writing 34 bytes to flash
Writing | ################################################## | 100% 0.66 s
Reading | ################################################## | 100% 0.36 s
34 bytes of flash verified
Avrdude done.  Thank you.
I am always surprised when Avrdude "thanks me"!
I appreciate polite software.

But it doesn't work

We should be able to connect an LED to pin 5 (PB0) and see it blink at about 1 Hz. Lucky for me, I have a hex file from back in 2019. It has 82 bytes of stuff. I flash it, hook it up, and indeed it makes an LED blink via pin 5.

So, my avrdude arrangement is working, but something is wrong with my scrawny hex file. When I examine the files from my 2019 build I notice several things:

We make the Makefile look like so:
#   ${CC} ${CFLAGS} -o ${TARGET}.o ${SRCS}
    ${CC} ${CFLAGS} -o ${TARGET}.elf ${SRCS}
#   ${LD} -o ${TARGET}.elf ${TARGET}.o
#   ${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.o ${TARGET}.hex
    ${OBJCOPY} -O ihex ${TARGET}.elf ${TARGET}.hex
    ${SIZE} -C --mcu=${MCU} ${TARGET}.elf
We let "CC" do both the compile and link (as it did in 2019) and we skip the "LD" business altogether. When we let gcc do the link, it know that it should add the C startup code and such. This yields a 72 byte output.

Best of all, It works!.


Feedback? Questions? Drop me a line!

Tom's Light Info / [email protected]