Quale è la causa del
Reset ?
|
COME INDIVIDUARE LA CAUSA DEL RESET
Il determinare quale sia stata la causa non è una questione
inutile, come può apparire a prima vista, ma , al contrario, può essere una
necessità fondamentale per il funzionamento del programma.
Sopratutto negli enhanced, che dispongono di numerose fonti di Reset, tra cui
una istruzione specifica e un automatismo programmabile che scatta al
superamento in su o in già delle risorse dello stack.
Ad esempio, per un sistema non presidiato che mantenga una memoria della
situazione di lavoro sarà indispensabile sapere a seguito di quale causa si
è riavviato, sopratutto se utilizza il modo SLEEP.
Saper che il
reset
è dipeso
da cause software, come un errore nello stack, o da problemi sull'
alimentazione,
o dall' intervento manuale dell' opratore permette non solo di avre statistica
dell' accaduto, ma sopratutto di attivare la giusta sequenza di ripartenza.
Infatti, il RESET
consiste nello spostare il Program Counter all' indirizzo 0000h, dove ha
inizio la sequenza delle istruzioni. Che si arrivi a questo punto per l'
arrivo della tensione piuttosto che per un errore dello stack è notevolmente
differente, in quanto la situazione dei registri interni è differente. Questo
richiede che i due avvenimenti siano trattai in modo diverso.
Fortunatamente
esiste negli enhanced una struttura di flag abbastanza semplice per cui è
possibile implementare un algoritmo altrettanto semplice per individuare la
causa del Reset.
La via adeguata fa ricorso al registro RCON, che contiene la
maggior parte dei flag necessari .
Questo registro raccoglie i flag che indicano quale è stata la causa del
reset.
RCON
|
bit
|
IPEN
|
SBOREN
|
-
|
!RI
|
!TO
|
!PD
|
!POR
|
!BOR
|
funzione
|
R/W
|
R/W
|
0
|
R/W
|
R/1
|
R/1
|
R/W
|
R/W
|
-
bit 4 !RI
: Reset from instruction
1 = istruzione RESET non eseguita (va settato a 1 da programma)
...
0 = reset eseguito in seguito a istruzione RESET
-
bit 3 !TO
: Watychdog Time-Out
1 = viene posto a un power up, da una istruzione CLRWDT o dalla modalità
SLEEP
0 = reset eseguito in seguito al time out del watchdog
-
bit2 !PD
: Power Down detection
1 = viene posto a un power up o da una istruzione CLRWDT
0 = a seguito dell' esecuzione dell' istruzione SLEEP
-
bit 1 !POR
: Power On Reset
1 = viene posto a uno via software
0 = reset eseguito in seguito all' arrivo della Vdd (da settare via
programma)
-
bit 3 !BOR
: Brown Out Reset
1 = viene posto a uno via software
0 = reset eseguito in seguito all' intervento del circuito di BOR
Va osservato che i flag !BOR, !POR e !RI se a zero, indicano l'avvenuto
evento a cui sono collegati, ma non si riposizionano a 1 automaticamente;
infatti , essendo indicatori di evento, DEVONO essere settati dal programma,
dopo che ne abbia presa visione.
Così pure !PD, che viene settato da una istruzione di CLRWDT.
Da notare che !RI e !PD vanno a 1 anche dopo il power up del processore.
Inoltre sarà da considerare anche il registro
STKPTR, che contiene i flag relativi alla situazione dello stack. Le
possibili combinazioni dei flag contenuti in questi registri è raccolta nella
seguente tabella :
Avvenimento |
RI
|
TO
|
PD
|
POR
|
BOR
|
FUL
|
UNF
|
Arrivo della tensione di alimentazione (POR)
|
1
|
1
|
1
|
0
|
0
|
0
|
0
|
MCLR in funzionamento normale
|
-
|
-
|
-
|
-
|
-
|
-
|
-
|
MCLR in modalità SLEEP
|
-
|
1
|
0
|
-
|
-
|
-
|
-
|
Istruzione RESET
|
0
|
-
|
-
|
-
|
-
|
-
|
-
|
Overflow dello stack
|
-
|
-
|
-
|
1
|
1
|
-
|
1
|
Underflow dello stack
|
-
|
-
|
-
|
1
|
1
|
1
|
-
|
Time out del watchdog in funzionamento normale
|
-
|
0
|
1
|
-
|
-
|
-
|
-
|
Time out del watchdog in modo sleep
|
-
|
0
|
0
|
-
|
-
|
-
|
-
|
Caduta sulla tensione Vdd (BOR)
|
1
|
1
|
1
|
-
|
0
|
0
|
0
|
Uscita dal modo SLEEP a causa di un interrupt
|
-
|
0
|
0
|
-
|
-
|
-
|
-
|
- indica un bit che non viene modificato o che è ininfluente.
Questa tabella è ricavata dalla lettura dei fogli dati e
confermata dall' esperienza pratica
e da origine al flow chart seguente:
|
Il primo evento di reset che si determina nell'
attività del processore è certamente la messa sotto tensione, a cui
corrisponde la generazione di un POR.
Dalla tabella si evidenzia che il bit POR va a 0,
mentre altri sono pure a 0 o a 1.
Testando per prima cosa questo bit e portandolo poi a
livello 1, si è nelle condizioni di verificare con sicurezza le cause
di successivi reset.
Si potranno scrivere alcune righe :
whichReset:
btfsc RCON,POR ;
power
on ?
; se no va al test seguente
bra newtws
bsf RCON,POR
; si - set flag
...
; esegue gestione
da questo momento in avanti, POR sarà a zero solo per
una completa mancanza di tensione che riavvii il modulo POR. Ogni
altro reset non modificherà il settaggio a 1 di POR.
Una successiva possibile causa di reset è una caduta
della tensione, tale da non riavviare completamente il micro, ma di
livello e durata adeguati a far scattare il modulo BOR.
Va ricordato che BOR è attivabile o meno sia attraverso
il CONFIG sia via software.
Questo permette di inserire la verifica del Brown Out solo se è
richiesta.
|
Dalla tabella si
rileva che la caduta di tensione influisce su 4 bit : BOR, RI , PD, TO.
BOR avviene ovviamente quando il microprocessore è già stato attivato e un
reset da POR è stato generato e quindi il bit POR non è più utile all'
analisi, avendolo già portato a 1 nella fase precedente.
PD viene modificato
anche per l' intervento del watchdog e quindi non è utile in
questa fase di discriminazione.
Analoga
considerazione per TO che è modificato anche da MCLR. Anche RI viene
modificato da fonti diverse, ma ci sono anche cause di reset che non
influiscono su questo flag.
Sarà
però utile imporre a questo bit un valore definito dopo il POR, in modo da
poterlo usare per le discriminazioni successive.Quindi RI potrà utilmente
essere settato :
whichReset:
btfsc RCON,POR
; messa sotto tensione ?
bra notpor
; no - testa successivo
bsf RCON,POR
; si - set flag
bsf RCON,RI
; set flag RI
...
; esegue gestione
notpor
btfss RCON,BOR
; no - caduta di tensione ?
bra isbor
; si, esegue gestione
Il reset da istruzione modifica esclusivamente il flag RI,
portandolo a 0. Avendolo posto a 1 nella fase iniziale, ora potremo usarlo
utilmente per determinare se è stata eseguita l' istruzione reset.
whichReset:
btfsc RCON,POR
; messa sotto tensione ?
bra notpor
; no - testa successivo
bsf RCON,POR
; si - set flag
bsf RCON,RI
; set flag RI
...
; esegue gestione
notpor
btfss RCON,BOR
; no - caduta di tensione ?
bra isbor
; si, esegue gestione
btfss RCON,RI
; no - instruzione RESET ?
bra isoftres ;
si, esegue gestione
Se nel CONFIG è stata abilitata l' opzione, anche un
debordamento dello stack provoca un reset.
In conseguenza di questo, due flag del registro STKPTR possono essere settati
e sono questi che andremo a testare.
whichReset:
btfsc RCON,POR
; messa sotto tensione ?
bra notpor
; no - testa successivo
bsf RCON,POR
; si - set flag
bsf RCON,RI
; set flag RI
...
; esegue gestione
notpor
btfss RCON,BOR
; no - caduta di tensione ?
bra isbor
; si, esegue gestione
btfss RCON,RI
; no - instruzione RESET ?
bra isoftres ;
si, esegue gestione
btfsc STKPTR,STKFUL
; no - stack overflow ?
bra isstackful
; si, esegue gestione
btfsc
STKPTR,STKUNF
; no - stack underflow ?
bra isstackempty ;
si, esegue gestione
Anche lo scatto del watchdog o il pin MCLR generano un reset.
Ci vengono in aiuto i bit TO e PD.
Situazione
|
TO
|
PD
|
MCLR in funzionamento normale
|
-
|
-
|
MCLR in sleep
|
1
|
0
|
Watchdog in funzionamento normale
|
0
|
1
|
La situazione di reset per watchdog è
facilmente identificabile, ma MCLR in modo normale non modifica nessuno di
questi due bit. Verificando i possibili casi, si nota che la stessa
situazione dei bit nel caso di watchdog e di MCLR dopo un watchdog, il che
richiede di eliminarne uno forzando TO e PD a 1 dopo aver trattato il reset da
watchdog. Però TO e PD sono a sola lettura e, apparentemente non
modificabili. Però l' istruzione CLRWDT , oltre a ricaricare il contatore del
watchdog, porta a 1 i due flag.
Per determinare il caso di MCLR in modo sleep è necessario aggiungere una
istruzione CLRWDT dopo ogni risveglio per riportare a 1 il flag PD.
Di seguito una possibile routine di identificazione della
causa del reset.
Si deve avere l' accortezza di inserire nel programma le seguenti
considerazioni :
.
Al
reset, il bit POR va posto a 1, in modo tale che si possa distinguere una
successiva rimessa sotto tensione
BOR va posizionato a 1 ad ogni reset in modo da individuare
con sicurezza successivi suoi interventi
Ugualmente una istruzione CLRWDT dovrà essere impostata per
portare TO e PD a 1
Il codice finale
potrebbe essere questo:
;
identificazione della causa del reset
whichReset:
btfss RCON,POR
; messa sotto tensione ?
bra ispor
; si, esegue gestione
btfss RCON,BOR
; no - caduta di tensione ?
bra isbor
; si, esegue gestione
btfss RCON,RI
; no - instruzione RESET ?
bra isoftres ;
si, esegue gestione
btfsc STKPTR,STKFUL
; no - stack overflow ?
bra isstackful
; si, esegue gestione
btfsc
STKPTR,STKUNF
; no - stack underflow ?
bra isstackempty ;
si, esegue gestione
; reset da MCLR ?
btfss
RCON,TO
; TO = 0 ?
btfss RCON,PD
; si, PD = 1 ?
bra ismclr
; si, esegue gestione
; nessuno dei precedenti, allora è reset da watchdog
; gestione reset da WDT
iswdt: ;
esegue gestione
....
bra whcRstEnd
; gestione POR
ispor: ;
esegue gestione
....
bra whcRstEnd
; gestione BOR
isbor: ;
esegue gestione
....
bra whcRstEnd
; gestione istruzione reset
issoftres: ; esegue gestione
....
bra whcRstEnd
; gestione stack overflow
isstackful: ; esegue gestione
....
bra whcRstEnd
; gestione stack overflow
isstackempty: ; esegue gestione
....
; uscita con settaggio dei flag
whcRstEnd:
bsf RCON,POR
; POR = 1
bsf RCON,BOR
; BOR = 1
bsf RCON,RI
; RI = 1
bsf STKPTR,STKFUL
; STKFUL = 0
bsf STKPTR,STKUNF
; STKUNF = 0
clrwdt
; TO e PD = 1
return
Ovviamente se non viene mai posto il processore in modo SLEEP
o se non si fa uso del BOR o del pin MCLR o se il reset a causa dello stack è
disabilitato, possono essere omessi i test e le gestioni relative. Ugualmente
non sarebbe indispensabile il settaggio di tutti i flag, in quanto solo alcuni
di essi saranno modificati a seconda delle condizioni applicate, ma non ci
sono molte ragioni per complicare l' algoritmo allo scopo di risparmiare uno o
due cicli.
Nell' area di
download è disponibile un sorgente .ASM che da' una traccia per svolgere
questa funzione.
|
|
Copyright © afg. Tutti i diritti riservati.
Aggiornato il 24/10/10.
|