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
1 Answer 1
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.
-
\$\begingroup\$ I have created a header containing the prototype 'void test_function(void);' compiled it using 'avr-gcc test.c -c -o test.o' and archieved it using 'avr-ar rcs libtest.a test.o'. I then attempted to use it will 'avr-gcc temp.c -I. -L. -ltest -o temp'. I still get undefined error! Am I doing something wrong? \$\endgroup\$Will03uk– Will03uk2012年02月28日 17:18:32 +00:00Commented Feb 28, 2012 at 17:18
-
\$\begingroup\$ @Will03uk Try avr-gcc -o temp temp.c -I. libtest.a \$\endgroup\$Toby Jaffey– Toby Jaffey2012年02月28日 17:21:20 +00:00Commented Feb 28, 2012 at 17:21
-
\$\begingroup\$ Same error again (I also had an incorrect header name error now and so the undefined error occurs before it pre-processes the program file, if that helps) \$\endgroup\$Will03uk– Will03uk2012年02月28日 17:35:40 +00:00Commented Feb 28, 2012 at 17:35
-
\$\begingroup\$ You actually implemented
test_function
intest.c
, right? Not just declared it? \$\endgroup\$Mike DeSimone– Mike DeSimone2012年02月28日 17:37:00 +00:00Commented Feb 28, 2012 at 17:37 -
\$\begingroup\$ Yeah, it's so wierd; I'll edit the code into the question. \$\endgroup\$Will03uk– Will03uk2012年02月28日 17:39:42 +00:00Commented Feb 28, 2012 at 17:39