6.33.6 Атрибуты функций AVR
Эти атрибуты функций поддерживаются бэкендом AVR:
-
signal interrupt-
Функция является обработчиком прерывания (ISR). Компилятор генерирует последовательности входа и выхода из функции, подходящие для использования в обработчике прерывания, когда один из атрибутов присутствует.
Аппаратное обеспечение AVR глобально отключает прерывания при выполнении прерывания.
- Обработчики прерываний с атрибутом
signalне восстанавливают разрешение прерываний. Безопасно разрешить прерывания в обработчикеsignal. Это «безопасность» относится только к коду, сгенерированному компилятором, а не к структуре IRQ приложения, которая является обязанностью приложения. - Обработчики прерываний с атрибутом
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игнорируется. - Обработчики прерываний с атрибутом
-
naked -
Этот атрибут позволяет компилятору сконструировать необходимую декларацию функции, при этом тело функции может быть кодом ассемблера. Указанная функция не будет иметь пролога/эпилога, сгенерированных компилятором. В функции «naked» безопасно включать только базовые
asmоператоры (см. Basic 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-14.2.0/gcc/AVR-Function-Attributes.html