Interrupt And Return

mushroom

New Member
My understanding is that I must have a 'Return' at the end of an interrupt sub. This returns the program to the line after where the interrupt occured. My problem is that if an interrupt accures I wish the program to goto Main, not return to next line. Any thoughts or ideas?
 

westaust55

Moderator
The RETURN at end the interrupt routine is mandatory.

One way is to set a flag (e.g. Make a bit variable = 1)
Then frequently in your code check if that flag is set and if so go to the Start of the Main loop.
Don't forget to clear (=0) that flag variable.


The topic arises from time to time. Here is a past thread:
http://www.picaxeforum.co.uk/showthread.php?26834-Consequences-of-leaving-and-interrupt-with-GOTO

If you don't need to preserve any values in variables or output pin states then the RESET command is an option.
 
Last edited:

lbenson

Senior Member
A listing of your program and more information about what it is doing and why you must return to Main would help people provide solutions.

"RESET" is sometimes an option. Your interrupt routine can set up initialization values in eeprom for when the picaxe resets if this doesn't recur too often (so as not to wear out your eeprom).
 

PhilHornby

Senior Member
lbenson;308961" said:
RESET" is sometimes an option. Your interrupt routine can set up initialization values in eeprom for when the picaxe resets ...
Or set a flag in a RAM variable and do a "RUN 0" ? ... that way the rest of the (software) environment would be intact....
 

stan74

Senior Member
you could put goto main in your interrupt sub but that would cause a stack overflow because the interrupt being called repeatedly and there's no return so the stack isn't cleared.
 

Buzby

Senior Member
IIRC, stack overflow only happens in the simulator. On the real chip the 'oldest' return address just gets pushed off the end of the stack.
 

stan74

Senior Member
yeah?? call,call,call where do the return addresses go? sorry maybe thinking summat else. I'm doing something similar..ish
 

mushroom

New Member
The RETURN at end the interrupt routine is mandatory.

One way is to set a flag (e.g. Make a bit variable = 1)
Then frequently in your code check if that flag is set and if so go to the Start of the Main loop.
Don't forget to clear (=0) that flag variable.


The topic arises from time to time. Here is a past thread:
http://www.picaxeforum.co.uk/showthread.php?26834-Consequences-of-leaving-and-interrupt-with-GOTO

If you don't need to preserve any values in variables or output pin states then the RESET command is an option.
Thanks all. Now I have some ideas to try. That link you provided Westaust55 helped too, and I don't know why my search didn't find it. I'm sure it's an often asked question.
I don't know how to add to the thread without using 'reply with quote'. Am I not seeing a button? Thanks again.
 

Buzby

Senior Member
I don't know how to add to the thread without using 'reply with quote'. Am I not seeing a button? Thanks again.
There should be a big '+Reply to Thread' below the bottom left of this message.

yeah?? call,call,call where do the return addresses go?
The return stacks in BASIC are PICAXE constructs, not PIC hardware stacks. I suspect they are just circular buffers.

It would be interesting to test, but not just now.

Cheers,

Buzby
 

westaust55

Moderator
If you log in first before attempting to reply, There should be a "Reply" button to click on immediately to the left of the "Reply With Quote" button at the bottom right of the posts.
Then an "Edit Post" button to the left of the "Reply" button.
 
Last edited:

hippy

Technical Support
Staff member
The return stacks in BASIC are PICAXE constructs, not PIC hardware stacks. I suspect they are just circular buffers.
That is correct. However it is not good programming practice to use the return address stack that way.

In addition, using a GOSUB or GOTO out of an interrupt will not work. The firmware needs to execute the interrupt related RETURN before it will allow re-enabling interrupts. One can get back to 'main' that way but it will no longer respond to interrupts.
 

stan74

Senior Member
I thought that but it was late. In other posts,using gosub without return causes stack overflow but repeat pushing doesn't crash,just forgets.
 

Buzby

Senior Member
A quick experiment with more 'gosubs' than 'returns'.

Code:
[color=Navy]#picaxe [/color][color=Black]28x2[/color]
[color=Navy]#no_table
#no_data[/color]

[color=Black]MyMain:
      [/color][color=Blue]gosub [/color][color=Black]MySub
      [/color][color=Blue]sertxd([/color][color=Red]"Returned "[/color][color=Black],#[/color][color=Purple]b0[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
      end[/color]
[color=Black]MySub:
      [/color][color=Blue]inc [/color][color=Purple]b0
      [/color][color=Blue]sertxd([/color][color=Red]"Gosubed "[/color][color=Black],#[/color][color=Purple]b0[/color][color=Black],[/color][color=Blue]cr[/color][color=Black],[/color][color=Blue]lf)
      if [/color][color=Purple]b0 [/color][color=DarkCyan]= [/color][color=Navy]5 [/color][color=Blue]then [/color][color=Black]: [/color][color=Blue]return [/color][color=Black]: [/color][color=Blue]endif
      gosub [/color][color=Black]MySub[/color]
[color=Blue]return[/color]
If the comparison is 'b0 = 5' then this is the result :
Gosubed 1
Gosubed 2
Gosubed 3
Gosubed 4
Gosubed 5
Returned 5

If the line is changed to 'b0 = 15', then this is the result :
Gosubed 1
Gosubed 2
Gosubed 3
Gosubed 4
Gosubed 5
Gosubed 6
Gosubed 7
Gosubed 8
Gosubed 9
Gosubed 10
Gosubed 11
Gosubed 12
Gosubed 13
Gosubed 14
Gosubed 15


So there is some effect when more 'gosubs' than 'returns' happens, but I've no idea what it is !.

( Too late tonight to experiment further, but I would like to find out. )

Cheers,

Buzby
 

AllyCat

Senior Member
Hi,

Is that with the simulator (PE5 or PE6) or a real chip (and which one)? That behaviour looks quite plausible (it's too late for me as well), but there are still a few simulator bugs, particularly in PE5.

However, the title of the thread was "Interrupt and Return", which appears to have been overlooked in the last few posts. IMHO hippy gives a concise and definitive answer in post #11: "The firmware needs to execute the interrupt related RETURN before it will allow re-enabling interrupts."

Cheers, Alan.
 

hippy

Technical Support
Staff member
It is the behaviour after RETURN which needs to be monitored when stack depth is exceeded. The GOSUBs will all be entered but it will eventually not RETURN to where the call was initially from.
 

AllyCat

Senior Member
Hi,

It's also necessary to call the subroutine from different addresses, or the stack data won't be "corrupted" (changed), even if an overflow does occur. So a simple looping or recursive test program may not show any issues. As already said, a stack overflow shouldn't be possible with interrupts (alone) because nesting is not permitted/supported.

I don't know if the PE6 "stack" is common between call/interrupt addresses and PUSH/POP instructions, but AFAIK the base PIC architecture is quite resilient because ONLY return addresses are pushed onto the stack (which is not necessarily even 16 bits wide). There's much more scope for creating chaos with many other processors, like the Z80, where "data" can be pushed onto the (single) stack and then used as a "return" address. :rolleyes:

Cheers, Alan.
 

Technical

Technical Support
Staff member
So there is some effect when more 'gosubs' than 'returns' happens, but I've no idea what it is !.
It's no secret, the gosubs are nested inside each other too many times and so the return address stack has therefore overflowed and the return address (ie the next line after the gosub) for the last 'return' to know where to jump back to has therefore been lost forever. So when it comes to process that last 'return' the return address is corrupt, hence the return command can't be processed and so the PICAXE 'hangs' and stops processing code.

You can only have 1 interrupt, and it will not cause a stack overflow by itself. As has been said before, there is never any reason to have a mismatch of gosubs to returns (and hence a a stack overflow), if you code does this it should be simply refactored and reworked until it doesn't - there is always another way!
 

stan74

Senior Member
If you write code normally this thread is irrelevant. Since timer interrupts occur often then return problems would show immediately but a gosub might not and it wouldn't should show an error when compiling. The compiler doesn't point out daft code. Be nice if error messages were like "You could save 100 bytes and do it faster if you did it this way". One day maybe.
 

stan74

Senior Member
Everyone on the forum chips in if they can to. Not long before voice error messages in a sarcastic superior tone. "Wrong again you nunse! May I recommend lego blocks...but you couldn't even stack them" like Marvin the paranoid android
 

Goeytex

Senior Member
The bottom line is that if an interrupt is used the code will eventually need to return back to the point where the interrupt occured UNLESS a "reset" command is issued somewhere along the way and the entire program is started over.

A sub can be called from the interrupt routine, but again that sub must return to the interrupt sub which then must return to the point where the interrupt occurred.

I certainly understand wanting to detect an event quickly (Interrupt?) and not being forced to return to the point in code where the event occurred.

But using an interrupt is not always necessary and may not always be the best method. ERCO never uses them and yet makes great robots and other stuff. So there are other ways to detect events and have the program flow to wherever you want. It all depends upon the application, what the event is, what the program needs to do after the event, and how fast it needs to do it. We have not been given this information by Mushroom.

@Mushroom... If you have not yet found and implemented an adequate solution, please let us know what the application is, what is triggering the interrupt, what the program needs to do, and how fast it needs to do it. Posting your existing (commented) code may also be helpful to those willing and able to help you.

If your problem has been solved, please let folks know.

Goey
 

stan74

Senior Member
Interrupts are neglected by picaxe users partly because it's put in the "hard stuff catagory" but they're very useful. The servo command works without thinking about. It could be done with a timer 0 interrupt every 20 ms and a pulsout variable. Same with stepper motor or even software pwm. Obviously interrupt on a pin or readadc as well. But some people just wait for an event because the program has nothing else to do. The answer to say running 2 stepper motors is another picaxe often.
 
Top