Vectored Interrupts PIC18F - Page 1
Forum section: electronics / general

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 07:43:55 am
content: Hi!I have a quick question I can not really test / not easy to test right now.I am using this video from microchip to see how to write my interrupt routines.Can I define both low and high interrupt routines?For example I define both:void __interrupt(irq(source_x), high_priority) mySource_xInt ( void )andvoid __interrupt(irq(source_x), low_priority) mySource_xInt ( void )Can I then select in run time which routine is being used based onthe priority select bit of the interrupt source?Is it legal to define them both? Only depending on priority of the interrupt?If I don´t define priority correctly is the interrupt source considered undetermined?Thanks for your reply in advance,Best Regards!

author: JPortici
author_rank: Super Contributor
timestamp: July 31, 2020, 08:34:13 am
content: Screw videos, Read the datasheet for your device. The interrupt section is fairly complete and have the answer for all your questions, hardware side. software side, the compiler manual is your friendBasically, in legacy mode (or for PIC18 older than the K42 series) you have two interrupt vectors, high and low.Each peripheral has its priority bit (except for INT0, it's always high priority) so if you ENABLE interrupt priorities and the peripheral interrupt, if it's in high priority it will call the high priority vector, otherwise it will call the low priority vector. you can change this at runtime. You can also disable low priority interrupts selectively (i.e.: both GIEH and GIEL have to be enabled for low priority interrupts)if you don't enable interrupt priorities all interrupts will go to the high priority vector (but remember to enable the PEIE bit or peripheral interrupts won't happen)if you use one of the newer PIC18 (K42 onward) you can also use the TRUE Vectored Interrupt Controller. Every interrupt source has its own routine, with nested interrupts and individual priority. High and low don't have any significance.IIRC the "irq_source" attribute in legacy mode is syntactic sugar so you create a "pseudo" dedicated irs (the main ISR call your function with all the associated overhead). I don't see why you shouldn't be able to have both at the same time.. in legacy mode of course

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 09:17:03 am
content: Hey thanks for the quick reply!Sorry I was not being specific enough. I work with some of the newer devices with true vectored interrupts (PIC18F26K83).I generally have an good grasp of how interrupts work with these newer PICs. Have been working with them for quite some time.Quote from: JPortici on July 31, 2020, 08:34:13 amCool still does not answer the initial question.What I do understand from the vectored interrupt and generally the whole interrupt saga of PICs is:You can set priority. High Priority - Low Priority Interrupts.Because it´s a true vectored interrupt. I can set per peripheral base interrupts.If multiple interrupts of the same priority appear then I do NOT need to do a software SELECT - CASE to find the sourse,rather the interrupts will be handled by their natural order. But IF and only if I want to do a software interrupt handling then this is also possible.According to the datasheet of PIC18F26K83 page 109 Quote:When more than one interrupt with the same userspecified priority level are requested, the priorityconflict is resolved by using a method called “NaturalOrder Priority”. Natural order priority is a fixed priorityscheme that is based on the Interrupt Vector Table.Table 9-2 shows the natural order priority and theinterrupt vector number assigned for each source.Still... when you write the routine you got to define a priority!void __interrupt(irq(source_x),high_priority) mySource_xInt ( void )andvoid __interrupt(irq(source_x),low_priority) mySource_xInt ( void )So I ask... Is the defining the priority bit in the corresponding IPRx register going to have an effect in which routine is executed?Let´s say I come to a point of my program that I need to prioritize on interrupt above all others.I normally use a low priority for that interrupt but as soon as I run a special routine I change the interrupt priority to high.Do I need to define both ISRs or not? A high and a low priority ISR.

author: JPortici
author_rank: Super Contributor
timestamp: July 31, 2020, 09:55:08 am
content: in IVT mode high_priority and low_priority don't have any sense, because they tell the compiler to place the (beginning of) the function at the high or low priority interrupt vector (0x08 and 0x18)The difference between legacy and IVT is that in legacy mode EVERY high priority interrupt will cause the controller to jump to 0x08, every low priority to 0x18. in IVT mode if for example a low priority interrupt is happening and a high priority happens the high priority preempts the low priority, but instead of going to 0x08 and decide what to do next, it jumps straight to the dedicated ISR(i was under the wrong impression that same-priority interrupts could preempt each other but i was wrong. if two interrupts of the same priority happen at the same time, the natural priority table decides which is served first... so you still have two levels, it's just that it is faster to handle multiple interrupts and you can effectively change the priority without having to write two ISRs)

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 10:51:49 am
content: Quote from: JPortici on July 31, 2020, 09:55:08 amI see, I see, I think I get it. It seems that the "non-IVT" approach is for legacy support or software handling of the interrupt priorities.Quote from: JPortici on July 31, 2020, 09:55:08 amSo there is no dedicated low and high priority address in the dedicated ISR. so you might as well leave that argument empty?!Sure I can live with that. In the video I posted before, they say that you should define the priority but even then, code is not executed determining the priority.So from what I get so far is that this is just a "we need to keep this argument here" rather than anything else.I should check though. Thanks for your input mate!

author: JPortici
author_rank: Super Contributor
timestamp: July 31, 2020, 06:20:14 pm
content: i've never used the high/low priority argument in my project with vectored interrupt

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 06:35:22 pm
content: Could you be as kind as to provide an example, better specific, just the full declaration.For the xc8 how would you right it?

author: NorthGuy
author_rank: Super Contributor
timestamp: July 31, 2020, 09:17:47 pm
content: Priority and vector are not related when you use vectored interrupts. High priority interrupts can preemt low priority interrupts. Low priority interrupts cannot preemt high priority interrupts. They also use different shadow locations to store registers upon ISR entry.

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 10:47:15 pm
content: Quote from: NorthGuy on July 31, 2020, 09:17:47 pmWith vectored interrupts, Priority DOES INDEED play a role. You just don´t input the priority as an argument at the declaration at all. It matters as hardware, but it doesn´t matter with the declaration.And that´s where the confusion started. And here it ends also.TB3162 Application Note from Microchip, explains everything in detail.Page 7 has the answer I was looking for.When writing the ISR you don´t need to put the priority in the declaration. Priority plays a role even with the vectored interrupts.It is just that instead of 2 vectors (high / low priority) you got many. If multiple interrupts occur, then what is executed is based on the priority, even with the multi-vector controller on.Now which of these interrupts are used, that have the same priority, if multiple have occurred then which one is executed is based on its position on the table.This is more the AVR way of interrupts but hell that´s cool.The application note is pretty useful for understanding the whole concept. But the documentation generally could use some more visualization for somethingnot totally dry cut and also wrong information ( video ) out there.Thanks for the help!Cheers!

author: NorthGuy
author_rank: Super Contributor
timestamp: July 31, 2020, 11:05:57 pm
content: Quote from: TrickyNekro on July 31, 2020, 10:47:15 pmIt is always better to read the datasheet than to read application notes. It gives much better picture:"User-assigned interrupt priority is enabled by setting IPEN. Each peripheral interrupt source can be assigned a high-or low-priority level by the user. The user-assignable interrupt priority control bits for each interrupt are located in theIPRx registers, which are device-specific and can be found in the respective data sheet for each device.The interrupts are serviced based on a predefined interrupt priority scheme detailed below.1. Interrupts set by the user as a high-priority interrupt have higher precedence of execution. High-priorityinterrupts will override a low-priority request when:1.1. A low-priority interrupt has been requested or its request is already pending.1.2. A low and high-priority interrupt are triggered concurrently (i.e., on the same instruction cycle).1.3. A low-priority interrupt was requested and the corresponding Interrupt Service Routine is currentlyexecuting. In this case, the lower priority interrupt routine will be interrupted then complete executingafter the high-priority interrupt has been serviced.2. Interrupts set by the user as low priority have a lower priority of execution and are preempted by any high-priority interrupt.3. Interrupts defined with the same software priority cannot preempt or interrupt each other. Concurrent pendinginterrupts with the same user priority are resolved using the natural order priority (when vectored interrupts areenabled) or in the order the interrupt flag bits are polled in the ISR (when vectored interrupts are disabled)."It tells you precisely how to set the priority and what are the consequences.

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: July 31, 2020, 11:39:56 pm
content: Sorry mate but I have to disagree app notes and errata have saves my a$$ many times.App notes can also be much more detailed and application specific. Most Microchip datasheets especially are minimalistic.Quote from: NorthGuy on July 31, 2020, 11:05:57 pmSorry mate, but I think you totally missed what I was asking. I had a "syntax" question!My problem was not to learn how interrupts were handled, that I understood already, datasheet is indeed pretty straight forward with this!My problem was how to write the description of the ISR when using multivectored interrupts and interrupts with possibly changing priority!Do you write this: void __interrupt(irq(source_x), high_priority) mySource_xInt ( void )or void __interrupt(irq(source_x) ) mySource_xInt ( void )or void __interrupt(irq(source_x), high_priority) mySource_high_xInt ( void ) and this void __interrupt(irq(source_x), low_priority) mySource_low_xInt ( void )etc. etc. etc. etc.Correct answer is this: void __interrupt(irq(source_x) ) mySource_xInt ( void )And that answer was only in the app note.A not so easy to google app note, but still comes up after some correct keywords.

author: Nerull
author_rank: Frequent Contributor
timestamp: July 31, 2020, 11:56:34 pm
content: Interrupt declaration is compiler specific, sometimes compiler version specific, and should be in your compiler documentation.Chip datasheets don't deal with how any particular C compiler chooses to handle interrupt declarations.

author: NorthGuy
author_rank: Super Contributor
timestamp: August 01, 2020, 12:09:15 am
content: Quote from: TrickyNekro on July 31, 2020, 11:39:56 pmI totally misunderstood you.You understand perfectly well that (a) you cannot assign the priority at the compile time because it can change at run time and (b) the compiler does not need to know the priority to generate the code, and you're searching for the syntax to specify the priority. Would never cross my mind that this was the situation.

author: JPortici
author_rank: Super Contributor
timestamp: August 01, 2020, 09:54:45 am
content: Quote from: Nerull on July 31, 2020, 11:56:34 pmexcept perhaps for microchip ones. Because the IVT is a rather new concept in PIC18, in the interrupt section there are code examples in both assembly and C (using of course XC8) on how to code ISRs and how to set up the IVT manually if you want them to be at a specific address because of bootloaderAlso reference manuals for dsPIC have lots of code examples with the associated state diagrams, necessary to understand some of the peripherals - the CAN FD peripheral for example require a configuration-specific structure to be defined and allocated. Without the code example it would be almost impossible to describe

author: TrickyNekro
author_rank: Frequent Contributor
timestamp: August 02, 2020, 04:02:16 pm
content: Quote from: NorthGuy on August 01, 2020, 12:09:15 amYou don´t need to be patronizing mate.Original post was pointing to a video.@5:50 of that video, Microchip gives example using IVT, they specify interrupt priority (high priority)@6:45 of that video, Microchip gives a sencond example using IVT, they again specify priority (low priority)In same video they say @6:12 to specify the priority of the interrupt.One application note later, they give an example where you don´t have to specify priority.Quote from: JPortici on August 01, 2020, 09:54:45 amCould not agree more with that. And is can also be, generally speaking, that you find discrepancies between example code and datasheets.