In which I PEBKAC so you don’t have to

Say you have a simple bit of code: #include <avr/io.h> #include <util/delay.h> #define LED_BUILTIN _BV(PORTB5) int main(void) { DDRB |= LED_BUILTIN; while (1) { PORTB |= LED_BUILTIN; // turn on led _delay_ms(1000); // delay 1s PORTB &= ~LED_BUILTIN; // turn off led _delay_ms(1000); // delay 1s } } You have a Makefile that compiles that into an object (.o) file like this: avr-gcc -mmcu=atmega328p -DF_CPU=16000000 -Os -c blink.c If you were to forget to set the device type when compiling your .
read more →

ATOMIC_BLOCK magic in avr-libc

The AVR C library, avr-libc, provide an ATOMIC_BLOCK macro that you can use to wrap critical sections of your code to ensure that interrupts are disabled while the code executes. At high level, the ATOMIC_BLOCK macro (when called using ATOMIC_FORCEON) does something like this: cli(); …your code here… seti(); But it’s more than that. If you read the documentation for the macro, it says: Creates a block of code that is guaranteed to be executed atomically.
read more →

AVR micro-optimization: Avr-gcc and –short-enums

How big is an enum? I noticed something odd while browsing through the assembly output of some AVR C code I wrote recently. In the code, I have the following expression: int main() { setup(); while (state != STATE_QUIT) { loop(); } } Here, state is a variable of type enum STATE, which looks something like this (not exactly like this; there are actually 19 possible values but I didn’t want to clutter this post with unnecessary code listings):
read more →

AVR micro-optimization: Losing malloc

Pssst! Hey…hey, buddy, wanna get an extra KB for cheap? When I write OO-style code in C, I usually start with something like the following, in which I use malloc() to allocate memory for a variable of a particular type, perform some initialization actions, and then return it to the caller: Button *button_new(uint8_t pin, uint8_t poll_freq) { Button *button = (Button *)malloc(sizeof(Button)); // do some initialization stuff return button; } And when initially writing pipower, that’s exactly what I did.
read more →

Debugging attiny85 code, part 1: simavr and gdb

In a case of awful timing, after my recent project involving some attiny85 programming I finally got around to learning how to use simavr and gdb to help debug my AVR code. It was too late for me (and I will never get the time back that I spent debugging things with an LED and lots of re-flashing), but maybe this will help someone else! I’ve split this into three posts:
read more →