News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Gosub in interrupt

Started by joesaliba, Dec 09, 2025, 09:24 AM

Previous topic - Next topic

joesaliba

I know that this topic has been discussed but I cannot find the thread.

So my simple question: -

Can I use a Gosub within an interrupt routine, or a simple procedure replacing a gosub?

All Gosub and return will remain in the ISR.

Thank you


top204

A Gosub cannot be used within an interrupt, because the compiler cannot track and store/restore the variables used in the subroutine.

In Positron8, you can use a procedure call, and it will track/restore the variables and SFRs used within it.

I am working on the same mechanism for Positron16.

Regards
Les

And may thanks for your donation Joe. It is very much appreciated.

joesaliba

You're welcome Les.

Ok. So to be sure, I can call a procedure outside the ISR.

Thank you

John Lawton

But do you really need to call a Proc?

In my opinion coding an interrupt is best done simply using the fastest code to reduce the execution time. Calling anything external to the interrupt might compromise that.

John

Wimax

I completely agree! And...when the interruption rate starts to become significant, you start counting the execution times of each individual instruction. 

joesaliba

Quote from: John Lawton on Dec 09, 2025, 06:32 PMBut do you really need to call a Proc?

In my opinion coding an interrupt is best done simply using the fastest code to reduce the execution time. Calling anything external to the interrupt might compromise that.

John

Agree. All I wanted to know if it can be done. I might be tight in space for code in future, and if I know that I can save 0.2% calling a procedure that is being used outside and inside an ISR I will go for it.

Timing is not critical for what the PIC is doing.

RGV250

QuoteTiming is not critical for what the PIC is doing.
In this case what I do is set a bit and then in the main loop if the bit is set, call the procedure and reset the bit at the end of it.

Bob

joesaliba

Quote from: RGV250 on Dec 10, 2025, 07:24 PM
QuoteTiming is not critical for what the PIC is doing.
In this case what I do is set a bit and then in the main loop if the bit is set, call the procedure and reset the bit at the end of it.

Bob

That is what I usually do, but I cannot do this in this particular project. I am happy to loose some time in ISR rather than loosing seconds in main code. The reason is that I cannot check that bit immediately after exiting the ISR.

Stephen Moss

Quote from: joesaliba on Dec 10, 2025, 07:08 PMAgree. All I wanted to know if it can be done. I might be tight in space for code in future, and if I know that I can save 0.2% calling a procedure that is being used outside and inside an ISR I will go for it.
I presume from the above that what your are trying to do is avoid having to copy code from your main loop into your ISR to save space?

I was just thinking what if you went about it the other way round, and put the subroutine in your ISR and call it from you main code, but it then occurred to me that whichever way you did it there is potentially a big problem here.
Maybe Les had already considered this in giving his previous answer and all will be fine, but that is not clear so for the sake of discussion/getting clarity...

Currently the discussion seems to be considering the call from the ISR to a Sub/Proc as being the same as a call from the Main code but the two situations are different because if your code only calls the sub/proc from either Main or your ISR there no problem as you exit the sub/proc and return to instruction after it was called.
However, let us assume that you have written your main code and the respective sub/proc as you normally would, and now you are writing your ISR which includes your call to the relevant sub/proc, so now your code allows the sub/proc to be called from both Main and the ISR. However, as you don't know when the relevant interrupt will occur you can have the following sequence of events...

  • The sub/proc is called by you Main code.
  • While executing the sub/proc in question an interrupt occurs and you jump out of the sub/proc to your ISR.
  • Your ISR then calls the same sub/proc, which then jumps you out of your ISR to the start of same sub/proc you have just jumped out of while part way through executing.

Is that not effectively a recursive call, just as it would be if you had called the sub/proc from within itself, i.e.,
MySub:
[some code here]
   If Interrupt = true then
      Gosub MySub
      Clear interrupt   
   EndIf
[some more code here]
EndSub
and if so can the compiler handle it or will the result be an incorrectly functioning mess?

Now that I have previewed my post the pseudo code above looks more like it will work, but I still can't shake the feeling that the pseudo codes simplicity is hiding a can of worms, that depending on the function of the sub/prog in question you will return incorrect results, what say ye?

joesaliba

And I think that Les that is why he said NO to Gosub, but yes to Proc.

Because the mechanism that he wrote for the 8-bit avoids what you said, at least that what I am thinking.

My code do call the Proc ONLY from the ISR, and not from the main routine.

trastikata

#10
If you need a complex code in your ISR, you can still use GoTo in a ISR. Thus include all code that you need there and jump into it with If-Then statement, and when you reach that code just jump over it - this won't slow down your ISR because it is only one additional jump.

So wrap your complex code with jump over directive and just jump to the end of the ISR, if needed call certain parts of the complex code and jump back to your ISR common code.

Everything should be within the ISR, but with carefully designed jumps back and forward and over complex code, your resultant ISR although very long will have very fast execution times if needed just by jumping to the end of the ISR:

Device = 18F2550
Declare Xtal = 8 
 
On_Interrupt GoTo Isr
GoTo Main        

Isr:
    Context Save
        'Simple code here
        'Do something
        If 1 = 1 Then GoTo ComplexCode1
ReturnFromComplexCode1:                  
        'Do something
        If 2 = 2 Then GoTo ComplexCode2 
ReturnFromComplexCode2:                
                  
        GoTo OverComplexCode
        'Some Complex Code start
ComplexCode1:
        'Do something
        GoTo ReturnFromComplexCode1
ComplexCode2: 
        'Do something
        GoTo ReturnFromComplexCode2
        'Some Complex Code end
OverComplexCode:       
    Context Restore
   
Main:
    'Main code here
    End