Какова нормальная задержка прерывания и время сохранения контекста на Microchip C18? - PullRequest
2 голосов
/ 21 июня 2011

Я использую компилятор Microchip C18, и при возникновении прерывания я испытываю довольно длительную задержку, прежде чем код ISR начинает работать.

В качестве эксперимента, это в моей основной функции:

while(1)
{
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 0;
}

В качестве обработчика прерываний я использую этот код, который я скопировал из некоторого примера (я не знаю, почему это так):

#pragma interrupt high_isr
void high_isr(void)
{
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 0;
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 1;
    LATAbits.LATA4 = 0;
}

#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm
}

Я получаю байты через SPI, и вскоре после получения байта основной цикл останавливается. Затем следует задержка в 16,5 мкс, прежде чем код ISR начнет работать. Это 165 инструкционных циклов!

interrupt timing увеличить изображение

Я знаю, что существует некоторое сохранение контекста, связанное с прерываниями, и что это еще хуже с прерываниями с низким приоритетом. Я отключил IPEN и использую только вектор с высоким приоритетом. Является ли 165 инструкций нормальной продолжительностью сохранения контекста?

Ответы [ 2 ]

3 голосов
/ 21 июня 2011

При некоторых обстоятельствах издержки прерывания могут быть такими же большими, как у вас!
Взгляните на this .

0 голосов
/ 09 февраля 2012

Ключом к получению хорошей производительности от прерываний на PIC является минимизация требуемого кода сохранения / восстановления контекста. Во многих случаях это означает запись критичных по времени частей обработчика прерываний в машинный код. Для частей, которые имеют по крайней мере некоторые небанкованные регистры, которые могут быть выделены для использования прерываний (мне очень не нравится решение Microchip сожрать большую часть или весь общий банк для адресации FSR2 вместо того, чтобы выделять, например, 15 байтов для адресации FSR2, по 7 байтов каждый Адресация FSR0 и FSR1 и один регистр «магических манипуляций» для каждого FSR [я бы хотел поговорить об идеях для таких вещей]) иногда можно обойтись без какого-либо сохранения / восстановления контекста в общем дело. Например, в одном из моих 14-разрядных проектов PIC мне требовалось прерывание каждые 1000 тактов. Так что с отключенным прескалярным RTCC мое прерывание было примерно таким:

INTERRUPT_ENTRY:
  bcf    INTCON,TMR0IF
  decfsz int_counter,f
   retfie
  movwf  saveW
  movf   STATUS,w
  clrf   STATUS  ; Bank 0
  movwf  saveStat
  movlw  4
  movwf  int_counter
  movlw  1024+3-1000  ' TMR0 unadjusted time, plus 3 'slip', minus desired time
  addwf  TMR0,f
  bsf    INTCON,GIE ; Interrupts can safely nest after this point!
  ... other interrupt stuff
  movf   saveStat,w
  movwf  STATUS
  swapf  saveW
  retfie ; Could just as well use RETURN, since interrupts are enabled  

Обратите внимание, что в 3/4 времени прерывание будет возвращаться после выполнения колоссальных трех инструкций, что в общей сложности займет около 6 циклов из любого кода, выполняемого ниже.

...