I'm working on some code where there are several possible sources of an interrupt - currently all the same priority level - and I'm struggling to understand what is possible within Swordfish.
Can you define more than one interrupt handler for the same priority and if so, how are they 'merged'? The help file isn't so clear on this, it suggests more than one is possible but the only example it gives is for different priority levels.
I am hoping to be able to create a module for interrupt-based serial comms and ideally wanted to put an interrupt handler within that module that would be automatically merged with the one in the main program which handles 4 timer interrupts. It would be even nicer (clearer in terms of code) if I could write a separate ISR for each timer.
Does the Interrupt command work that way? Or can you just have one instance for each priority level and you have to test the interrupt flags manually?
As an aside, part of the reason for wanting to move the serial routines out in to a module is for clarity of code. It would be great if David could look at adding code-folding to the IDE as that would help a lot. If you close just close all the subs and functions and only open them up when you wanted to check or edit something that would make development a lot easier.
Multiple interrupt question
Moderators: David Barker, Jerry Messina
-
- Posts: 219
- Joined: Wed Sep 11, 2013 1:27 pm
- Location: Chesterfield
- David Barker
- Swordfish Developer
- Posts: 1214
- Joined: Tue Oct 03, 2006 7:01 pm
- Location: Saltburn by the Sea, UK
- Contact:
Re: Multiple interrupt question
Interrupt limitations are defined by the 18 series micros and not by Swordfish. The 18 series has only two interrupt levels (high and low). If you have multiple interrupt sources attached to a high or low interrupt, you have to check (and clear) the interrupt flag source in the ISR itself. For example,
It's not often pretty but it will work. You need to read the device datasheet for more information of interrupt flags, priorities etc. You can only have separate ISRs with different priorities on the PIC24 and PIC32 series.
Code: Select all
interrupt:
if usart_data_received_flag_set then
...do this
clear flag
elseif on_change_flag_set then
...do this
clear flag
etc etc
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Re: Multiple interrupt question
To expand a bit on your original questions...
It makes it next to impossible to do this in a nice, modular fashion since the isr code is usually separate from the module code, but that's what you're pretty much stuck with because of the way the PIC18 vectors work.
You'll have to deal with the interrupt IF, IE, and IP flags yourself. As a side note, make sure you only ever call 'Enable()/Disable()' once in your main code. If you want to enable/disable individual intr sources you should use the IE flag for that source.
Also, be very careful about using subroutine/library calls in the ISRs. Be sure to use the Save()/Restore() mechanism as appropriate for your code. It usually takes a bit of work 'under the hood' to get this right.
You can only have one handler per priority. While you can have multiple interrupt() procedures declared in your source modules, only one can ever be active and in use. That is, you can only ever 'Enable()' one of them for each of the two priorities. I think that's what the help file is referring to. It would be a nice feature if it worked that way somehow, but it doesn't.Can you define more than one interrupt handler for the same priority and if so, how are they 'merged'? The help file isn't so clear on this, it suggests more than one is possible but the only example it gives is for different priority levels.
Unfortunately that won't work. The SF interrupt model works fine for a single interrupt source, but once you want to have multiple sources from different modules handled by a single priority you'll have to do all the interrupt() routines in a common place and test the individual sources yourself, just like you'd have to do in any other language.I am hoping to be able to create a module...<SNIP>. Does the Interrupt command work that way?
It makes it next to impossible to do this in a nice, modular fashion since the isr code is usually separate from the module code, but that's what you're pretty much stuck with because of the way the PIC18 vectors work.
You'll have to deal with the interrupt IF, IE, and IP flags yourself. As a side note, make sure you only ever call 'Enable()/Disable()' once in your main code. If you want to enable/disable individual intr sources you should use the IE flag for that source.
Also, be very careful about using subroutine/library calls in the ISRs. Be sure to use the Save()/Restore() mechanism as appropriate for your code. It usually takes a bit of work 'under the hood' to get this right.
-
- Posts: 219
- Joined: Wed Sep 11, 2013 1:27 pm
- Location: Chesterfield
Re: Multiple interrupt question
Thanks, David and Jerry, unfortunately that confirms you can't have a library for interrupt-driven serial comms which is a shame.
I guess what I was hoping is that you could define a code block that could be automatically inserted in to the interrupt handler defined in the main source file. In theory - with a few rules defined - it could be not too difficult to implement and could be quite powerful. As you've pointed out, David, a typical ISR involves testing a flag and executing some code. I'd guess it wouldn't be too difficult to implement a pre-processor directive where you specify the flag to be tested and the code to be executed if it is set and this be automatically added in to the ISR?
The down-side of that approach is that any user changing of the ISR would have to be quite tightly controlled and if you had interrupts interacting with each other (not sure if this is done or even advisable...) then it wouldn't be possible.
Does that seem a good suggestion? Almost automatic creating of a single ISR rather than letting the user create it.
I guess what I was hoping is that you could define a code block that could be automatically inserted in to the interrupt handler defined in the main source file. In theory - with a few rules defined - it could be not too difficult to implement and could be quite powerful. As you've pointed out, David, a typical ISR involves testing a flag and executing some code. I'd guess it wouldn't be too difficult to implement a pre-processor directive where you specify the flag to be tested and the code to be executed if it is set and this be automatically added in to the ISR?
The down-side of that approach is that any user changing of the ISR would have to be quite tightly controlled and if you had interrupts interacting with each other (not sure if this is done or even advisable...) then it wouldn't be possible.
Does that seem a good suggestion? Almost automatic creating of a single ISR rather than letting the user create it.
-
- Swordfish Developer
- Posts: 1473
- Joined: Fri Jan 30, 2009 6:27 pm
- Location: US
Re: Multiple interrupt question
Not quite what you're suggesting, but there's a scheme I've used that gives a semi-modular approach that I posted here in this thread http://sfcompiler.co.uk/phpBB3/viewtopic.php?f=3&t=1253 a few years back. You still need to have a custom ISR module file for the project, but the lib modules themselves typically don't need to change.
I've used it on a number of projects and it's worked out well for me. One thing... that post is pretty old so I'm sure I've changed a number of things since then, but it's a starting point.
I've used it on a number of projects and it's worked out well for me. One thing... that post is pretty old so I'm sure I've changed a number of things since then, but it's a starting point.