Tutorials - PIC18 by Data Sheet

 

Pagina 54-56

 


FAST REGISTER STACK

Un interessante meccanismo degli enhanced è il Fast Register Stack.

Nei mid range, una chiamata da interrupt richiedeva la classica  introduzione con il salvataggio dei registri principali e, all' uscita, il loro restore, risolto solitamente con due macro.

;+++++
; PUSH/PULL save and restore W,PCLATH,STATUS and FSR registers -
; used on interrupt entry/exit

PUSH    MACRO
    movwf Saved_W      ; save w reg
    swapf STATUS,W     ; affects NO status bits
    clrf  STATUS       ; sets to BANK0
    movwf Saved_Status ; save status reg
    movf  PCLATH,W
    movwf Saved_Pclath ; save pclath
    clrf  PCLATH
    movf  FSR,W
    movwf Saved_Fsr    ; save fsr reg
        ENDM

PULL    MACRO
    movf  Saved_Fsr,W    ; get saved fsr reg
    movwf FSR ; restore
    movf  Saved_Pclath,W ; get saved pclath
    movwf PCLATH         ; restore
    swapf Saved_Status,W ; get saved status in w
    movwf STATUS         ; restore status ( and bank )
    swapf Saved_W,F      ; reload into self to set status bits
    swapf Saved_W,W      ; and restore
        ENDM

 

E' chiaro che questa situazione richiede un certo numero di registri per il salvataggio, oltre a consumare spazio nella memoria programma e tempo nella sua esecuzione.

Anche qui gli enhanced risolvono brillantemente la situazione utilizzando un gruppo di registri dedicati ed un meccanismo che, in modo completamente automatico, provvede al salvataggio e al restore di WREG, STATUS e PC.

Questa possibilità viene attivata da programma indicando un suffisso FAST all' istruzione di ritorno dall' interrupt, che diventa:

      retfie FAST   ; rientro da interrupt e restore dei registri

E questa è l' unica azione da effettuare, dato che i registri:

  • WERG

  • STATUS

  • BSR 

sono stati salvati al momento della chiamata dell' interrupt in tre registri registri speciali, al di fuori della memoria ordinaria e  non altrimenti accessibili, chiamati WREGS, STATUSS e BSRS e da li vengono prelevati e riposizionati al ritorno in modo totalmente automatico e trasparente per il programmatore. 

Solitamente, non occorrendo altro per definire il contesto, questi tre elementi sono sufficienti. 

Il vantaggio di questa opzione consiste nel fatto che non è necessario implementare alcun salvataggio manuale dei registri, non vengono utilizzati registri di RAM accessibile e non viene impegnato alcun tempo supplementare per le operazioni di salvataggio e restore.

 

Questo sistema è utilizzabile anche per le chiamate a subroutine, per cui si potrà avere un:

     call subroutine, FAST 

la cui chiusura, che determina il restore automatico dei parametri salvati, è definito da :

return   FAST

Nel caso di un interrupt, non occorre alcuna indicazione FAST, in quanto il meccanismo provvederà ad avviarsi da se, mentre se voluto in una subroutine deve essere esplicitata, altrimenti è assente.

NOTA:

Da questo deriva che la parola FAST è riservata e non può essere altrimenti usata.

Se usato con criterio, il sistema FAST del salvataggio del contesto è pratico e potente, in quanto, oltre ad essere automatico, non richiede alcun tempo supplementare per la sua esecuzione e neppure consuma memoria.

Se usato con criterio in quanto esiste un solo livello di salvataggio che non sarà possibile utilizzare contemporaneamente per una chiamata a subroutine e per una di interrupt.
Ovvero, usando FAST intrinseco per la gestione dell' interrupt, non sarà possibile usare il metodo in una chiamata a subroutine che abbia la possibilità di sovrapporsi al tempo dell' interrupt stesso.

Inoltre, come chiarito nella sezione dedicata agli interrupt, i PIC18 dispongono di due livelli, di cui solo quello ad alta priorità potrà usare il metodo FAST, in quanto, avendo la possibilità di sovra passare una chiamata a bassa priorità, renderebbe inutile il salvataggio di ambiente di quest'ultima, sovrascrivendo i registri.

In questi casi, dovendo salvare il contesto, sarà necessario provvedere "manualmente" con la solita sequenza di istruzioni ed usando i registri disponibili in RAM.

Solitamente la disponibilità di un solo livello per il salvataggio automatico del contesto non crea grossi problemi, in quanto questa tecnica trova l' uso più intensivo nella gestione di interrupt veloci, e quindi prioritari come livello, piuttosto che nelle chiamate a subroutine.

 

 


AVVERTENZE:
  1. A riguardo delle subroutine, poi, occorre evidenziare che il metodo FAST è applicabile solo a chiamate "lunge" effettuate dall' istruzione  call e non a chiamate corte a seguito di un  rcall
    Ovvero :

    rcall   subroutinex , FAST

    non è possibile e non sarà accettata dall' assemblatore.

  2. Così pure non ha senso un retlw FAST , dato che una cosa del genere cercherebbe di recuperare un ipotetico registro W salvato , mentre intende ritornare nello stesso tempo con un determinato valore in W ! 

  3. La procedura di salvataggio nel Fast Register Stack è comandata dal suffisso FAST nel caso della CALL, ma è automatica nel caso dell' interrupt. Ovvero, alla chiamata da interrupt i registri sono salvati in ogni caso, anche se poi non saranno poi recuperati con il RETFIE FAST.
     
  4. Esiste un solo gruppo di registri dedicati a questa operazione, per cui potranno essere utilizzati solamente da una procedura per volta
    Se due procedure chiamano FAST in sequenza, i dati dell' ultima chiamante sovrascriveranno quelli precedenti, che andranno persi. 

Le conseguenze dei punti 2 e 3 sono queste:

  • se si sta utilizzando FAST nelle CALL, l' area di salvataggio potrà essere utilizzata da una sola CALL per volta
     
  • se si sta utilizzando l' interrupt, FAST per le CALL è possibile, ma assolutamente sconsigliabile, onde evitare sovrascritture
     
  • se si stanno utilizzando interrupt con priorità, si dovrà riservare il metodo FAST per l' interrupt a priorità alta e ricorrere ad un salvataggio manuale per l' ambiente dell' interrupt a bassa priorità (dato che un interrupt HP può interrompere un LP e quindi cancellarne i dati del Fast Register Stack).
  1. FAST salva solamente WREG, STATUS e BSR. Se devono essere salvati anche altri registri, ad esempio gli FSR, occorrerà aggiungere una gestione manuale per questi.

 

Dunque è evidente che il FAST è pensato dai progettisti principalmente per il servizio di interrupt ad alta priorità, ma , come bonus ulteriore, viene reso disponibile anche per le chiamate a subroutine.

I riassunto, la situazione è la seguente :

  1. non si utilizzano interrupt: il metodo FAST può essere applicato senza problemi alle chiamate a subroutine

  2. si impiegano interrupt ad un solo livello: in questo caso si utilizzerà il metodo FAST per la gestione dell' interrupt e, dove necessario, si salverà il contesto alle chiamate di subroutine con i classici mov

  3. si impiegano tutti e due i livelli di interrupt: in questo caso il FAST sarà riservato alle chiamate a priorità alta, mentre per quelle a bassa priorità ed eventualmente per le subroutine si provvederà "manualmente"

Una tipica sequenza di salvataggio "manuale" del contesto può essere la seguente:

 

ISR :
; save context

movwf wSave, 0
movff STATUS, statSave
movff BSR, bsrSave
movff FSR0L, fsr0lSave
movff FSR0H, fsr0hSave
...
...

;gestione interrupt
...
...

; restore context

movff fsr0lSave, FSR0L
movff fsr0hSave, FSR0H
movff bsrSave, BSR
movf  wSave, w, 0
movff statSave, STATUS
retfie

 

 

Se non si utilizza la sintassi FAST, il sistema di accesso e ritorno all' interrupt è lo stesso dei mid range e il salvataggio dei registri è completamente a carico del programmatore.

 

 


 

 

 

Copyright © afg. Tutti i diritti riservati.
Aggiornato il 04/11/10.