IL REGISTRO RCON
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 7 IPEN
: Interrupt Priority ENable bits
1 =
abilita gli interrupt con livello di priorità
0 =
disabilita gli interrupt con livello di priorità
-
bit 6 SBOREN : BOR Software
ENable bit
se BOREN1:0 = 01 in CONFIG2L
1 = BOR abilitato
0 = BOR disabilitato
se BOREN1:0 = 00,10 o 11
bit non attivo e letto come 0
-
bit 5 non utlizzato - se letto,
riporta 0
-
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
Si tratta, come si vede, principalmente di flag dedicati all' identificazione
delle cause di un reset, oltre ad un bit di controllo, SBOREN (Software
BOR ENable), che abilita o disabilita la funzione BOR (solo, però, se nella
configurazione è stata scelta questa possibilità.)
Inoltre è presente un bit che ha poco a che fare con il reset ed è IPEN,
che abilita o disabilita la presenza di due livelli di interrupt
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 un 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.
Poichè le cause di reset possono essere molteplici, in alcune situazioni
può essere necessario determinare quale sia stata la causa, sia per ragioni
diagnostiche, sia per far fronte a particolari esigenze del sistema che il
processore sta controllando.
Alla luce di quanto sopra è possibile, con sufficiente facilità, derivare un algoritmo che permette di
identificare 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. 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.
Inoltre, dato che il reset può dipendere anche da cause software, come un
errore nello stack, o da problemi sull' alimentazione, ecco che l'
identificazione della causa di reset è indispensabile per una azione di debug.
La via adeguata fa ricorso al registro RCON, che contiene la maggior parte
dei flag necessari, ma anche al 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 .
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
; messa
sotto tensione ?
bra notpor
; no - testa successivo
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.
V a 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
:
-
Alla prima messa sotto tensione, la causa è certamente POR
-
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
; 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.