Salve a tutti!
Ho il seguente dubbio e mi farebbe piacere avere un confronto.
Ho un PIC su cui devo utilizzare n.2 interrupt provenienti da n.2 timer distinti; per necessità di organizzazione vorrei dare ai due interrupt la medesima priorità (low interrupt).
ciò che mi chiedo è:
cosa succede se mentre sto sviluppando la routine di interrupt del primo timer incorre la richiesta di interrupt per il secondo?
dubbio1: uscendo dalla routine e tornando al programma principale, se non ho resettato il flag di interrupt del secondo timer tornerò comunque dentro la ISR?
dubbio2: se ancora non sono uscito dalla ISR e controllo il flag del secondo timer scoprendo che è stato settato.. può venirne qualche problema dalla sua gestione e reset in questa fase?
Comportamento PIC con n. 2 Timer interrupt vicini
Moderatore:
Paolino
12 messaggi
• Pagina 1 di 2 • 1, 2
0
voti
Ciao
demos81, devi evitare le ricorsioni.
In generale, una volta che il Program Counter (il contatore di programma) è stato portato al vettore di interrupt, dovresti disabilitare (inertizzare) la riattivazione.
Questo vale a prescindere dalla causa alla quale può essere associato un interrupt (timer, seriale, comparatore ... ).
Quando hai terminato l'esecuzione corrente ripristini l'abilitazione.
Saluti
In generale, una volta che il Program Counter (il contatore di programma) è stato portato al vettore di interrupt, dovresti disabilitare (inertizzare) la riattivazione.
Questo vale a prescindere dalla causa alla quale può essere associato un interrupt (timer, seriale, comparatore ... ).
Quando hai terminato l'esecuzione corrente ripristini l'abilitazione.
Saluti
W - U.H.F.
-

WALTERmwp
30,2k 4 8 13 - G.Master EY

- Messaggi: 8986
- Iscritto il: 17 lug 2010, 18:42
- Località: le 4 del mattino
0
voti
demos81 ha scritto:Salve a tutti!
Ho il seguente dubbio e mi farebbe piacere avere un confronto.
Ho un PIC su cui devo utilizzare n.2 interrupt provenienti da n.2 timer distinti; per necessità di organizzazione vorrei dare ai due interrupt la medesima priorità (low interrupt).
ciò che mi chiedo è:
cosa succede se mentre sto sviluppando la routine di interrupt del primo timer incorre la richiesta di interrupt per il secondo?
Il secondo interrupt verrà ignorato, come se non fosse avvenuto.
demos81 ha scritto:dubbio1: uscendo dalla routine e tornando al programma principale, se non ho resettato il flag di interrupt del secondo timer tornerò comunque dentro la ISR?
No, il programma entrerà nella routine di IRQ solo la prima volta che si verifica l'interrupt, poi mai più.
demos81 ha scritto:dubbio2: se ancora non sono uscito dalla ISR e controllo il flag del secondo timer scoprendo che è stato settato.. può venirne qualche problema dalla sua gestione e reset in questa fase?
Non ho capito bene cosa intendi fare. come esattamente vorresti gestire la cosa?
0
voti
cerco di spiegarmi meglio, ho una situazione che semplifico di seguito:
ora, se ho ben capito se TMR1IF viene settato(quindi il secondo timer va in overflow) mentre sto ancora svolgendo la funzione Fciclica1 dovrei essere in grado di accorgermene dal secondo if e pertanto eseguire Fciclica2.
Quindi il rischio di perdere un esecuzione di funzione sotto interrupt sarebbe legata ai seguenti due casi:
1. perdo una esecuzione di Fciclica1 perché TMR0IF viene settato mentre sto svolgendo Fciclica2 oppure se sono appena entrato nella ISR (o meglio l'esecuzione ha superato il primo if) a causa di un interrupt su TMR1.
2. perdo una esecuzione ciclica di Fciclica2 perché sono entrato nella ISR a causa di un interrupt su TMR0 ma l'esecuzione ha già superato il secondo IF e pertanto l'overflow su TMR1 viene ignorata ...
in entrambi i casi l'interruzione persa non ricorrerà più perché non avrò resettato il flag.
Ho detto boiate?
- Codice: Seleziona tutto
void interrupt(){
if (TMR0IF==1){
//....Fciclica1
TMR0IF=0;
}
if (TMR1IF==1){
//....Fciclica2
TMR1IF=0;
}
}
void main(){
//.........programma ciclico
}
ora, se ho ben capito se TMR1IF viene settato(quindi il secondo timer va in overflow) mentre sto ancora svolgendo la funzione Fciclica1 dovrei essere in grado di accorgermene dal secondo if e pertanto eseguire Fciclica2.
Quindi il rischio di perdere un esecuzione di funzione sotto interrupt sarebbe legata ai seguenti due casi:
1. perdo una esecuzione di Fciclica1 perché TMR0IF viene settato mentre sto svolgendo Fciclica2 oppure se sono appena entrato nella ISR (o meglio l'esecuzione ha superato il primo if) a causa di un interrupt su TMR1.
2. perdo una esecuzione ciclica di Fciclica2 perché sono entrato nella ISR a causa di un interrupt su TMR0 ma l'esecuzione ha già superato il secondo IF e pertanto l'overflow su TMR1 viene ignorata ...
in entrambi i casi l'interruzione persa non ricorrerà più perché non avrò resettato il flag.
Ho detto boiate?
0
voti
La mia idea era di usare i due timer per generare due onde quadre su due pin diversi a frequenza differente e comunque variabile e rimodulabile nel tempo in maniera indipendente.
Solo che se le cose stan così rischierei di perdere il sincronismo ogni volta che i due fronti di salita o discesa si avvicinano troppo.
Solo che se le cose stan così rischierei di perdere il sincronismo ogni volta che i due fronti di salita o discesa si avvicinano troppo.
1
voti
Mi sembrava d'avere inserito un'altra risposta ma evidentemente mi confondo con un altro thread.
Nel Post [4], dal mio punto di vista, la risposta al caso (1) e al (2) è si.
Quello che però riporti come "perdo una esecuzione (...)" mi pare ambigua come affermazione.
Allora io fornisco una interpretazione poi facci sapere se è coerente con la tua riflessione, quindi: "perdi la esecuzione" di quello che diversamente avresti potuto eseguire nel corso dello svolgimento della corrente ISR (cioè della ISR in corso di svolgimento).
Tieni presente, però, che essendo disattivata l'abilitazione generale degli interrupt(s), il "trigger" relativo alla esecuzione che ti sei perso, si scatena (secondo interrupt) nel momento seguente al ripristino della abilitazione generale degli interrupt(s) (GIE).
A quel punto il vettore di interrupt viene riportato al Program Counter e la routine di interrupt (la ISR) viene di nuovo processata.
In pratica, nei casi da te ipotizzati, tra l'insorgenza dell'interrupt (per quanto sopra scritto si intende il secondo interrupt) e la esecuzione di quanto è previsto ed associato ad esso, ti ritrovi un delta temporale.
Questo delta (se non consideriamo la latenza prevista nel "silicio" e consistente in un paio di cicli "macchina" che intercorrono tra l'attivazione della flag di interrupt ed il caricamento del vettore di interrupt nel Program Counter) è pari al tempo che intercorre tra l'istante in cui si verifica l'evento (attivazione flag del secondo interrupt) e la completa esecuzione della ISR.
Questo è lo "sfasamento" che ti potresti ritrovare, in un certo istante, tra le due forme d'onda
Sono stato un po ripetitivo ma auspico si capisca e, sopratutto, spero sia corretto quanto scritto.
Confido comunque nel riscontro di qualcun altro.
Saluti
Nel Post [4], dal mio punto di vista, la risposta al caso (1) e al (2) è si.
Quello che però riporti come "perdo una esecuzione (...)" mi pare ambigua come affermazione.
Allora io fornisco una interpretazione poi facci sapere se è coerente con la tua riflessione, quindi: "perdi la esecuzione" di quello che diversamente avresti potuto eseguire nel corso dello svolgimento della corrente ISR (cioè della ISR in corso di svolgimento).
Tieni presente, però, che essendo disattivata l'abilitazione generale degli interrupt(s), il "trigger" relativo alla esecuzione che ti sei perso, si scatena (secondo interrupt) nel momento seguente al ripristino della abilitazione generale degli interrupt(s) (GIE).
A quel punto il vettore di interrupt viene riportato al Program Counter e la routine di interrupt (la ISR) viene di nuovo processata.
In pratica, nei casi da te ipotizzati, tra l'insorgenza dell'interrupt (per quanto sopra scritto si intende il secondo interrupt) e la esecuzione di quanto è previsto ed associato ad esso, ti ritrovi un delta temporale.
Questo delta (se non consideriamo la latenza prevista nel "silicio" e consistente in un paio di cicli "macchina" che intercorrono tra l'attivazione della flag di interrupt ed il caricamento del vettore di interrupt nel Program Counter) è pari al tempo che intercorre tra l'istante in cui si verifica l'evento (attivazione flag del secondo interrupt) e la completa esecuzione della ISR.
Questo è lo "sfasamento" che ti potresti ritrovare, in un certo istante, tra le due forme d'onda
Sono stato un po ripetitivo ma auspico si capisca e, sopratutto, spero sia corretto quanto scritto.
Confido comunque nel riscontro di qualcun altro.
Saluti
W - U.H.F.
-

WALTERmwp
30,2k 4 8 13 - G.Master EY

- Messaggi: 8986
- Iscritto il: 17 lug 2010, 18:42
- Località: le 4 del mattino
1
voti
Nella funzione dell'interruzione devi valutare sia il flag di interrupt del timer che ha provocato l'interruzione stessa e l'overflow dell'altro timer.
Eseguire altre funzioni direttamente dalla funzione di interruzione non mi è mai sembrata una buona idea. Meglio cambiare uno o più flag settati a piacere.
Eseguire altre funzioni direttamente dalla funzione di interruzione non mi è mai sembrata una buona idea. Meglio cambiare uno o più flag settati a piacere.
0
voti
simo85 ha scritto:Nella funzione dell'interruzione devi valutare sia il flag di interrupt del timer che ha provocato l'interruzione stessa e l'overflow dell'altro timer.
Eseguire altre funzioni direttamente dalla funzione di interruzione non mi è mai sembrata una buona idea. Meglio cambiare uno o più flag settati a piacere.
Mi hai preceduto!
anche io consiglio di scrivere una ISR più corta possibile, usando dei flag.
ciao!
0
voti
Intanto un grazie a tutti per la partecipazione e l'aiuto.
Considerate che le funzioni dentro gli interrupt sono davvero ridicole proprio il settaggio di qualche flag che attiverà poi delle funzioni nel main e poco più (considero un max di 3 4 istruzioni in C).
inoltre il mio principale problema non è nemmeno se le routine hanno una piccola latenza quanto la paura di "perdere" l'esecuzione
WALTERmwp da quel che dici tu al rientro nell'esecuzione del main (quindi uscendo dalla ISR) dato che il GIE bit viene ritirato su dovrei riscontrare un nuovo "trigger" relativo alla esecuzione che mi ero perso, e dovrei riuscire a recuperarla.
Questa situazione quindi mi andrebbe anche bene.. solo che ne son perplesso.
In teoria ho sempre letto che se io esco dalla routine di interrupt senza aver resettato un flag questo non darà più luogo a un interrupt per l'assenza del nuovo fronte di salita che dovrebbe attivarlo.
Quindi mi chiedo: se un flag si attiva mentre eseguo una routine di interrupt di ugual priorità, e io non la vedo quindi il suo flag rimane settato, per quale motivo il comportamento dovrebbe essere diverso?
se seguo la logica precedente sarei portato a credere che all'uscita dell'ISR e al set di GIE non verrà più eseguita l'interruzione associata al secondo flag/sorgente di interrupt, ne ora ne dopo.
Considerate che le funzioni dentro gli interrupt sono davvero ridicole proprio il settaggio di qualche flag che attiverà poi delle funzioni nel main e poco più (considero un max di 3 4 istruzioni in C).
inoltre il mio principale problema non è nemmeno se le routine hanno una piccola latenza quanto la paura di "perdere" l'esecuzione
Questa situazione quindi mi andrebbe anche bene.. solo che ne son perplesso.
In teoria ho sempre letto che se io esco dalla routine di interrupt senza aver resettato un flag questo non darà più luogo a un interrupt per l'assenza del nuovo fronte di salita che dovrebbe attivarlo.
Quindi mi chiedo: se un flag si attiva mentre eseguo una routine di interrupt di ugual priorità, e io non la vedo quindi il suo flag rimane settato, per quale motivo il comportamento dovrebbe essere diverso?
se seguo la logica precedente sarei portato a credere che all'uscita dell'ISR e al set di GIE non verrà più eseguita l'interruzione associata al secondo flag/sorgente di interrupt, ne ora ne dopo.
0
voti
demos81 ha scritto:Considerate che le funzioni dentro gli interrupt sono davvero ridicole
Ridicole no, però se questo è il codice:
- Codice: Seleziona tutto
void interrupt()
{
foo();
}
void foo()
{
/* ... */
}
Finché foo( ) non sarà terminata tu starai eseguendo una interruzione. E tu devi fare in modo che la funzione di interrupt sia il più corta possibile. Quindi secondo me è meglio non eseguire funzioni all'interno di una interrupt. In più le istruzioni di salto da una funzione ad un'altra, generalmente richiedono più cicli di clock per essere eseguite.
Poi:
demos81 ha scritto:La mia idea era di usare i due timer per generare due onde quadre su due pin diversi a frequenza differente e comunque variabile e rimodulabile nel tempo in maniera indipendente.
Sei sicuro che per cambiare lo stato di un pin e variare una temporizzazione, ti serva una funzione?
12 messaggi
• Pagina 1 di 2 • 1, 2
Torna a Firmware e programmazione
Chi c’è in linea
Visitano il forum: Nessuno e 0 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)



