What is "part specific header?"

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I know what it is, but it may not be completely accurate.

 

My guess is that there is a library that must be included in the program specific to the device I'm using.  Since I'm using the Atmel Studio IDE, the device is pre-selected and therefore I don't need to specifically include the device library?  It's there, behind the scenes and the compiler takes care of the details?

 

For those unfamiliar with the phrase, I read it in the datasheet for the attiny, with regard to code examples:

 

3.2 Code Examples
This documentation contains simple code examples that briefly show how to use various parts of the device. These
code examples assume that the part specific header file is included before compilation. Be aware that not all C
compiler vendors include bit definitions in the header files and interrupt handling in C is compiler dependent.
Please confirm with the C compiler documentation for more details.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When you

#include <avr/io.h>

it will automatically include the part-specific header e.g. iom32.h

 

There is a similar mechanism for other Compilers and even ASM programs.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are correct. When you specify a device as part of setting up a new project, that, behind the scenes, accesses a whole chain of header files that covers everything from register and bit names to flash and ram address limits.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you know your avr-gcc programs all begin:

#include <avr/io.h>

now put the cursor on that line and Alt-G (go to definition) which will open the file in your editor.

 

Do you see how it works? It uses a symbol such as __AVR_ATmega16__ to choose to include iom16.h or whatever from amongst about 300 other device specific .h files. That __AVR_ATmega16__ symbol in turn is defined when you pass -mmcu=atmega16 to the compiler. And in your project you will ave selected to build for ATmega16 and that is what lead to that -mmcu value being passed.

 

My example here uses mega16. Perhaps you build for something else? If so you can trace the path to the point at which its own device specific header is included.

 

In such headers it then defines the names of all the SFRs and all the bit names in those SFRs

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

As you know your avr-gcc programs all begin:

#include <avr/io.h>

 

Um, okay... I do now! But, the alt-G isn't working.  I tried the context menu (right click) and alt-G is listed.  Clicking on it from the context menu doesn't work either.  The <avr/io.h> is in black text.  Should that be another color? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Heres a screenshot...

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The standard library include files show in black in my configuration.

And when I right click and select "Goto Implementation" the file opens (AS7.0.1006).

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

frog_jr wrote:

The standard library include files show in black in my configuration.

And when I right click and select "Goto Implementation" the file opens (AS7.0.1006).

 

Poking around I found if I hit alt-g while on one of the register names that it will open iom16.h file (tab all the way to the right) and cursor to the define .  It just won't work on the include line.  Is there something wrong with my setup?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and more explanation to go with that :

GCC Wiki

avr-gcc

The Device Header avr/io.h

https://gcc.gnu.org/wiki/avr-gcc#The_Device_Header_avr.2BAC8-io.h

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The point I was trying to make about io.h to you is that it is simply a lot of this:

#if defined (__AVR_AT94K__)
#  include <avr/ioat94k.h>
#elif defined (__AVR_AT43USB320__)
#  include <avr/io43u32x.h>
#elif defined (__AVR_AT43USB355__)
#  include <avr/io43u35x.h>
#elif defined (__AVR_AT76C711__)
#  include <avr/io76c711.h>
#elif defined (__AVR_AT86RF401__)
#  include <avr/io86r401.h>
#elif defined (__AVR_AT90PWM1__)
#  include <avr/io90pwm1.h>
#elif defined (__AVR_AT90PWM2__)
#  include <avr/io90pwmx.h>
#elif defined (__AVR_AT90PWM2B__)
#  include <avr/io90pwm2b.h>
#elif defined (__AVR_AT90PWM3__)
#  include <avr/io90pwmx.h>
#elif defined (__AVR_AT90PWM3B__)
#  include <avr/io90pwm3b.h>
#elif defined (__AVR_AT90PWM216__)
#  include <avr/io90pwm216.h>
<and so on for about 300 different models of AVR...>

In other words you write:

#include <avr/io.h>

int main(void) {
    DDRB = 0xFF;
    while(1) {
        PORTB ^= 0xFF;
    }
}

and if you then compile this with:

avr-gcc -mmcu=atmega8 -Os main.c -o main.elf

then that long list in io.h will include the header file for atmega8 because the symbol __AVR_ATmega8__ will be defined by the use of -mmcu=atmega8. Whereas if you use:

avr-gcc -mmcu=atmega328p -Os main.c -o main.elf

then the header for mega328 will be used because __AVR_ATmega328P__.

 

In each case the addresses of PORTB and DDRB will then be supplied by the header file. So the same code can be built for two (or many more) AVR using the symbols DDRB and PORTB and because of -mmcu the correct values for the address of those locations will be defined by the appropriate header file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Alright.  Thanks everyone.