Where are avr-gcc libraries stored?

2.4k Views Asked by At

I'm trying to locate the .c files that are related to the #include header files in avr.

I want to have a look at some of the standard libraries that are defined in the avr-gcc library, particularly the PORT definitions contained in <avr/io.h>. I searched through the library in /usr/lib/avr/include/avr and found the header file, however what I am looking for is the .c file. Does this file exist? If so, where can I find it? If not, what is the header file referencing?

3

There are 3 best solutions below

0
Clifford On BEST ANSWER

The compiler provided libraries are precompiled object code stored in static libraries. In gcc, libraries conventionally the extension .a (for "archive" for largely historic reasons), and the prefix "lib".

At build time, the linker will search the library archives to find the object-code modules necessary to resolve references to library symbols. It extracts the required modules and links them to the binary image being built.

In gcc a library libXXX.a is typically linked using the command line switch -lXXX - so the libXXX.a naming convention is important in that case. So for example the standard C library libc.a is linked by the switch -lc.

So to answer your question, there are normally no .c files for the compiler provided libraries provided with the toolchain. The library need not even have been written in C.

That said, being open source, the source files (.c or otherwise) will be available from the repositories of the various libraries. For example, for the standard C library: https://www.nongnu.org/avr-libc/.

For other AVR architecture and I/O support libraries, you might inspect the associated header files or documentation. The header files will typically have a boiler-plate comment with a project URL for example.

0
David Grayson On

PORTB and other special function registers are usually defined as macros in headers provided by avr-libc. Find your include/avr directory (the one that contains io.h). In that directory, there should be many other header files. As an example, iom328p.h contains the following line that defines PORTB on the ATmega328P:

#define PORTB _SFR_IO8(0x05)

If you are also looking for the libraries that are distributed as .a files, you should run avr-gcc -print-search-dirs.

0
emacs drives me nuts On

There are several ways to find out where the system headers are located and which are included:

avr-gcc -v -mmcu=atmega8 foo.c ...

With option -v, GCC will print (amongst other stuff) whch include paths it is using. Check the output on a shell / console, where GCC will print the search paths:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/avr/5.4.0/include
 /usr/lib/gcc/avr/5.4.0/include-fixed
 /usr/lib/gcc/avr/5.4.0/../../../avr/include

The last location is for AVR-LibC, which provides avr/io.h. Resolving the ..s, that path is just /usr/lib/avr/include. These paths depend on how avr-gcc was configured and installed, hence you have to run that command with your installation of avr-gcc.

avr-gcc -H -mmcu=atmega8 foo.c ...

Suppose the C-file foo.c reads:

#include <avr/io.h>

int main (void)
{
    PORTD = 0;
}

for an easy example. With -H, GCC will print out which files it is actually including:

. /usr/lib/avr/include/avr/io.h
.. /usr/lib/avr/include/avr/sfr_defs.h
... /usr/lib/avr/include/inttypes.h
.... /usr/lib/gcc/avr/5.4.0/include/stdint.h
..... /usr/lib/avr/include/stdint.h
.. /usr/lib/avr/include/avr/iom8.h
.. /usr/lib/avr/include/avr/portpins.h
.. /usr/lib/avr/include/avr/common.h
.. /usr/lib/avr/include/avr/version.h
.. /usr/lib/avr/include/avr/fuse.h
.. /usr/lib/avr/include/avr/lock.h

avr-gcc -save-temps -g3 -mmcu=atmega8 foo.c ...

With DWARF-3 debugging info, the macro definitions will be recorded in the debug info and are visible in the pre-processed file (*.i for C code, *.ii for C++, *.s for pre-processed assembly). Hence, in foo.i we can find the definition of PORTD as

#define PORTD _SFR_IO8(0x12)

Starting from the line which contains that definition, scroll up until you find the annotation that tells in which file the macro definition happened. For example

# 45 "/usr/lib/avr/include/avr/iom8.h" 3

in the case of my toolchain installation. This means that the lines following that annotation follow line 45 of /usr/lib/avr/include/avr/iom8.h.

If you want to see the resolution of PORTD, scroll down to the end of foo.i which contains the pre-processed source:

# 3 "foo.c"
int main (void)
{
   (*(volatile uint8_t *)((0x12) + 0x20)) = 0;
}

0x12 is the I/O address of PORTD, and 0x20 is the offset between I/O addresses and RAM addresses for ATmega8. This means the compiler may implement PORTD = 0 by means of out 0x12, __zero_reg__.

avr-gcc -print-file-name=libc.a -mmcu=...

Finally, this command will print the location (absolue path) of libraries like libc.a, libm.a, libgcc.a or lib<mcu>.a. The location of the library depends on how the compiler was configureed and installed, but also on command line options like -mmcu=.

avr-gcc -Wl,-Map,foo.map -mmcu=atmega8 foo.c -o foo.elf

This directs the linker to dump a "map" file foo.map where it reports which symbol will drag which module from which library. This is a text file that contains lines like:

LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/crtatmega8.o
...
LOAD /usr/lib/gcc/avr/5.4.0/avr4/libgcc.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libm.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libc.a
LOAD /usr/lib/gcc/avr/5.4.0/../../../avr/lib/avr4/libatmega8.a

libgcc.a is from the compiler's C runtime, and all the others are provided by AVR-LibC. Resolving the ..s, the AVR-LibC files for ATmega8 are located in /usr/lib/avr/lib/avr4/.