Electronic – How to create a static library for the AVR Atmega328p

avravr-gccclibrary

I am attempting to create a library much like the Arduino in C.

I have tried in the past and although I have lost the code, I remember simply getting loads of undefined references to functions specified in the header files and in the library which did contain all the object files (checked by avr-objdump).

I want to know how I should compile the library (example makefile) and how the program should be compiled to it. Also, do I need to re-compile the library for every AVR and Clock speed, or is there a way around it?

If you need any more information, just ask.

Thanks


EDIT: Example (not working)

program.c

#include "test.h"

int main(void)
{
    test_function();
}

test.c

#include "test.h"

void test_function()
{
    int i;
    i++;
}

test.h

#ifndef __TEST_H_
#define __TEST_H_

void test_function(void);

#endif

Best Answer

The AVR-Libc user manual has an entire chapter on how to build a library. I would suggest starting there. If you use an IDE like eclipse, there will be project settings that are applicable if you want to build as a library instead of an executable.

Edit

Here's what eclipse does when I set it up for your example:

So that it couldn't be trivially compiled away, I changed your test_function to:

#include "test.h"

void test_function()
{
    volatile int i = 0;
    i++;
}

Building the library:

avr-gcc -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"test.d" -MT"test.d" -c -o"test.o" "../test.c"

avr-ar -r "libtest.a"  ./test.o 

avr-objdump -h -S libtest.a  >"libtest.lss"

avr-size --format=avr --mcu=atmega328p libtest.a

Building the main program

avr-gcc -I"C:\path\to\my\workspace\test" -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega328p -DF_CPU=16000000UL -MMD -MP -MF"program.d" -MT"program.d" -c -o"program.o" "../program.c"

avr-gcc -Wl,-Map,MainProgram.map -L"C:\path\to\my\workspace\test\Release" -mmcu=atmega328p -o"MainProgram.elf"  ./program.o   -ltest

avr-objdump -h -S MainProgram.elf  >"MainProgram.lss"

avr-size --format=avr --mcu=atmega328p MainProgram.elf

... and it builds without error. My guess is you need include paths specified in the command lines. Following proper naming conventions is pretty important too, try and follow the pattern above. Obviously the avr-objdump and avr-size commands are just for more information and not required if you're just building.

I'm pretty certain that if you'll need to recompile your library for specific target architectures and clock speeds as well.