Come funziona lo stack di chiamate durante un'interruzione su AVR?


8

(Specifico per Arduino Uno ...)

Cosa succede allo stack quando si verifica un interrupt su un microcontrollore AVR e chiamo una funzione? Il compilatore incorpora il codice? Mette in cache lo stack da qualche parte e quindi reimposta il puntatore dello stack? Ha uno stack secondario solo per gli interrupt?

A quanto ho capito, il vettore per l'interrupt è un comando GOTO diretto nell'assembly. Inoltre, non penso che il microcontrollore si rovinerebbe automaticamente con lo stack, quindi è probabilmente lasciato solo. Tuttavia, ciò non spiega ancora come funzionano le funzioni durante un ISR.


La risposta di seguito è ottima, ti preghiamo di notare che il compilatore non può incorporare le chiamate di interruzione perché ... Sono chiamate di interruzione: D
Vladimir Cravero,

1
@VladimirCravero Intendevo incorporare le funzioni chiamate all'interno dell'interrupt (se chiamo foo () nell'ISR lo incorpora, quindi non è proprio una chiamata di funzione?)
Anonymous Penguin

Quindi la risposta qui sotto non risponde alla tua domanda o no? cavernicolo spiega cosa succede quando si verifica un interrupt, ma non cosa succede quando una funzione viene chiamata in un contesto interrotto. la risposta a quest'ultima sarebbe: niente di speciale, la funzione viene chiamata e basta. la magia accade quando viene attivato l'interrupt, ciò che accade dopo (prima dell'iret) è un codice normale, di solito ininterrotto.
Vladimir Cravero,

@VladimirCravero sì, lo fa (indirettamente). Stavo parlando di come lo stack è stato modificato per un ISR, pensando che per prima cosa doveva essere modificato per usare le funzioni. Immagino che le funzioni funzionino allo stesso modo dopo l'installazione dell'ISR.
Pinguino anonimo

bene, ce l'hai allora. dopo il salto al vettore di interruzione tutto va bene e puoi andare in giro dove vuoi.
Vladimir Cravero,

Risposte:


16

L'AVR è un'architettura RISC, quindi ha una gestione hardware piuttosto basilare degli interrupt. La maggior parte dei processori fa casino con lo stack durante gli interrupt, sebbene ci siano un paio, in particolare ARM e PowerPC, che usano metodi diversi.

In ogni caso, questo è ciò che AVR fa per gli interrupt:

Quando si verifica un interrupt, l'hardware del processore esegue questi passaggi, che non sono solo un semplice GOTO:

  1. Termina l'istruzione corrente.
  2. Disabilita il flag di interruzione globale.
  3. Inserisci l'indirizzo della prossima istruzione in pila.
  4. Copiare l'indirizzo nel vettore di interrupt corretto (in base all'interrupt che si è verificato) nel contatore del programma.

Ora a questo punto, l'hardware ha fatto tutto ciò che stava per fare. Il software deve essere scritto correttamente per non rompere le cose. In genere, i passaggi successivi sono in questo senso.

  1. Inserire il registro di stato nello stack. (Questo deve essere fatto prima di essere modificato).

  2. Inserire tutti i registri della CPU che saranno (o potrebbero essere) modificati nello stack. I registri che devono essere salvati in questo modo sono definiti dal modello di programmazione. Il modello di programmazione è definito dal compilatore.

Ora è possibile eseguire il codice di interruzione funzionante. Per rispondere al caso relativo alla chiamata di una funzione, fa semplicemente quello che fa sempre, spinge il valore di ritorno nello stack, quindi lo riavvia al termine. Ciò non influisce su nessuno di questi valori precedenti che abbiamo salvato nello stack fino ad ora.

  1. Esegui il codice di lavoro ISR.

Ora abbiamo finito e vogliamo tornare dall'interruzione. Innanzitutto dobbiamo eseguire la pulizia del software.

  1. Pop i registri della CPU che abbiamo inserito nel passaggio 6.
  2. Riporta il valore di stato salvato nel registro di stato. Dopodiché dobbiamo stare attenti a non eseguire alcuna istruzione che potrebbe cambiare il registro di stato.
  3. Eseguire l'istruzione RTI. L'hardware esegue questi passaggi per questa istruzione:

    un. Abilita il flag di interruzione globale. (Si noti che è necessario eseguire almeno un'istruzione prima che venga rispettato l'interruzione successiva. In questo modo si evita che interruzioni pesanti blocchino completamente il lavoro in background.)

    b. Inserisci l'indirizzo di ritorno salvato nel PC.

Ora torniamo al codice normale.

Si noti che ci sono alcuni punti in cui dobbiamo stare molto attenti, in particolare attorno al registro di stato e ai registri di salvataggio che potrebbero essere modificati. Fortunatamente se si utilizza un compilatore C, tutto questo viene gestito sotto le copertine.

Inoltre, devi guardare la profondità del tuo stack. In qualsiasi momento in cui gli interrupt sono abilitati, un ISR potrebbe usare più dello stack di quanto sia ovvio guardando il codice locale. Ovviamente, questo non viene fuori molto se non spingi la tua memoria al limite.

Ecco un link che descrive questo processo se si desidera un riferimento.


Qual è lo scopo dei passaggi 5/6? Mi sembra sciocco non modificare direttamente i registri, anche se immagino che pasticciare con alcuni registri durante gli interrupt possa creare alcuni risultati negativi.
Pinguino anonimo il

1
I passaggi 5 e 6 salvano lo stato corrente (prima dell'interrupt) del sistema, in modo che possa essere ripristinato (passaggi 8 e 9) al termine dell'interrupt, per consentire al programma principale di continuare come se non fosse stato interrotto.
Peter Bennett,

1
Questo è un eccellente riassunto.
Connor Wolf,

3
E 'anche interessante notare, che se davvero, davvero sapere cosa si sta facendo, è possibile disattivare il salvataggio automatico dello stato e di altri registri, con una bandiera GCC ( ISR_NAKED). Questo può farti saltare i passaggi 5,6,8,9, in un contesto in cui hai davvero bisogno di quei cicli. Il rovescio della medaglia è che devi essere assolutamente certo di conservare i registri pertinenti o di sovrascriverli senza danni.
Connor Wolf,

2
È interessante da sapere, ma farei la programmazione degli assiemi prima di usare quella bandiera. Così pericoloso ...
uomo delle caverne
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.