please dont rip this site

PIC Microcontroller Memory Method

reentrant code

A subroutine is "re-entrant" if it is designed so that, if it is ever interrupted in the middle, and then the interrupt routine calls the same subroutine, then everything works the way it ought to work.

Alas, it is very difficult to write re-entrant code on the Microchip PIC processors.

For example, if you have a "square_root" subroutine, and you call it with "9", but while it is still calculating it gets interrupted, and the interrupt routine decides it needs to find the square root of "4" -- what happens? Most square root routines for the PIC will return the proper value "2" to the interrupt routine ... but when the calculation of the square root of "9" resumes, they wig out and return "2" or some other completely wrong answer.

Our options are:

nested interrupts require data stacks

(see also software stacks on the Scenix )

Nikolai Golovchenko says:

Yes, the nested interrupts are possible. The method I used on 16F84 processed two interrupts (RBIF and TMR0IF), but more interrupts could be okay. To do this, I use software stack macros (see attachment) that use FSR as a stack pointer. A typical interrupt handler looks like this:
            ORG     0x004                   ; interrupt vector location
            PUSHW                             ;store W
            PUSHSTATUS                 ;store STATUS

                                            ;code goes here

            POPSTATUS                      ;restore W
            POPW                            ;restore STATUS
            retfie                          ; return from interrupt

After storing W and STATUS goes usual interrupt flags polling .
As soon as a set flag is detected, it should be cleared and GIE=1 to allow other interrupts to actually interrupt the process.
Be careful not to allow too many interrupts to be processed, only the ones that have critical response time, because hardware stack may overflow. The best way is to keep GIE reset during the most critical interrupt so that it could finish without unwanted interrupts.
Priority of different interrupts is programmed by flags polling sequence(in case they trigger at the same time).
That's it.

By the way, I find software stack macros very useful in practically every program. The best example is when you need one scratch pad register. Using stack it's simple:

PUSH    ;reserve one byte on stack
....use INDF as a scratch pad reg
POP    ;restore stack

Good luck.

;*******************************
;Software stack organization
;*******************************
;FSR is a stack pointer
;Top of stack is in INDF
;Stack grows in upper addresses direction
;*******************************************************************
;MACRO:      INSTR.NUMBER:   STATUS INFLUENCE:          W INFLUENCE:
;
;PUSHW          2               no                      no
;POPW           3               no                      yes
;POPW2          2               yes!!!                  yes
;PUSHSTATUS     3               no                      yes!!!
;POPSTATUS      3               yes                     yes!!!
;PUSH           1               no                      no
;POP            1               no                      no
;*******************************************************************
;Notes: 1) FSR should point at the stack top
;       2) PUSHSTATUS and POPSTATUS must be used in pair,
;       because these macros mangle quadruples
;*******************************************************************

PUSHW   MACRO
        INCFSZ FSR, F   ;never goes zero, but STATUS is safe
        MOVWF INDF
        ENDM

POPW    MACRO
        SWAPF INDF, F
        SWAPF INDF, W	;same as movfw indf, but STATUS unchanged
        DECFSZ FSR, F   ;never goes zero, but STATUS is safe
        ENDM

POPW2   MACRO
        MOVF INDF, W
        DECFSZ FSR, F   ;the popped W STATUS is safe
        ENDM

PUSHSTATUS      MACRO
        SWAPF STATUS, W
        INCFSZ FSR, F   ;never goes zero, but STATUS is safe
        MOVWF INDF
        ENDM

POPSTATUS       MACRO
        SWAPF INDF, W
        MOVWF STATUS
        DECFSZ FSR, F
        ENDM

PUSH    MACRO
        INCFSZ FSR, F
        ENDM

POP     MACRO
        DECFSZ FSR, F
        ENDM

Robin Abbott of Forest Electronic Developments says:

This might be of use to someone. Recently I had a project where a subroutine took a value in W and saved to a software stack:

movwf Temp
movfw sp        ; Stack pointer
movwf FSR    ; Point to it
movfw Temp
movwf 0

Trouble is it uses a temporary variable which I didn't have (it is in an interrupt). This alternative which makes use of XOR uses no temporary variable at the expense of 1 extra word:

  movwf FSR
  movfw sp
  xorwf FSR
  xorwf FSR,w
  xorwf FSR
  movwf 0

You can also use this to swap two variables (say x and y) without a temporary variable leaving X (or Y if order is reversed) in W.

    movfw x       ; Get X
    xorwf y         ; Y is now X^Y
    xorwf y,w     ; W is now (X^y)^X==Y  (say OldY)
    movwf x       ; Now X is OldY
    xorwf y         ; finally Y is (OldX^Y)^Y==OldX

I think this may be an old technique - I have vague memories of something similar from the pre-history of programming, but only found a use for it now

(See math/bit/swap.htm for details. )

Timer tutorial (incl prescalers) by Andrew Warren

Are the stack-based math routines /techref/microchip/pfu.htm compatible with the above code?

James Cameron [quozl at us.netrek.org] says:

I've also done a software stack, mainly for mathematical functions, in order to significantly reduce memory (file register) utilisation on a 12C509. Not a call and return stack, just a parameter stack. http://quozl.netrek.org/stack-math.asm

{ed: This has now been expanded at http://quozl.netrek.org/uptime/ to include

FORTH on the PIC uses 2 software stacks: the Data stack and the "Rack" http://wiki.enst.fr/bin/view/Picforth/FakeReturnStack

deeper return stack

"PIC12C509 - Getting Around the Stack Limitation" by Peter H. Anderson 1997 http://www.phanderson.com/PIC/12C509/stack.html says "The 12C5 series PIC has only a two level stack which limits the number of nested subroutine calls to two. This may be a very serious limitation. (The 16C84 has an eight level stack which permits nested subroutines to eight deep. I can't imagine a program where this will not be sufficient).". That article describes one way of implementing a deep return stack, when the hardware return stack is inadequate.

See also

Interested:

Questions:


file: /techref/microchip/sstack.htm, 12KB, , updated: 2007/1/24 22:35, local time: 2008/8/28 22:48,
TOP NEW HELP FIND: 
38.103.63.61:LOG IN
©2008 PLEASE DON'T RIP! DO: LINK / DIGG! / MAKE!

 ©2008 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it!
<A HREF="http://www.piclist.com/techref/microchip/sstack.htm"> Software Stacks and Nested Interrupts</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be reviewed) Just type in the box and press the Post button. (HTML welcomed!): A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Did you find what you needed?

  PICList 2008 contributors:
o List host: MIT, Site host massmind.org, Top posters @20080828 Apptech, Jinx, Xiaofan Chen, olin piclist, Alan B. Pearce, Vitaliy, William \Chops\ Westfield, Tamas Rudnai, Cedric Chang, David VanHorn,
* Page Editors: James Newton, David Cary, and YOU!
* Roman Black of Black Robotics donates from sales of Linistep stepper controller kits.
* Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters.
* Monthly Subscribers: Shultz Electronics, Timothy Weber, on-going support is MOST appreciated!
* Contributors: Richard Seriani, Sr.
  'What can I do?' - SiCKO

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .