Abilita interruzione ma nessun ISR


10

Vorrei sapere cosa succede se è abilitato un Interrupt (es: Arbitration Lost Interrupt nel modulo CAN dell'LPC1778 di NXP), ma non è stato definito alcun ISR per l'interrupt.

Quando si verifica tale interruzione, so che verrà impostato il rispettivo flag di interruzione, ma poiché non ho definito alcun ISR, non vi sarà alcun indirizzo di offset vettoriale di interruzione memorizzato per il trasferimento di controllo per tale interruzione e quindi il controllo passerà indietro alla routine principale, e posso resettare il flag di interrupt eseguendo il polling nella routine principale (questo è quello che sto pensando). Ci sarà qualche latenza quando la CPU sta scoprendo che non c'è ISR su cui saltare?

Qualsiasi soluzione su ciò che potrebbe accadere può davvero aiutarmi.

Grazie.

Aggiornare:

Ho abilitato CAN Interrupt sul mio uC, ma non ho definito un ISR. Quando ho eseguito un test di loopback interno, il codice è entrato in un loop infinito. Ecco il codice di disassemblaggio del loop infinito in esecuzione su LPC1778:

B       .
ENDP

Quindi, se stai usando gli interrupt, usa l'ISR.


3
Non è necessario abilitare l'interrupt per poter eseguire il polling dei flag nella funzione principale. Se si verifica la condizione che imposta il flag, quel flag verrà impostato indipendentemente dall'attivazione dell'interrupt associato.
brhans,

Stai dicendo che verrà impostato un flag di interruzione Perso dell'arbitrato del bus anche se non abilito "Interrompi in caso di perdita dell'arbitrato del bus" (anche se non esiste un registro di stato che possa indicare la perdita dell'arbitrato del bus tranne il registro dello stato di interruzione)?
AlphaGoku,

Sì. In ogni MCU con cui ho lavorato, i flag di interrupt vengono impostati ogni volta che si verifica la condizione che li dovrebbe impostare. Abilitando l'interrupt si fa in modo che l'MCU vettori al gestore quando è impostato il flag associato e disabilitando l'interrupt si fa in modo che ignori il flag e non vettori al gestore anche se il flag è impostato . Disabilitare / abilitare l'interrupt influisce solo sul comportamento del gestore da salto a interrupt, non sul comportamento di impostazione della bandiera.
brhans,

Wow. Qualcosa che non sapevo. Molte grazie. Quindi ogni driver deve controllare periodicamente anche i registri di stato degli interrupt e ripristinarli anche se gli interrupt non sono stati abilitati :)
AlphaGoku

@AkshayImmanuelD solo se è importante. Se l'interruzione è sempre disabilitata e nient'altro si preoccupa della bandiera, allora se è impostato o cancellato è irrilevante.
Hobbs

Risposte:


17

Se non è stato definito alcun ISR, la posizione dell'istruzione di salto nel vettore di interrupt sarà nulla, potrebbe essere un salto a una routine di eccezione, può saltare all'inizio del programma o può contenere un "ritorno da istruzione "interrupt" (ad es. RTI).

Ecco uno smontaggio di una tabella di interrupt per un processore ATMega 16 che mostra tre interrupt inutilizzati associati a una routine che gestisce tali casi (può semplicemente andare in un ciclo infinito) e un vettore legittimo.

  28:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  2c:   0c 94 5c 00     jmp 0xb8    ; 0xb8 <__vector_11>   // <-- ISR
  30:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>
  34:   0c 94 47 00     jmp 0x8e    ; 0x8e <__bad_interrupt>

Quale dei metodi descritti in precedenza per la gestione di un ISR mancante dipenderà sia dall'architettura del microcontrollore che dal compilatore. Nel caso di un'istruzione RTI o equivalente, tornerà immediatamente all'applicazione. Tuttavia, se l'interrupt è attivato dal livello anziché dall'avvio, questo probabilmente farà scattare nuovamente l'interrupt, quindi si finisce in un ciclo infinito.

Penso che possa dipendere dall'architettura del chip se gli interrupt interni (ad esempio un personaggio ricevuto da un UART) siano considerati innescati dal livello o innescati dal limite. Gli interrupt esterni possono generalmente essere configurati come l'uno o l'altro.

C'è anche un altro caso, a volte diversi interrupt sono raggruppati insieme e usano lo stesso vettore. Ciò era particolarmente vero per i processori più vecchi che avrebbero potuto avere solo un paio di interruzioni. In tal caso, la causa dell'interrupt è stata determinata sondando lo stato dei registri degli interrupt, che è un po 'come quello che proponete.

Ma è in ogni caso una cattiva pratica avere interruzioni in un sistema e nessun ISR definito. Non farlo


2
.... o può essere indefinito.
Wouter van Ooijen,

@WoutervanOoijen questo è ciò che intendevo con null vettore di interrupt.
Tcrosley,

1
I registri di stato non possono indicare alcuni errori come quello che ho menzionato sopra. Ma tali errori hanno un interrupt. Quindi ho pensato di abilitare l'interrupt solo per identificare l'errore e non usare alcun ISR. Durante la simulazione dell'LPC1778 utilizzando Keil, non ho ricevuto alcuna eccezione, quindi immagino che l'UC debba usare l'RTI come
hai

1
Qualcosa di cui essere consapevoli: se abiliti un interrupt, ma il gestore non cancella il flag (o non esiste un gestore e il comportamento predefinito è un semplice ritorno), molto probabilmente scoprirai che il tuo MCU finirà per sempre bloccato in un ciclo di interruzione.
brhans,

1
Gli interrupt PIO sull'ATSAM3X8E possono essere innescati dal fronte, ma la condizione di interrupt una volta impostata non verrà cancellata fino a quando non si legge l'ISR (registro dello stato di interrupt) nel gestore degli interrupt, risultando nel loop @brhans menzionato.
Simon Wright,

1

Dipende dall'MCU, dal compilatore e dal resto del codice.

Dalla mia esperienza:

  1. AVR: per impostazione predefinita se non si specifica un ISR, il vettore di interrupt in flash sarà 0x0000, il che significa che l'applicazione passerà al ripristino ogni volta che si verifica questo interrupt.

    Se hai davvero bisogno dell'interrupt, ma non hai bisogno del gestore (ad es. Usa la modalità di spegnimento a basso rumore ADC e usa l'interrupt solo per riattivare l'MCU) dovresti usare la macro EMPTY_INTERRUPT

  2. NXP Kinetis (ARM) - tutti i vettori di default puntano a un gestore predefinito che ha un punto di interruzione, la CPU si fermerà semplicemente e lo comunicherà al tuo debugger.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.