Author Topic: Sorry to interrupt ...  (Read 2900 times)

0 Members and 1 Guest are viewing this topic.

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 264
  • Country: gb
Sorry to interrupt ...
« on: May 31, 2018, 04:14:42 pm »
As I understand it, when an interrupt occurs (I’m using a PIC 16F1827) the programme counter (PC) is pushed to the stack and the programme jumps to 0004h to start the interrupt code.

Programmes that I have seen always seem to use a subroutine ending in “RETFIE” so that the programme runs this then gets back to what it was doing.

In my project the programme will be in a loop displaying the current result when an interrupt occurs. I then want that interrupt to jump to executing code part the way down the main loop and carry one, not acting as a subroutine at all - more of a "GOTO".

Is this “allowed”? Will it cause unpredictability? What is it that triggers the return of the PC from the stack, is it “RETFIE”?

Also, I note in the datasheet that the “GIE: Global Interrupt Enable bit” of INTCON0 is cleared on interrupt. Is this normal/usual?

Thank you.
Some light can never be seen!
RJD
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 2319
  • Country: gb
Re: Sorry to interrupt ...
« Reply #1 on: May 31, 2018, 05:04:25 pm »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

GIE is disabled when servicing an interrupt to prevent further interrupts occurring (re-entering the ISR) and again quickly filling up the stack.  It's possible to re-enable interrupts whilst in the interrupt handler, but you really need to understand the implications of this.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #2 on: May 31, 2018, 05:14:38 pm »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

if the mainloop just pushed something on the stack before the interrupt, then returning from the interrupt to a different place in
main those will never be popped off the stack and it'll just keep growing

 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 2319
  • Country: gb
Re: Sorry to interrupt ...
« Reply #3 on: May 31, 2018, 05:19:46 pm »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

if the mainloop just pushed something on the stack before the interrupt, then returning from the interrupt to a different place in
main those will never be popped off the stack and it'll just keep growing

Yes, that's what I said....
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #4 on: May 31, 2018, 05:41:32 pm »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

if the mainloop just pushed something on the stack before the interrupt, then returning from the interrupt to a different place in
main those will never be popped off the stack and it'll just keep growing

Yes, that's what I said....

you said pop the saved address, but the main loop could have pushed other things on the stack at the moment the interrupt happens if you return to a different place the code that pops those off again will never happen

 

Online PA0PBZ

  • Super Contributor
  • ***
  • Posts: 4260
  • Country: nl
Re: Sorry to interrupt ...
« Reply #5 on: May 31, 2018, 05:48:39 pm »
In my project the programme will be in a loop displaying the current result when an interrupt occurs. I then want that interrupt to jump to executing code part the way down the main loop and carry one, not acting as a subroutine at all - more of a "GOTO".

Generally speaking, if you think you need to do this you are doing something wrong, so think it over again and try to find  another solutions where you use the interrupt the way it was ment to be. For instance, you could set a flag in the interrupt routine and let the main loop check for this flag and then execute the code you want... there are many ways to solve your problem in a normal way. Maybe post what you are trying to do?

Keyboard error: Press F1 to continue.
 

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 264
  • Country: gb
Re: Sorry to interrupt ...
« Reply #6 on: May 31, 2018, 07:00:15 pm »
mikerj:
I see so I don't need to set GIE if I use RETFIE, understood.
What happens when the stack overflows? Only I have a very odd result happening: my project displays temperature and every fifth reading (each new reading is triggered by the interrupt) is bogus while the intervening four are fine. Could this be a stack problem? I realise it could be just bad programming!

langwadt:
As you see from the above I may be experiencing problems.

PA0PBZ:
Yes, you're right, I was doing it this way out of laziness. I just wondered if it was possible/allowable.
Some light can never be seen!
RJD
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #7 on: May 31, 2018, 07:29:40 pm »
mikerj:
I see so I don't need to set GIE if I use RETFIE, understood.
What happens when the stack overflows?

pushing on the stack writes at memory locations not reserved for the stack i.e. possibly other variables etc. so anything can happen


 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 8246
Re: Sorry to interrupt ...
« Reply #8 on: May 31, 2018, 07:58:30 pm »
Generally speaking, exiting an interrupt service routine (ISR) by anything other than a normal return from interrupt instruction to resume execution of the main program from the point it was interrupted at, is an *EXTREMELY* bad idea.  If you write an ISR that modifies its return address without a dammed good reason, expect to have to justify yourself in a hostile performance review!

However in a few special circumstances, it can be useful.  e.g if you are bit-banging a protocol or signal in a loop that's so tight you don't have enough instruction cycles slack to test a flag to exit the loop, or in a preemptive RTOS kernal, which swaps stacks to swap threads, then returns to  the point in the new thread at which it was previously interrupted and suspended.

As the enhanced midrange PICs have dedicated stack memory, they are ill suited to premptive RTOSes as the stack would have to be copied off to RAM one return address at a time and reloaded with its previously saved contents from the new thread. On a processor with a stack in general purpose RAM, the equivalent operation is to save the current stack pointer to the thread table, and load it with the one from the next thread which effectively swaps the stack leaving the previous thread's stack inactive till its needed again and making the new thread's stack current.  Of course there are some other critical details required to successfully resume the next thread. e.g preserving critical flags and registers on a per thread basis

The remaining use - to break out of a loop that's so tight you cant afford a single extra instruction to check an exit flag can be handled semi-cleanly.

Immediately after the loop, duplicate it except the final BRA or GOTO instruction that returns to the start of the loop must be replaced by a NOP.   In the ISR, check if the TOSH:TOSL register pair is in the address range of the first copy of the loop.  If so, add the number of instructions in the loop to TOSH:TOSL, so the RETFIE returns to the equivalent next instruction in the second copy of the loop, so the loop processing is completed cleanly and the loop finally exits as the second copy doesn't have a BRA or GOTO back to the start.

@langwadt: All 8 bit PICs have dedicated storage for the stack, It is physically impossible for it to overflow into general purpose RAM.
« Last Edit: June 01, 2018, 02:52:55 am by Ian.M »
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #9 on: May 31, 2018, 08:49:33 pm »
@langwadt: All 8 bit PICs have dedicated storage for the stack, It is physically impossible for it to overflow into general purpose RAM.

never had the misfortune to use a pic ;) 

so the stack pointer will probably wrap and still cause all kinds of havoc
 

Offline jpanhalt

  • Frequent Contributor
  • **
  • Posts: 706
  • Country: us
Re: Sorry to interrupt ...
« Reply #10 on: May 31, 2018, 09:20:57 pm »
I am late to the party, sorry.  But since you are using an ehannced mid-range PIC, you can "pop" the last address just by decrementing STKPTR (Bank 31).

Here's an alternative I call MIB (Men in Black, if you remember the movie).  It erases all memory of the interrupt and lets you start
afresh.
Code: (asm) [Select]
MIB                           ;erases interrupt return functionality
     movlb     31
     clrf      STKPTR
     movlb     2
     bcf       LATC,2         ;ensures LED is off when entering Command Mode 
     call      ClrScrn        ;call from any bank, returns |B0                  |B0
     btfss     INTCON,IOCIF
     bra       Event          ;not switch, must be Event
     movlb     7              ;                                                 |B7                                   
     btfsc     IOCBF,SW1      ;test for SW1                                     |B7
     bra       DoSW1          ;                                                 |B7
     bra       DoSW2          ;                                                 |B7

Only the first 3 instructions are relevant.  The rest are to identify the source of the interrupt.  Of course, if you want to retain where  you were umpteen steps before the interrupt, change the clrf to decrf...

John
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1558
  • Country: us
Re: Sorry to interrupt ...
« Reply #11 on: June 01, 2018, 01:44:29 am »
PA0PBZ:
Yes, you're right, I was doing it this way out of laziness. I just wondered if it was possible/allowable.

I agree with PAOPBZ on this one.

Yes, it's doable.  But, HIGHLY DISCOURAGED!  You are just asking for stack corruption and other mysterious problems.  I remember an occasion in my early years where one word was left on the stack by mistake.  It took 3 engineers over a week to find and correct.  When you start having these questions about a design, STOP and look at the big picture.  There will be a better way.

Just use the interrupt routine to read a new value and store it in a global variable.  Then, allow the main loop to display the value during its periodic update.  If you are NOT updating the entire display at a periodic rate, then set a flag in the interrupt routine to trigger an update in the main loop.
« Last Edit: June 01, 2018, 01:47:20 am by MarkF »
 

Online Brumby

  • Supporter
  • ****
  • Posts: 9776
  • Country: au
Re: Sorry to interrupt ...
« Reply #12 on: June 01, 2018, 03:03:06 am »
I cringed at the idea of playing with interrupt returns.  Like any common computer architecture, the fundamental execution is a linear one and every logical branch is - quite literally - a "go to".  So, yes, you can do it - but it's like lighting up a cigarette in a fireworks factory IMO.

Free use of the "go to", however, is not conducive to well structured, robust programs which is why the modular style with calls has been a fundamental mainstay in the programming sphere for a very long time.  Even in my first job writing application software in IBM assembler, this structural approach was the norm.
 Programming with interrupts is, perhaps, the quintessential example of this structured process.  Everything is built around the idea.

Most specific of the concerns I have is the state of execution when the interrupt occurs.  Whatever you were doing at the time stops while the interrupt is serviced and if you were part way through doing something, not allowing the return to that processing could leave you in an unknown condition.  Where this becomes a true minefield is if you have another interrupt fire off while you are still faffing around with the first.


Personally, I would avoid such programming like the plague - but if you really, really, really feel you need to, then think long and hard, tread very carefully and test the crap out of it.

Once you're happy with the testing, do it again ... and maybe get someone who doesn't like you to test it.  If you don't, the universe will find an edge case that will shoot you down in flames.
« Last Edit: June 01, 2018, 03:06:47 am by Brumby »
 

Offline jpanhalt

  • Frequent Contributor
  • **
  • Posts: 706
  • Country: us
Re: Sorry to interrupt ...
« Reply #13 on: June 01, 2018, 03:51:07 am »
1) If you are just going to set a flag in the interrupt and then poll that flag as recommended by some, why have an interrupt to begin with?   Just poll the xyzIF.

2) I have other routines,  e.g., string print routines (macros), that use the stack to calculate a return with no interrupt.   Among other things, the da directive is used to pack two, 7-bit ascii into a single program memory location (Microchip reference manual), "• da "abcdef" will put 30E2 31E4 32E6 into program memory."   For routines that have a lot of "dialog" that can save hundreds of lines of code.  Try to do that concisely without using the stack.
For example:
Code: (asm) [Select]
StrPrint  macro     label   
          call      PutText                 
          da        label,0         
          endm

3)  Fears that that the world will end if you use the stack as a tool are greatly exaggerated.  They all sound a little like the warnings against flying ("if god had wanted man to fly he would have given him wings...").  Sure there are sincere believers in that, but the person writing the code is ultimately responsible for every line, not just the stack.  To put that another way, if Microchip hadn't wanted users to touch the stack, why did it give them the tools to do it?  Obviously, there is demand for the ability to push and pop the stack by programmers, and Microchip simply complied to compete.
 
The following users thanked this post: NivagSwerdna

Online Brumby

  • Supporter
  • ****
  • Posts: 9776
  • Country: au
Re: Sorry to interrupt ...
« Reply #14 on: June 01, 2018, 06:41:10 am »
1) If you are just going to set a flag in the interrupt and then poll that flag as recommended by some, why have an interrupt to begin with?   Just poll the xyzIF.
Really?  I can come up with a couple of reasons without even trying.
 

Online wraper

  • Supporter
  • ****
  • Posts: 11030
  • Country: lv
Re: Sorry to interrupt ...
« Reply #15 on: June 01, 2018, 06:50:43 am »
1) If you are just going to set a flag in the interrupt and then poll that flag as recommended by some, why have an interrupt to begin with?   Just poll the xyzIF.
So how often do you need to poll to not loose the event?  :palm: If the event is so slow that you don't need to use interrupt, then sure. You shouldn't use interrupts right and left when there is no need for that.
 

Online Brumby

  • Supporter
  • ****
  • Posts: 9776
  • Country: au
Re: Sorry to interrupt ...
« Reply #16 on: June 01, 2018, 06:52:08 am »
That was one ^ ^ ^ ^

Another is if you needed to know the exact time the event occurred.  Then there's handling multiple events that might occur during a single poll cycle.
« Last Edit: June 01, 2018, 06:54:57 am by Brumby »
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 1558
  • Country: us
Re: Sorry to interrupt ...
« Reply #17 on: June 01, 2018, 07:21:55 am »
1) If you are just going to set a flag in the interrupt and then poll that flag as recommended by some, why have an interrupt to begin with?   Just poll the xyzIF.
So how often do you need to poll to not loose the event?  :palm: If the event is so slow that you don't need to use interrupt, then sure. You shouldn't use interrupts right and left when there is no need for that.

One example that I recently did was processing a rotary encoder.  The interrupt routine read the encoder at a high fixed rate and saved the total number of clicks until the Display Loop was able to process them.  The Display Loop run at a much slower rate and didn't need to see each event.  Just the total number of clicks.  The total number clicks was used in sequencing through menu items, incrementing/decrementing values, etc.  In this case, a 1000Hz system timer created interrupt events to perform varies tasks (read the encoder and update some hardware at a fixed rate).  The Main Loop processed the encoder inputs and updated a display in the background.

Whether you poll for an event or use interrupts depends on the task(s) and rates required by your design.

One thing to remember here is that you want the interrupt service routine to be fast (i.e. get in and get out as quickly as possible) so it is ready for the next event.  Especially if you are looking for multiple events.  Do the heavy processing in your main loop where things are NOT time critical.


 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 2319
  • Country: gb
Re: Sorry to interrupt ...
« Reply #18 on: June 01, 2018, 08:23:09 am »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

if the mainloop just pushed something on the stack before the interrupt, then returning from the interrupt to a different place in
main those will never be popped off the stack and it'll just keep growing

Yes, that's what I said....

you said pop the saved address, but the main loop could have pushed other things on the stack at the moment the interrupt happens if you return to a different place the code that pops those off again will never happen

The 14 bit PIC has a hardware stack purely for return addresses, it's not used to save or pass data between functions.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 2319
  • Country: gb
Re: Sorry to interrupt ...
« Reply #19 on: June 01, 2018, 08:25:03 am »
That was one ^ ^ ^ ^

Another is if you needed to know the exact time the event occurred.  Then there's handling multiple events that might occur during a single poll cycle.

If the ISR is ONLY setting a flag, then you might as well poll the interrupt flag.  It's only when the ISR is doing other stuff that polling may not be useful.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #20 on: June 01, 2018, 08:34:04 am »
The RETFIE instruction re-enables interrupts and pops the last address off the stack and loads it to the program counter.  It's quite possible to use a normal "RETURN" at the end of an interrupt, the only difference is that interrupts will not be automatically re-enabled.

If you jump to a specific location at the end of your inetrrupt rather than executing a RETFIE/RETURN then you will need to manually "pop" the saved address from the hardware stack by decrementing the STKPTR register.  If you don't do this then the stack will quickly overflow.  Note this is only possible on later versions of the 14 bit PIC core (such as the 16F1827) that allows access to the stack pointer, early devices had no way of doing this.

if the mainloop just pushed something on the stack before the interrupt, then returning from the interrupt to a different place in
main those will never be popped off the stack and it'll just keep growing

Yes, that's what I said....

you said pop the saved address, but the main loop could have pushed other things on the stack at the moment the interrupt happens if you return to a different place the code that pops those off again will never happen

The 14 bit PIC has a hardware stack purely for return addresses, it's not used to save or pass data between functions.

so the main loop could call functions so there are addresses on the stack that will never get popped if you just straight to a different place in main?

 

Online NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 1908
  • Country: gb
Re: Sorry to interrupt ...
« Reply #21 on: June 01, 2018, 08:47:08 am »
RETFIE
Read the manual

Quote
The RETFIE instruction exits the ISR by popping the
previous address from the stack, restoring the saved
context from the shadow registers and setting the GIE
bit.

For additional information on a specific interrupt’s
operation, refer to its peripheral chapter.
8.2 Interrupt Latency
Interrupt latency is defined as the time from when the
interrupt event occurs to the time code execution at the
interrupt vector begins. The latency for synchronous
interrupts is 3 or 4 instruction cycles. For asynchronous
interrupts, the latency is 3 to 5 instruction cycles,
depending on when the interrupt occurs. See Figure 8-2
and Figure 8.3 for more details.
Note 1: Individual interrupt flag bits are set,
regardless of the state of any other
enable bits.
2: All interrupts will be ignored while the GIE
bit is cleared. Any interrupt occurring
while the GIE bit is clear will be serviced
when the GIE bit is set again.

So why is there a RETFIE instruction?  Because it atomically does two things... it pops the PC and sets the GIE bit.  You are going to find that operation crucial for reliable operation.  But that doesn't preclude sharing code paths between interrupt code and other code just that you need to keep track when you return and use the correct mechanism to get back.

Experience tends to result in keeping interrupt routines as small and simple as possible as they are hard to debug and you need to keep them short otherwise you will be late servicing the next one (the event will just set the flag and you will pick it up when you REFIE and potentially lead to starvation of the main thread of control).

Anything is possible... but there is a reason for the existance of the RETFIE instruction.

Have fun!
 

Offline jpanhalt

  • Frequent Contributor
  • **
  • Posts: 706
  • Country: us
Re: Sorry to interrupt ...
« Reply #22 on: June 01, 2018, 09:15:51 am »
That was one ^ ^ ^ ^

Another is if you needed to know the exact time the event occurred.  Then there's handling multiple events that might occur during a single poll cycle.

Here's what PAOPBZ said and others agreed:
Quote
For instance, you could set a flag in the interrupt routine and let the main loop check for this flag and then execute the code you want... there are many ways to solve your problem in a normal way.

Let me summarize your comments: If you don't know what "your" program does, you shouldn't be writing it.

I agree.   But, nothing you have said relates factually with using access to the stack responsibly.
 

Offline jpanhalt

  • Frequent Contributor
  • **
  • Posts: 706
  • Country: us
Re: Sorry to interrupt ...
« Reply #23 on: June 01, 2018, 09:21:16 am »
1) If you are just going to set a flag in the interrupt and then poll that flag as recommended by some, why have an interrupt to begin with?   Just poll the xyzIF.
So how often do you need to poll to not loose the event?  :palm: If the event is so slow that you don't need to use interrupt, then sure. You shouldn't use interrupts right and left when there is no need for that.

One example that I recently did was processing a rotary encoder.  The interrupt routine read the encoder at a high fixed rate and saved the total number of clicks until the Display Loop was able to process them.  The Display Loop run at a much slower rate and didn't need to see each event.  Just the total number of clicks.  The total number clicks was used in sequencing through menu items, incrementing/decrementing values, etc.  In this case, a 1000Hz system timer created interrupt events to perform varies tasks (read the encoder and update some hardware at a fixed rate).  The Main Loop processed the encoder inputs and updated a display in the background.

Whether you poll for an event or use interrupts depends on the task(s) and rates required by your design.

One thing to remember here is that you want the interrupt service routine to be fast (i.e. get in and get out as quickly as possible) so it is ready for the next event.  Especially if you are looking for multiple events.  Do the heavy processing in your main loop where things are NOT time critical.

Only since you quote my statement will I respond.   I have no issue with doing what you did with the encoder, nor did I mean you should always poll in IF and not use an interrupt.   I was responding specifically to PAOPBZ's comment.
 

Online NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 1908
  • Country: gb
Re: Sorry to interrupt ...
« Reply #24 on: June 01, 2018, 09:23:53 am »
... on reflection... I recently disassembled a very old bit of 8039 code...

The technique used there was the IRQ would service an outside request, calculate and then and just push an address (after removing the original stack entry) of one of a number of routines to run after the ISR completed.  The 8039 would run that routine and then finally enter a hard loop, waiting to be interrupted and scheduled again.  The technique was pre-emptive... i.e. a new IRQ would schedule the new work with the old work (if it hadn't already reached the hard idle loop) being superseded.

Not an unusual technique
 
The following users thanked this post: jpanhalt

Offline jpanhalt

  • Frequent Contributor
  • **
  • Posts: 706
  • Country: us
Re: Sorry to interrupt ...
« Reply #25 on: June 01, 2018, 10:02:04 am »
... on reflection... I recently disassembled a very old bit of 8039 code...

The technique used there was the IRQ would service an outside request, calculate and then and just push an address (after removing the original stack entry) of one of a number of routines to run after the ISR completed.  The 8039 would run that routine and then finally enter a hard loop, waiting to be interrupted and scheduled again.  The technique was pre-emptive... i.e. a new IRQ would schedule the new work with the old work (if it hadn't already reached the hard idle loop) being superseded.

Not an unusual technique

Exactly, and now the 8-bit, enhanced mid-range  PIC's can do that too.  It has been available with 18F's and others for a long time.
 

Online wraper

  • Supporter
  • ****
  • Posts: 11030
  • Country: lv
Re: Sorry to interrupt ...
« Reply #26 on: June 01, 2018, 10:13:14 am »
In my project the programme will be in a loop displaying the current result when an interrupt occurs. I then want that interrupt to jump to executing code part the way down the main loop and carry one, not acting as a subroutine at all - more of a "GOTO".
You need to be wary that interrupt can occur in any random point of main loop. And you need to be wary of data corruption which may happen when you make goto from a random point of a program. I would consider it relatively safe only if you completely discard all of the data you had before such interrupt.

Not to say that you will have data transfer corruption if MCU was talking with some peripheral devices. You may just hang the bus and will need to reset it.
« Last Edit: June 01, 2018, 10:34:15 am by wraper »
 

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 264
  • Country: gb
Re: Sorry to interrupt ...
« Reply #27 on: June 01, 2018, 12:40:03 pm »
Wow! Apologies for causing such trouble!

I have only programmed in high level languages on PCs before so the stack was a mystery to me. While I was learning PIC stuff the significance of the RETFIE command was not made clear ... I know, ignorance of the law is no excuse.

I now understand that I must not be lazy and must code properly even (especially?) on practice projects!  :-[
Some light can never be seen!
RJD
 

Online NivagSwerdna

  • Super Contributor
  • ***
  • Posts: 1908
  • Country: gb
Re: Sorry to interrupt ...
« Reply #28 on: June 01, 2018, 12:51:41 pm »
You didn't cause .any trouble  :)

Be creative don't necessarily follow any of these recommendations!

Have fun
 

Online Brumby

  • Supporter
  • ****
  • Posts: 9776
  • Country: au
Re: Sorry to interrupt ...
« Reply #29 on: June 01, 2018, 12:58:07 pm »
Wow! Apologies for causing such trouble!
Don't apologise ... you didn't cause any trouble.  You simply asked a reasonable question.

Quote
I have only programmed in high level languages on PCs before so the stack was a mystery to me.
This is one of the reasons why caution has been strongly represented.  You can certainly do whatever you like, but some of the trouble you can get yourself into playing with the stack can be pretty hairy.  Understanding and discipline are useful companions.
 

Offline PerranOak

  • Frequent Contributor
  • **
  • Posts: 264
  • Country: gb
Re: Sorry to interrupt ...
« Reply #30 on: June 01, 2018, 02:15:27 pm »
Cheers both.

What a noble but gassy bunch we are!
Some light can never be seen!
RJD
 

Offline dnwheeler

  • Regular Contributor
  • *
  • Posts: 73
  • Country: us
Re: Sorry to interrupt ...
« Reply #31 on: June 01, 2018, 06:45:19 pm »
Probably the biggest issue to consider is that you don't really know what code was being interrupted. For example, the code may have been in the middle of interacting with some external device, or reconfiguring several hardware registers, or clocking out a series of data values, etc. If an interrupt occurs and you don't return from it, some hardware could be left in an "in-between" state. Lights could be left on, devices could get stuck on/off, allocated memory may not be freed, etc.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 2319
  • Country: gb
Re: Sorry to interrupt ...
« Reply #32 on: June 04, 2018, 09:00:36 am »

The 14 bit PIC has a hardware stack purely for return addresses, it's not used to save or pass data between functions.

so the main loop could call functions so there are addresses on the stack that will never get popped if you just straight to a different place in main?

Exactly.  This is why you would need to manually pop the last address off the stack if you were going to jump out of the ISR, rather than returning.
 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: dk
Re: Sorry to interrupt ...
« Reply #33 on: June 04, 2018, 02:05:04 pm »

The 14 bit PIC has a hardware stack purely for return addresses, it's not used to save or pass data between functions.

so the main loop could call functions so there are addresses on the stack that will never get popped if you just straight to a different place in main?

Exactly.  This is why you would need to manually pop the last address off the stack if you were going to jump out of the ISR, rather than returning.

that would get rid of the address pushed by entering the interrupt, what if the main loop just pushed an address on the stack to call another function? 
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf