Istruzioni AVR SEI


13

L'istruzione SEI AVR ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) attende il completamento dell'istruzione successiva prima di abilitare gli interrupt.

Se uso un'altra istruzione per impostare il flag I in SREG, anche questo attenderà 1 istruzione?

In altre parole: l'attesa è una caratteristica dell'istruzione SEI o del registro di stato?

Se è una caratteristica dell'istruzione SEI, a che punto viene effettivamente impostato il flag, nel ciclo che esegue SEI o con l'istruzione successiva?


Questa è un'ottima domanda, ma non dovrebbe essere troppo difficile testare ed essere sicuri.
Vorac,

1
@Vorac Puoi darmi un esempio di come questo potrebbe essere testato? Questa sarebbe sicuramente la mia risposta accettata.
Jay

1
Potrebbe essere una caratteristica di un'implementazione dell'architettura AVR e in cui è possibile gestire gli interrupt. IIRC, l'architettura AVR utilizzava una pipeline a 3 stadi. Pertanto, l'istruzione successiva potrebbe essere già "in volo" (ovvero nella fase 1 della pipeline o più avanti) prima che il cambio della bandiera I possa essere utilizzato per verificare la presenza di interruzioni. Non ho cercato per molto tempo, ma non credo che i progettisti dell'architettura AVR si sarebbero auto-limitati. Quindi, testare l'interrupt per un'istruzione nella fase 1 della pipeline e non prima dell'istruzione successiva (nella fase 2) offre loro una certa flessibilità.
Bagliore

Risposte:


8

Risultati empirici!

Mentre le altre risposte sono ponderate e ben ragionate, sono tutte incomplete o solo congetture. Laddove la documentazione è ambigua, dobbiamo sperimentare e testare ogni caso.

Questa domanda merita una risposta conclusiva, quindi estraiamo un AVR e iniziamo a impostare alcuni bit!

Procedura

Per testare, ho realizzato un piccolo programma Arduino (ATMEGA328P) che avrebbe ...

  1. imposta un ISR che non restituirebbe mai ( while (1))
  2. assegnato l'ISR a una fonte che potrei innescare nel software ( INT0andando in basso)
  3. interruzioni disabilitate
  4. abilitato e attivato l'interrupt in modo che sia in sospeso

Ho usato un banco di prova che accendeva un LED nella singola istruzione dopo l'attivazione degli interrupt. Provando diversi modi per abilitare gli interrupt nel banco di prova e controllare il LED, sono riuscito a capire se l'istruzione dopo l'istruzione di abilitazione è stata eseguita o meno.

Se il LED non si accende, allora so che l'ISR è stato eseguito (e bloccato) immediatamente dopo l'attivazione degli interrupt.

Se il LED si è acceso, allora so che è stata eseguita l'esecuzione dell'istruzione successiva prima che fosse chiamato l'ISR.

risultati

SEI istruzione (caso base)

Codice:

sei

Risultato: LED acceso. Seguite le istruzioni eseguite.

OUT istruzione

Codice:

in  r16,0x3f   // Get SREG
ori r16,128    // Set I bit 
out 0x3f,r16   // Save back to SREG

Risultato:

LED acceso. Seguite le istruzioni eseguite.

ST istruzione

Codice:

   clr r29        // Clear Y high byte
   ldi r28,0x5f   // Set Y low byte to point to SREG
   ld r16, Y      // Get SREG
   ori r16,128    // Set I bit 
   st Y,r16       // Put SREG

Risultato:

LED acceso. Seguite le istruzioni eseguite.

Conclusione!

D: L'attesa è una caratteristica dell'istruzione SEI o del registro di stato?

A: Sembra che la modifica del Ibit in SREGsia da a 0a a 1consentirà l'esecuzione successiva delle seguenti istruzioni anche in presenza di un interrupt in sospeso, indipendentemente dall'istruzione utilizzata per impostare il bit.

Appunti

Questo in realtà si è trasformato in una domanda molto interessante con molte complicazioni. Se sei interessato ai dettagli, dai un'occhiata ...

http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/


2
Quando la specifica è ambigua, c'è un problema con "Risultati empirici". Semplicemente perché l'hardware specifico testato funziona in un modo specifico, non significa che altre parti funzioneranno in quel modo. Gli Atmel sono liberi di cambiare l'implementazione purché non modifichi le specifiche. Quindi, "Dove la documentazione è ambigua, ..." rimane esattamente che, dopo esperimenti e prove, è ancora ambigua.
Bagliore

@gbulmer Sono d'accordo al 100%. Chi utilizza funzioni prive di documenti nella produzione è destinato a essere triste. Ancora una domanda empirica interessante (e una risposta), e probabilmente ok per dipendere da un progetto personale unico.
bigjosh,

Sì, hai fatto un'indagine affascinante.
Bagliore

4

Secondo la mia documentazione, l'esecuzione seidell'istruzione non è diversa dalla scrittura diretta di 1 sull'I bit dell'SREG. Il vantaggio dell'istruzione è che non è necessario prima caricare un valore 1<<Iin un registro di lavoro per modificare l'SREG, risparmiando così tempo.

Per elaborare, usando sei:

sei ; One cycle

Impostazione del bit usando sbi(funzionerebbe solo se SREG fosse nei 32 byte inferiori della mappa del registro, ma sembra che nella maggior parte se non in tutto non lo è.)

sbi SREG,7 ; Two cycles

Scrivendo a I bit direttamente in SREG:

in  r24,SREG ;
ori r24,0x80 ;
out SREG,r24 ; Three cycles

Il Ibit deve essere impostato in SREG non appena l' seiistruzione (o sbio out) viene completata. Tuttavia, tutti gli interrupt in sospeso non verranno gestiti fino al completamento dell'istruzione successiva : il bit verrà impostato, ma è necessario un ciclo aggiuntivo per abilitare gli interrupt. Poiché un interrupt non può essere gestito a metà dell'istruzione e alcune istruzioni richiedono più di un ciclo per essere eseguite, specificano il tempo impiegato per essere abilitate come un'unica istruzione. Questo dovrebbe essere il caso di tutte le versioni del codice, vale a dire che ognuna delle precedenti causerà il ritardo di un'istruzione.


Dopo un po 'di ricerca, ho trovato questo thread sul forum Arduino in cui sono stati eseguiti diversi test per verificare il comportamento. Sembra essere d'accordo con quello che ho detto sopra.

Inoltre, secondo quel thread, se il Iflag è già impostato, allora non vi è alcuna risposta ritardata di un interrupt causato da seiciò implica che la risposta ritardata non è causata dall'istruzione stessa, ma piuttosto nell'hardware interno controllato dal Iflag - quindi qualsiasi operazione che cambi la bandiera in SREG, sia essa seio outo stsavrà esattamente lo stesso comportamento.


Quindi non c'è alcun aspetto nel ritardare l'operazione, specifico per SEI ma non OUT, che consenta di completare le seguenti istruzioni?
Brian Drummond,

Nel caso del secondo esempio, quando viene gestito un interrupt in sospeso? C'è un ritardo del ciclo come nel primo?
Jay

@jayjay guarda il mio aggiornamento.
Tom Carpenter,

1
Si noti che SBInon può essere utilizzato per impostare il Ibit in SREGmodo che qualsiasi codice che lo fa probabilmente non sia stato effettivamente testato nella vita reale perché non si monterà nemmeno. SBIpuò funzionare solo sui 32 registri inferiori e SREG si trova nello slot 63.
bigjosh,

@bigjosh l'esempio SBI era quello a cui pensavo più tardi - outera quello che stavo usando originariamente. Ho pensato di imbattermi in un AVR (potrebbe essere un ATTiny) che ha l'SREG nei 32 registri inferiori, ma potrei immaginarlo.
Tom Carpenter,

1

IMHO fa scrivere su SREG ancora ritardando 1 istruzione può essere testata in questo modo (pseudocodice):

ISR() { PORTA = 0; while(1); }
main() 
{
    cli();
    DDRA = 0xff;
    configure_isr_for_level_interrupt_that_will_trigger_immediately();
    SREG = 0xff;
    cli();
    PORTA = 0xff;
    while(1);
}

Purtroppo mi manca il tempo per farlo :(


0

Non è quello che dice. La documentazione dice

Le istruzioni seguenti SEI verranno eseguite prima di qualsiasi interruzione in sospeso.

non che aspetta la prossima istruzione. Ho letto questo dato che il flag è impostato immediatamente ma anche se abilitato, nessun interrupt verrà gestito fino a quando non verrà eseguita l'istruzione successiva.


Questo è tutto vero, ma la mia domanda è: questo comportamento è specifico del SEI?
Jay

@jayjay Sospetto che ciò sia dovuto alla lunghezza della pipeline delle istruzioni
crasica il
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.