¿Cómo creo una biblioteca estática para el AVR Atmega328p?

Estoy intentando crear una biblioteca muy parecida a Arduino en C.

Lo intenté en el pasado y, aunque perdí el código, recuerdo que simplemente recibí muchas referencias indefinidas a funciones especificadas en los archivos de encabezado y en la biblioteca que contenía todos los archivos de objetos (verificados por avr-objdump).

Quiero saber cómo debo compilar la biblioteca (archivo MAKE de ejemplo) y cómo se debe compilar el programa. Además, ¿debo volver a compilar la biblioteca para cada AVR y velocidad de reloj, o hay alguna forma de evitarlo?

Si necesita más información, solo pregunte.

Gracias


EDITAR: Ejemplo (no funciona)

programa.c

#include "test.h"

int main(void)
{
    test_function();
}

prueba.c

#include "test.h"

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

prueba.h

#ifndef __TEST_H_
#define __TEST_H_

void test_function(void);

#endif

Respuestas (1)

El manual de usuario de AVR-Libc tiene un capítulo completo sobre cómo crear una biblioteca . Sugeriría empezar por ahí. Si usa un IDE como eclipse, habrá configuraciones de proyecto que se aplicarán si desea compilar como una biblioteca en lugar de un ejecutable.

Editar

Esto es lo que hace eclipse cuando lo configuro para tu ejemplo:

Para que no se pudiera compilar trivialmente, cambié su función de prueba a:

#include "test.h"

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

Construyendo la biblioteca:

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

Construyendo el programa principal

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

... y se construye sin error. Supongo que necesita incluir rutas especificadas en las líneas de comando. Seguir las convenciones de nomenclatura adecuadas también es muy importante, intente seguir el patrón anterior. Obviamente, los comandos avr-objdump y avr-size son solo para obtener más información y no son necesarios si solo está construyendo.

Estoy bastante seguro de que si necesitará volver a compilar su biblioteca para arquitecturas de destino específicas y velocidades de reloj también.

He creado un encabezado que contiene el prototipo 'void test_function(void);' lo compiló usando 'avr-gcc test.c -c -o test.o' y lo archivó usando 'avr-ar rcs libtest.a test.o'. Luego intenté usarlo 'avr-gcc temp.c -I. -l -ltest -o temp'. ¡Todavía recibo un error indefinido! ¿Estoy haciendo algo mal?
@ Will03uk Pruebe avr-gcc -o temp temp.c -I. libtest.a
El mismo error nuevamente (también tuve un error de nombre de encabezado incorrecto ahora, por lo que el error indefinido ocurre antes de que procese previamente el archivo del programa, si eso ayuda)
Realmente implementaste test_functionen test.c, ¿verdad? ¿No solo lo declaró?
Sí, es tan extraño; Editaré el código en la pregunta.
Ignorando los diferentes chips AVR, ¡lo siguiente funciona! avr-gcc -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega128 -DF_CPU=2000000UL -c -o test.o test.c - Os avr-ar -r "libtest.a" test.o avr-gcc -Wall -g2 -gstabs -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega128 - DF_CPU=2000000UL -c -o temp.o temp.c avr-gcc -Wl,-Map,program.map -L. -mmcu=atmega128 -o program.elf temp.o -ltest