Определение функции (высокое прерывание) внутри или снаружи макроса C - PullRequest
1 голос
/ 17 января 2012

Для начала, я использую компилятор C18 для моей PIC.Когда я создаю функцию наподобие high_ISR без каких-либо вызовов, мой компилятор добавляет код, код, который я могу видеть только в представлении списка дизассемблирования.Это заставляет мою функцию high_ISR иметь время цикла, скажем, 160 циклов (но оно выглядит пустым, если смотреть на код C).

Вместо этого, если я определю это как макрос, у меня будет пусто «секретно».кодВозникнут ли у меня проблемы с другими функциями, что приведет к удалению кода, который мой компилятор тайно помещает туда, будет ли он справляться с этим другими способами?

Я имею в виду, я хочу, чтобы ISR были быстрыми.Есть ли способ сделать функцию ISR быстрой при записи функции в файл AC, могу ли я как-то подавить «секретный код».

См. Примеры кода ниже:

Правильное создание моего high_ISRфункция в файле .c, но с длительным циклом

#pragma interrupt highISR
void highISR(void)
{
    SomeFunction();
}

Макро созданная функция, например, в моем заголовочном файле (скажем, время цикла из 16 циклов)

#define FAST_INTERRUPT           \
    void highISR(void)           \
    {                            \
        SomeFunction();          \
    }

Просто для пояснения, Если я использую макрос, я реализую его как:

#pragma interrupt higISR
    FAST_INTERRUPT

Первое объявление highISR выдает это:

    #pragma interrupt highISR
323: void highISR(void)
 12B12    CFDA     MOVFF 0xfda, 0xfe4
 12B14    FFE4     NOP
 12B16    CFE2     MOVFF 0xfe2, 0xfda
 12B18    FFDA     NOP
 12B1A    CFE9     MOVFF 0xfe9, 0xfe4
 12B1C    FFE4     NOP
 12B1E    CFEA     MOVFF 0xfea, 0xfe4
 12B20    FFE4     NOP
 12B22    CFD9     MOVFF 0xfd9, 0xfe4
 12B24    FFE4     NOP
 12B26    CFDA     MOVFF 0xfda, 0xfe4
 12B28    FFE4     NOP
 12B2A    C1FB     MOVFF 0x1fb, 0xfe4
 12B2C    FFE4     NOP
 12B2E    C1FC     MOVFF 0x1fc, 0xfe4
 12B30    FFE4     NOP
 12B32    C1FD     MOVFF 0x1fd, 0xfe4
 12B34    FFE4     NOP
 12B36    C1FE     MOVFF 0x1fe, 0xfe4
 12B38    FFE4     NOP
 12B3A    CFF6     MOVFF 0xff6, 0xfe4
 12B3C    FFE4     NOP
 12B3E    CFF7     MOVFF 0xff7, 0xfe4
 12B40    FFE4     NOP
 12B42    CFF8     MOVFF 0xff8, 0xfe4
 12B44    FFE4     NOP
 12B46    CFF5     MOVFF 0xff5, 0xfe4
 12B48    FFE4     NOP
 12B4A    CFF3     MOVFF 0xff3, 0xfe4
 12B4C    FFE4     NOP
 12B4E    CFF4     MOVFF 0xff4, 0xfe4
 12B50    FFE4     NOP
 12B52    CFFA     MOVFF 0xffa, 0xfe4
 12B54    FFE4     NOP
 12B56    CFFB     MOVFF 0xffb, 0xfe4
 12B58    FFE4     NOP
 12B5A    EE05     LFSR 0, 0x500
 12B5C    F000     NOP
 12B5E    0E12     MOVLW 0x12
 12B60    04E8     DECF 0xfe8, W, ACCESS
 12B62    E303     BNC 0x12b6a
 12B64    CFEE     MOVFF 0xfee, 0xfe4
 12B66    FFE4     NOP
 12B68    D7FB     BRA 0x12b60
 12B6A    52E6     MOVF 0xfe6, F, ACCESS
324:                    {
325:                        SomeFunction();
 12B6C    EC48     CALL 0x14090, 0
 12B6E    F0A0     NOP
327:                    }
 12B70    52E5     MOVF 0xfe5, F, ACCESS
 12B72    EE05     LFSR 0, 0x511
 12B74    F011     NOP
 12B76    0E12     MOVLW 0x12
 12B78    04E8     DECF 0xfe8, W, ACCESS
 12B7A    E303     BNC 0x12b82
 12B7C    CFE5     MOVFF 0xfe5, 0xfed
 12B7E    FFED     NOP
 12B80    D7FB     BRA 0x12b78
 12B82    CFE5     MOVFF 0xfe5, 0xffb
 12B84    FFFB     NOP
 12B86    CFE5     MOVFF 0xfe5, 0xffa
 12B88    FFFA     NOP
 12B8A    CFE5     MOVFF 0xfe5, 0xff4
 12B8C    FFF4     NOP
 12B8E    CFE5     MOVFF 0xfe5, 0xff3
 12B90    FFF3     NOP
 12B92    CFE5     MOVFF 0xfe5, 0xff5
 12B94    FFF5     NOP
 12B96    CFE5     MOVFF 0xfe5, 0xff8
 12B98    FFF8     NOP
 12B9A    CFE5     MOVFF 0xfe5, 0xff7
 12B9C    FFF7     NOP
 12B9E    CFE5     MOVFF 0xfe5, 0xff6
 12BA0    FFF6     NOP
 12BA2    CFE5     MOVFF 0xfe5, 0x1fe
 12BA4    F1FE     NOP
 12BA6    CFE5     MOVFF 0xfe5, 0x1fd
 12BA8    F1FD     NOP
 12BAA    CFE5     MOVFF 0xfe5, 0x1fc
 12BAC    F1FC     NOP
 12BAE    CFE5     MOVFF 0xfe5, 0x1fb
 12BB0    F1FB     NOP
 12BB2    CFE5     MOVFF 0xfe5, 0xfda
 12BB4    FFDA     NOP
 12BB6    CFE5     MOVFF 0xfe5, 0xfd9
 12BB8    FFD9     NOP
 12BBA    CFE5     MOVFF 0xfe5, 0xfea
 12BBC    FFEA     NOP
 12BBE    CFE5     MOVFF 0xfe5, 0xfe9
 12BC0    FFE9     NOP
 12BC2    CFE5     MOVFF 0xfe5, 0xfda
 12BC4    FFDA     NOP
 12BC6    0011     RETFIE 0x1

Вторая функция только производит это ->

322:      #pragma interrupt highISR
323:          FAST_INTERRUPT
 13742    CFDA     MOVFF 0xfda, 0xfe4
 13744    FFE4     NOP
 13746    CFE2     MOVFF 0xfe2, 0xfda
 13748    FFDA     NOP
 1374A    52E6     MOVF 0xfe6, F, ACCESS
 1374C    0105     MOVLB 0x5
 1374E    5140     MOVF 0x40, W, BANKED
 13750    1A77     XORWF 0xf77, F, ACCESS
 13752    96A4     BCF 0xfa4, 0x3, ACCESS
 13754    2877     INCF 0xf77, W, ACCESS
 13756    6078     CPFSLT 0xf78, ACCESS
 13758    86A4     BSF 0xfa4, 0x3, ACCESS
 1375A    7E8B     BTG 0xf8b, 0x7, ACCESS
 1375C    0011     RETFIE 0x1
 1375E    52E5     MOVF 0xfe5, F, ACCESS
 13760    CFE5     MOVFF 0xfe5, 0xfda
 13762    FFDA     NOP
 13764    0011     RETFIE 0x1

Дополнительные пояснения, чтобы показать, что сами функции написаны одинаково: Для первой процедуры ->

void SomeFunction(void)
{
    if(PIR3bits.TMR4IF)
    {
        PIR3bits.TMR4IF = 0; 

        PR4 ^= _SoftPWM_Toggle;

        _asm
            INCF PR4,0,ACCESS 
            CPFSLT TMR4,ACCESS 
        _endasm

            PIR3bits.TMR4IF = 1; 

        SOFT_PWM_PIN ^= 1;
    }
}

Второй в заголовке как макрос ->

#define FAST_INTERRUPT \
    void highISR(void) \
    { \
        PR4 ^= _SoftPWM_Toggle; \
        \
        PIR3bits.TMR4IF = 0; \
        \
        _asm \
            INCF PR4,0,ACCESS \
            CPFSLT TMR4,ACCESS \
        _endasm \
        \
            PIR3bits.TMR4IF = 1; \
        \
        SOFT_PWM_PIN ^= 1; \
        \
        _asm \
            RETFIE 1 \
        _endasm \
    }

1 Ответ

2 голосов
/ 21 января 2012

Я не думаю, что это мусор во время выполнения. Помните, что прерывание может произойти где угодно в вашем коде основной строки. Когда вы вернетесь из прерывания, вы ожидаете, что ваш код получит то же состояние, в котором остановился. Компилятор добавляет код для сохранения этого состояния в начале ISR, а затем для восстановления состояния в конце прерывания. Если этого не происходит, и вы изменяете регистр или ячейку памяти в ISR, которую использовал код основной строки, то есть вероятность, что код не будет выполняться так, как ожидается, когда ISR вернется. Исключив сгенерированный компилятором код, вы передали ответственность за ISR для сохранения, а затем восстановления состояния основного кода. Если вы можете гарантировать, что все будет в порядке (пустой ISR будет примером, он никогда не изменит состояние). Если вы не можете, странное выполнение кода произойдет, когда вы вернетесь к основной строке кода из ISR. Если вы используете высокоуровневый скомпилированный язык, трудно понять, что он использует под прикрытием, поэтому компилятор сгенерирует код сохранения состояния для вашего ISR безопаснее, чем пытаться сделать это самостоятельно.

Предлагаю вам ознакомиться с документацией к руководству пользователя компилятора C MPLAB® C18. В директиве #pragma interupt есть дополнительные параметры, которые позволяют вам немного настроить, какая информация о состоянии сохраняется.

...