Spec-Zone.ru › GCC 15

6.4.1.6 Атрибуты функций AVR

Бэкенд AVR поддерживает следующие атрибуты функций:

signal
interrupt

Функция является обработчиком прерывания (ISR). Если указан один из этих атрибутов, компилятор генерирует последовательности входа в функцию и выхода из неё, подходящие для использования в обработчике прерывания.

Аппаратное обеспечение AVR глобально отключает прерывания при обработке прерывания.

  • ISR с атрибутом signal не включают прерывания повторно. В обработчике signal безопасно включать прерывания. Эта «безопасность» относится только к коду, сгенерированному компилятором, а не к схеме IRQ приложения, за которую отвечает само приложение.
  • ISR с атрибутом interrupt включают прерывания повторно. Первая инструкция процедуры — это инструкция SEI, которая глобально включает прерывания.

Рекомендуется использовать эти атрибуты с помощью макроса ISR, предоставляемого avr/interrupt.h из AVR-LibC:

#include <avr/interrupt.h>

ISR (INT0_vect) // Uses the "signal" attribute.
{
    // Code
}

ISR (ADC_vect, ISR_NOBLOCK) // Uses the "interrupt" attribute.
{
    // Code
}

Если для одной и той же функции указаны оба атрибута — signal и interrupt, — то signal игнорируется без предупреждения.

signal(num)
interrupt(num)

Подобен атрибуту signal или interrupt без аргумента, но номер IRQ передаётся атрибуту в качестве аргумента num, вместо того чтобы указывать имя ISR в качестве имени функции:

__attribute__((signal(1)))
static void my_handler (void)
{
   // Code for __vector_1
}

Обратите внимание, что функция-обработчик не обязана быть видимой извне. Рекомендуется использовать эти атрибуты с помощью макроса ISR_N, предоставляемого avr/interrupt.h из 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 можно указывать несколько раз; в этом случае несколько векторов прерываний будут указывать на одну и ту же функцию-обработчик. Это аналогично макросу ISR_ALIASOF из AVR-LibC, но без дополнительных затрат, вызванных ISR_ALIASOF.

noblock

Этот атрибут можно использовать вместе с атрибутом signal, чтобы указать, что обработчик прерывания должен начинаться с инструкции SEI, глобально включающей прерывания. Совместное использование атрибутов signal и noblock даёт тот же эффект, что и атрибут interrupt. Использование атрибута noblock без signal не даёт эффекта.

naked

Этот атрибут позволяет компилятору сформировать необходимое объявление функции, оставляя её тело на языке ассемблера. Для указанной функции компилятор не генерирует последовательности пролога и эпилога. В функциях с атрибутом naked безопасно использовать только базовые инструкции asm (см. раздел Базовый Asm — инструкции ассемблера без операндов). Хотя расширенный asm или сочетание базового asm с кодом на C могут, на первый взгляд, работать, полагаться на их надёжную работу нельзя; такая возможность не поддерживается.

no_gccisr

Не используйте __gcc_isr — псевдоинструкцию — в функции с атрибутом interrupt или signal, то есть в обработчике прерывания (ISR). Используйте этот атрибут, если пролог ISR всегда должен начинаться с такого кода:

push  __zero_reg__
push  __tmp_reg__
in    __tmp_reg__, __SREG__
push  __tmp_reg__
clr   __zero_reg__

и, соответственно, эпилог всегда должен завершаться таким кодом — независимо от того, используются ли в ISR упомянутые регистры. Этот атрибут может быть полезен, например, в следующих случаях:

  • Код, который (фактически) изменяет биты SREG, отличные от флага I, посредством записи в ячейку памяти SREG.
  • Код, в котором встроенный ассемблер используется для перехода к другой функции, ожидающей наличия (части) описанного выше кода пролога.

Чтобы отключить генерацию __gcc_isr для всего модуля компиляции, используйте параметр -mno-gas-isr-prologues; см. раздел Параметры AVR.

OS_main
OS_task

В AVR функции с атрибутом OS_main или OS_task не сохраняют и не восстанавливают регистры, сохраняемые при вызове, в прологе и эпилоге.

Атрибут OS_main можно использовать, если гарантируется, что на момент входа в функцию прерывания отключены. Это позволяет сэкономить ресурсы, когда для выделения кадра под локальные переменные необходимо изменить указатель стека.

Атрибут OS_task можно использовать, если на момент входа в функцию не гарантируется, что прерывания отключены, например в функциях задач многопоточной операционной системы. В этом случае изменение регистра указателя стека защищено сохранением, сбросом и восстановлением глобального флага разрешения прерываний.

Отличия от атрибута функции naked:

  • Функции naked не содержат инструкции возврата, тогда как функции OS_main и OS_task содержат инструкцию возврата RET или RETI.
  • Функции naked не создают кадр для локальных переменных и не используют указатель кадра, тогда как функции OS_main и OS_task делают это при необходимости.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/AVR-Function-Attributes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API