These attributes are supported by the AVR back end:
signal ¶interruptThese attributes apply to functions.
They specify that the function is an interrupt service routine (ISR). The compiler generates function entry and exit sequences suitable for use in an interrupt handler when one of the attributes is present.
The AVR hardware globally disables interrupts when an interrupt is executed.
signal attribute do not re-enable interrupts.
It is save to enable interrupts in a signal handler.
This “save” only applies to the code
generated by the compiler and not to the IRQ layout of the
application which is responsibility of the application.
interrupt attribute re-enable interrupts.
The first instruction of the routine is a SEI instruction to
globally enable interrupts.
The recommended way to use these attributes is by means of the
ISR macro provided by avr/interrupt.h from
AVR-LibC:
#include <avr/interrupt.h>
ISR (INT0_vect) // Uses the "signal" attribute.
{
// Code
}
ISR (ADC_vect, ISR_NOBLOCK) // Uses the "interrupt" attribute.
{
// Code
}
When both signal and interrupt are specified for the same
function, then signal is silently ignored.
signal(num) ¶interrupt(num)These attributes apply to functions.
They are similar to the signal and interrupt attributes
(respectively) without arguments,
but the IRQ number is supplied as an argument num to
the attribute, rather than providing the ISR name itself as the function name:
__attribute__((signal(1)))
static void my_handler (void)
{
// Code for __vector_1
}
Notice that the handler function needs not to be externally visible.
The recommended way to use these attributes is by means of the
ISR_N macro provided by avr/interrupt.h from
AVR-LibC:
#include <avr/interrupt.h>
ISR_N (PCINT0_vect_num)
static void my_pcint0_handler (void)
{
// Code
}
ISR_N (ADC_vect_num, ISR_NOBLOCK)
static void my_adc_handler (void)
{
// Code
}
ISR_N can be specified more than once, in which case several
interrupt vectors are pointing to the same handler function. This
is similar to the ISR_ALIASOF macro provided by AVR-LibC, but
without the overhead introduced by ISR_ALIASOF.
noblock ¶This attribute applies to functions.
It can be used together with the signal attribute
to indicate that an interrupt service routine should start with a SEI
instruction to globally re-enable interrupts. Using attributes signal
and noblock together has the same effect like using the interrupt
attribute. Using the noblock attribute without signal has no
effect.
no_gccisr ¶This attribute applies to functions.
It specifies that GCC should not use the __gcc_isr
pseudo instruction
in a function with
the interrupt or signal attribute aka. interrupt
service routine (ISR).
Use this attribute if the preamble of the ISR prologue should always read
push __zero_reg__ push __tmp_reg__ in __tmp_reg__, __SREG__ push __tmp_reg__ clr __zero_reg__
and accordingly for the postamble of the epilogue—no matter whether the mentioned registers are actually used in the ISR or not. Situations where you might want to use this attribute include:
SREG other than the
I-flag by writing to the memory location of SREG.
To disable __gcc_isr generation for the whole compilation unit,
use option -mno-gas-isr-prologues, see AVR Options.
OS_main ¶OS_taskThis attribute applies to functions.
On AVR, functions with the OS_main or OS_task attribute
do not save/restore any call-saved register in their prologue/epilogue.
The OS_main attribute can be used when there is
guarantee that interrupts are disabled at the time when the function
is entered. This saves resources when the stack pointer has to be
changed to set up a frame for local variables.
The OS_task attribute can be used when there is no
guarantee that interrupts are disabled at that time when the function
is entered like for, e.g. task functions in a multi-threading operating
system. In that case, changing the stack pointer register is
guarded by save/clear/restore of the global interrupt enable flag.
The differences to the naked function attribute are:
naked functions do not have a return instruction whereas
OS_main and OS_task functions have a RET or
RETI return instruction.
naked functions do not set up a frame for local variables
or a frame pointer whereas OS_main and OS_task do this
as needed.
progmem ¶This attribute applies to variables.
The progmem attribute is used on the AVR to place read-only
data in the non-volatile program memory (flash). The progmem
attribute accomplishes this by putting respective variables into a
section whose name starts with .progmem.
This attribute works similar to the section attribute
but adds additional checking.
progmem affects the location
of the data but not how this data is accessed.
In order to read data located with the progmem attribute
(inline) assembler must be used.
/* Use custom macros from AVR-LibC */
#include <avr/pgmspace.h>
/* Locate var in flash memory */
const int var[2] PROGMEM = { 1, 2 };
int read_var (int i)
{
/* Access var[] by accessor macro from avr/pgmspace.h */
return (int) pgm_read_word (& var[i]);
}
AVR is a Harvard architecture processor and data and read-only data normally resides in the data memory (RAM).
See also the AVR Named Address Spaces section for an alternate way to locate and access data in flash memory.
On such devices, there is no need for attribute progmem or
__flash qualifier at all.
Just use standard C / C++. The compiler will generate LD*
instructions. As flash memory is visible in the RAM address range,
and the default linker script does not locate .rodata in
RAM, no special features are needed in order not to waste RAM for
read-only data or to read from flash. You might even get slightly better
performance by
avoiding progmem and __flash. This applies to devices from
families avrtiny and avrxmega3, see AVR Options for
an overview.
The compiler adds 0x4000
to the addresses of objects and declarations in progmem and locates
the objects in flash memory, namely in section .progmem.data.
The offset is needed because the flash memory is visible in the RAM
address space starting at address 0x4000.
Data in progmem can be accessed by means of ordinary C code,
no special functions or macros are needed.
/* var is located in flash memory */
extern const int var[2] __attribute__((progmem));
int read_var (int i)
{
return var[i];
}
Please notice that on these devices, there is no need for progmem
at all.
io ¶io (addr)This attribute applies to variables.
Variables with the io attribute are used to address
memory-mapped peripherals in the I/O address range.
No memory is allocated.
If an address is specified, the variable
is assigned that address, and the value is interpreted as an
address in the data address space.
Example:
volatile int porta __attribute__((io (__AVR_SFR_OFFSET__ + 0x2)));
Otherwise, the variable is not assigned an address, but the
compiler will still use in and out instructions where applicable,
assuming some other module assigns an address in the I/O address range.
Example:
extern volatile int porta __attribute__((io));
io_low ¶io_low (addr)The io_low attribute applies to variables.
This is like the io attribute, but additionally it informs the
compiler that the object lies in the lower half of the I/O area,
allowing the use of cbi, sbi, sbic and sbis
instructions.
address (addr) ¶This attribute applies to variables.
Variables with the address attribute can be used to address
memory-mapped peripherals that may lie outside the I/O address range.
Just like with the io and io_low attributes, no memory is
allocated.
volatile int porta __attribute__((address (0x600)));
This attribute can also be used to define symbols in C/C++
code which otherwise would require assembly, a linker description file
or command-line options like -Wl,--defsym,a_symbol=value.
For example,
int a_symbol __attribute__((weak, address (1234)));
will be compiled to
.weak a_symbol a_symbol = 1234
absdata ¶This attribute applies to variables.
Variables in static storage and with the absdata attribute can
be accessed by the LDS and STS instructions which take
absolute addresses.
0x40…0xbf accessible by
LDS and STS. One way to achieve this as an
appropriate linker description file.
LDS
and STS, there is currently (Binutils 2.26) just an unspecific
warning like
module.cc:(.text+0x1c): warning: internal error: out of range error
See also the -mabsdata command-line option.