2011-06-20 3 views
1

J'utilise le compilateur Microchip C18 et à l'apparition d'une interruption, j'éprouve un délai assez long avant que le code ISR commence à fonctionner.Qu'est-ce qu'une latence d'interruption normale et un temps d'économie de contexte sur Microchip C18?

A titre d'expérience, cela est dans ma fonction principale:

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

Comme gestionnaire d'interruption j'utilise ce code je copiais de quelques exemples (je ne sais pas pourquoi il a fait de cette façon):

#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 
} 

Je reçois des octets via SPI et peu après la réception d'un octet, la boucle principale s'arrête. Ensuite, un délai de 16,5 μs suit avant que le code ISR ne commence à fonctionner. C'est 165 cycles d'instruction!

interrupt timing enlarge image

Je sais qu'il ya un certain sauvegarde de contexte associé à des interruptions et qu'il est encore pire avec de faibles interruptions prioritaires. J'ai désactivé IPEN et j'utilise seulement le vecteur de haute priorité. Les instructions 165 ont-elles une durée normale d'économie de contexte?

Répondre

2

Dans certaines circonstances, les interruptions peuvent être importantes.
Jetez un oeil à this.

+0

+1 Je le savais mais je pensais que c'était la fonction qui s'appelait réellement ce qui prend beaucoup de temps. Excellente FAQ. – AndreKR

0

La clé pour obtenir de bonnes performances à partir des interruptions sur le PIC est de minimiser l'étendue du code de sauvegarde/restauration de contexte requis. Dans de nombreux cas, cela signifie écrire les parties critiques du gestionnaire d'interruptions dans le code machine. Sur les parties qui ont au moins quelques registres non bancarisés qui peuvent être utilisés pour interrompre l'utilisation (je déteste vraiment la décision de Microchip d'engloutir la totalité ou la totalité de la banque commune pour l'adressage FSR2, au lieu d'allouer 15 octets pour l'adressage FSR2 Adressage FSR0 et FSR1, et un registre de «manipulation magique» pour chaque FSR [j'aimerais discuter des idées pour de telles choses]) il est parfois possible de se passer de n'importe quel contexte enregistrer/restaurer dans le cas commun. Par exemple, dans l'un de mes projets PIC 14 bits, j'avais besoin d'une interruption tous les 1000 cycles d'horloge. Donc, avec RTCC prescalar désactivé, mon interruption était quelque chose comme:

 
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 

Notez que 3/4 du temps, une interruption sera de retour après l'exécution d'un total énorme de trois instructions, prenant un total d'environ 6 cycles de tout le code s'exécutait en dessous.

+0

La question concerne le compilateur C18. Bien que peut-être utile, je ne peux pas faire la tête ou la queue de votre réponse, sauf si vous le mettez dans son contexte. Je ne sais même pas où mettre ce code de montage en ligne. – AndreKR

Questions connexes