You are here

GCC Signal Attribute

Перевод может содержать ошибки. Читайте первоисточник: GCC Signal Attribute

Назад: [Как работает FreeRTOS] Вверх: [Как работает FreeRTOS] Вперёд: [Как работает FreeRTOS]

 

Среда разработки GCC позволяет писать прерывания на языке C. Например, обработчик прерывания AVR "compare A match" таймера 1 может быть написан с использованием следующего синтаксиса:

;-------------------------------------------------------------------------------
void SIG_OUTPUT_COMPARE1A( void ) __attribute__ ( ( signal ) );

void SIG_OUTPUT_COMPARE1A( void )
{
    /* ISR C code for RTOS tick. */
    vPortYieldFromTick();
}

Директива '__attribute__ ( ( signal ) )' в прототипе функции информирует компилятор о том, что эта функция является обработчиком прерывания. И тогда компилятор делает следующие изменения в объектном коде:

  1. Атрибут 'signal' гарантирует, что каждый регистр процессора, который был изменён при выполнении кода обработки прерывания, будет восстановлен к моменту завершения обработчика прерывания. Это необходимо потому, что компилятор не имеет ни малейшего представления, когда будут вызываться прерывания, и, следовательно, не может заранее определить, когда и какие регистры нужно сохранять.
  2. Также атрибут 'signal' заставляет использовать инструкцию 'возврат из прерывания' (RETI) вместо используемой по-умолчанию инструкции 'возврат' (RET). Дело в том, что ядро AVR запрещает прерывания при входе в обработчик прерывания, а инструкция RETI снова разрешает их.

Листинг компилятора будет выглядеть примерно так:

;-------------------------------------------------------------------------------
;void SIG_OUTPUT_COMPARE1A( void )
;{
    ; ---------------------------------------
    ; КОД, ГЕНЕРИРУЕМЫЙ КОМПИЛЯТОРОМ ДЛЯ
    ; СОХРАНЕНИЯ ЗНАЧЕНИЯ РЕГИСТРОВ, КОТОРЫЕ
    ; БУДУТ ИЗМЕНЕНЫ ВО ВРЕМЯ ВЫПОЛНЕНИЯ 
    ; ОБРАБОТЧИКА ПРЕРЫВАНИЯ.

    PUSH    R1
    PUSH    R0
    IN      R0,0x3F
    PUSH    R0
    CLR     R1
    PUSH    R18
    PUSH    R19
    PUSH    R20
    PUSH    R21
    PUSH    R22
    PUSH    R23
    PUSH    R24
    PUSH    R25
    PUSH    R26
    PUSH    R27
    PUSH    R30
    PUSH    R31
    ; ---------------------------------------

    ; КОД, ГЕНЕРИРУЕМЫЙ КОМПИЛЯТОРОМ НА
    ; ОСНОВЕ C-КОДА ПРИЛОЖЕНИЯ.

    ;vPortYieldFromTick();
    CALL    0x0000029B       ;Call subroutine
;}
    ; ---------------------------------------

    ; КОД, ГЕНЕРИРУЕМЫЙ КОМПИЛЯТОРОМ ДЛЯ
    ; ВОССТАНОВЛЕНИЯ РЕГИСТРОВ В ИХ
    ; ПРЕДЫДУЩЕЕ СОСТОЯНИЕ.

    POP     R31
    POP     R30
    POP     R27
    POP     R26
    POP     R25
    POP     R24
    POP     R23
    POP     R22
    POP     R21
    POP     R20
    POP     R19
    POP     R18
    POP     R0
    OUT     0x3F,R0
    POP     R0
    POP     R1

    RETI
    ; ---------------------------------------
 


Далее: Реализация FreeRTOS - The GCC Naked Attribute

Hobby's category: