Thank you Darrel. I appriciate the help.
Hi Darrel,
I'm a bit confused by the idea that a "RESUME (label)" is like a GOSUB. From the following quote in the PBP manual, it sounds more like RESUME (label) acts like a GOTO:
I've always used RESMUE with a label, as I want to RESUME at a known location in the code, and have never had any issues, even in large programs with lots of other sub-routines.When the RESUME statement is encountered at the end of the BASIC
interrupt handler, it sets the GIE bit to re-enable interrupts and returns to
where the program was before the interrupt occurred. If RESUME is
given a label to jump to, execution will continue at that location instead.
All previous return addresses will be lost in this case.
Any further info would be great. Thanks,
Arch
BUT as it erase all previous return address... it just clear the stack at the same time imho.
Let's say you're limited to a 4 level deep stack, everytime you'll RESUME you will eat one in place in the stack. Since your code don't do any Gosubs, it never give you problem, but one day, if you're at the stack limit, and then you add a RESUME LABEL, you may get this problem. Something to be tested i guess.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
Hi Steve,Originally Posted by mister_e
Well, that's what got me wondering. In other code with lots of gosubs, using a RESUME (label) has not caused any problems.
If the stack gets cleared with the RESUME (label), how would the stack overflow occur?
Thanks,
Arch
EDIT
Interesting info Darrel. Can't figure how any other code I've written with ON INTERRUPT continues to work - by the look of what you posted, the code should crash or go off in odd directions - but for some reason it does work OK even after a RESUME (label) followed by several subroutines. I'll have to try and figure that one out one of these days.
On that little sample above - I don't think the DISABLE / ENABLE are needed, as the interrupt handler comes before the ON INTERRUPT statement (at least that's what the manual says).
EndEDIT
Last edited by Archilochus; - 5th May 2006 at 04:22.
Forget me... see Darrel's explanation above. Sorry i didn't write a single code line and look the compiled file OR, like Darrel, look the According Macro.
Once again i failed
But BTW, if you never had any failure, it's probably because you don't use much nested gosub AND/OR you're a lucky guy!
Thanks Darrel, i just see some interesting stuff to do with that RST?RP nowI think i'll go deeper in the .LIB when i'll be back in Canada.
Last edited by mister_e; - 5th May 2006 at 04:21.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
I'm not sure how to interpret this bit from the same file that Darrel mentioned above:
From this, it looks like PBP does a GOTO to get to the interrupt handler (inthand?) - so no address would be placed on the stack since the handler is not a subroutine, is that right?;************************************************* ***************
;* ONINT?LL : Macro - On Interrupt Goto *
;* *
;* Input : L interrupt handler label *
;* : L interrupt checker label *
;* Output : None *
;* *
;* Notes : *
;************************************************* ***************
ONINT?LL macro Inthand, Intchk
local label
bsf INTCON, GIE
L?GOTO label
Intchk btfsc INTCON, GIE
return
L?GOTO Inthand
label
endm
ONINT_USED = 1
endmod
Arch
OK, so let's look at how the whole process of ON INTERRUPT works.
When an Interrupt occurs, the hardware turns off the GIE bit, pushes the current address on the stack and then vectors to address 4.
At address 4, PBP only puts 1 opcode. RETURN
This pops the hardware generated address from the stack and immediately returns execution to where it was before the interrupt. But leaves the GIE bit turned off, so that no other interrupts can occur until the last one is handled. Because, it can only be Handled, after PBP is done with whatever it was doing at the time.
Then in-between each and every line of code (that's not DISABLED) it does a CALL to the interrupt "Checker" which simply checks to see if GIE is a 0 or not. If it is 0, it means an interrupt occurred and it does the GOTO that you see in the ONINT?LL macro;
It's that CALL to the checker that puts the address on the stack, so that it can return back to the point in-between lines that it jumped from.
So again, if a return never happens, the stack builds up.
An interesting side note is that many people think you can turn OFF all interrupts by clearing the GIE bit (myself included previously). But what that really does with ON INTERRUPT is to make PBP think that an interrupt has happened, it calls the handler (which shouldn't do anything since no Flags are set) and then turns GIE back on again. In order to turn off interrupts globally, that section of code must be DISABLED.
It all boils down to the one statement in the manual that seems so innocuous.Can't figure how any other code I've written with ON INTERRUPT continues to work.
All previous return addresses will be lost in this case.
As long as you never want to go back to the sections of code that got interrupted, then the stack simply wraps around, and only NEW gosubs past that point will be returned to. That's not something that any of my programs would be able to tolerate.
Yup, you're right, anything before the ON INTERRUPT statement is considered DISABLED. My Bad.On that little sample above - I don't think the DISABLE / ENABLE are needed, as the interrupt handler comes before the ON INTERRUPT statement (at least that's what the manual says).
HTH,
Darrel
Hi Darrel,
Thanks for explaining further - I think the idea has finally got through my thick skull.
This must be why my programs keep working - once interrupted, everything the progam was doing is dropped, and the code never has to return back to before the interrupt, so the stray return addresses piling up on the stack just get overwritten when there are new GOSUBs or CALLs.It all boils down to the one statement in the manual that seems so innocuous.
All previous return addresses will be lost in this case.
As long as you never want to go back to the sections of code that got interrupted, then the stack simply wraps around, and only NEW gosubs past that point will be returned to. That's not something that any of my programs would be able to tolerate.
I'll have to keep this issue in mind if my code ever gets more complex! The PBP manual really should mention something about the potential stack problems with RESUME(label).
Thanks again,
Arch
Yes, the manual is a bit vague. But if we take a look at the macro's themself it should be a little clearer.
These are from the PBPPIC14.mac file.With only the RESUME it does a retfie (Return from Interrupt) which causes the hardware to turn GIE back on and pops the last address off the stack to return to.Code:;**************************************************************** ;* RESUME? : Macro - Resume * ;* * ;* Input : None * ;* Output : None * ;* * ;* Notes : * ;**************************************************************** RESUME? macro RST?RP retfie endm endmod ;**************************************************************** ;* RESUME?L : Macro - Resume Label * ;* * ;* Input : Label * ;* Output : None * ;* * ;* Notes : * ;**************************************************************** RESUME?L macro Label bsf INTCON, GIE L?GOTO Label endm endmod
But, if you include a label with the resume, all it does is set the GIE bit manually, then GOTO's the label. At this point, the address from the interrupt is still on the stack. Once the Subroutine has finished and does a RETURN. It will return to the point where the interrupt first happened.
If the subroutine doesn't do a RETURN, the stack keeps building up.
Also, that subroutine should be enclosed in DISABLE/ENABLE statments to keep it from being interrupted before it returns.
If you're OK with the idea of the stack wrapping around and Discarding all previous gosubs after an interrupt, then it'll still work that way on a 16F. But don't try it with an 18F.
HTH,
Darrel
Bookmarks