| Electronics > Beginners |
| Sorry to interrupt ... |
| << < (5/7) > >> |
| langwadt:
--- Quote from: mikerj on June 01, 2018, 08:23:09 am --- --- Quote from: langwadt on May 31, 2018, 05:41:32 pm --- --- Quote from: mikerj on May 31, 2018, 05:19:46 pm --- --- Quote from: langwadt on May 31, 2018, 05:14:38 pm --- --- Quote from: mikerj 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. --- End quote --- 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 --- End quote --- Yes, that's what I said.... --- End quote --- 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 --- End quote --- The 14 bit PIC has a hardware stack purely for return addresses, it's not used to save or pass data between functions. --- End quote --- 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? |
| NivagSwerdna:
--- Quote from: PerranOak on May 31, 2018, 04:14:42 pm ---RETFIE --- End quote --- 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. --- End quote --- 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! |
| jpanhalt:
--- Quote from: Brumby 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. --- End quote --- 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. --- End quote --- 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. |
| jpanhalt:
--- Quote from: MarkF on June 01, 2018, 07:21:55 am --- --- Quote from: wraper on June 01, 2018, 06:50:43 am --- --- Quote from: jpanhalt 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. --- End quote --- 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. --- End quote --- 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. --- End quote --- 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. |
| NivagSwerdna:
... 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 |
| Navigation |
| Message Index |
| Next page |
| Previous page |