Context saving in an Exception handler

Discuss the Firewing language

Context saving in an Exception handler

Postby Timbo » Sat May 16, 2015 4:50 pm

When I have code in an interrupt exception handler what do I need to do about interrupt context saving. And how do I find out what needs saving. eg is the simple way. I know I can look at the asm. I never do anything but basic maths and logic testing but not sure how it handles complex maths eg

RoundedDiv = (ValueNum + ( ValueDivisor / 2)) / ValueDivisor

Does that start using internal variables or is the code broken so does not need to hold intermediate vars


Thanks
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Context saving in an Exception handler

Postby Jerry Messina » Sat May 16, 2015 11:20 pm

There's no quick easy answer to that. It depends on a number of factors... the data types involved, 8/16/32 bit target, etc.

In general, multiplication and division will probably involve one of the system libraries, so you should use 'save(0)' to protect the internal system variables (those named SB_xxxxx). For the PIC18 (which I think you're using), save(0) will also save the FSR0, FSR1, and PROD registers for you.

An expression like
Code: Select all
RoundedDiv = (ValueNum + ( ValueDivisor / 2)) / ValueDivisor

will almost always generate some intermediate temp variables, but you normally shouldn't have to worry too much about those if the code is
directly inline in the isr. If it's in a sub or event that you call from the isr that's a different story. If you call a routine then you should add the sub's name to the save() list.

If you want to avoid the use of any intermediate values, then you have to help the compiler along and break up the expression so that there's nothing on the right-hand side that would have to be saved...
Code: Select all
    RoundedDiv = ValueDivisor / 2
    RoundedDiv = RoundedDiv + ValueNum
    RoundedDiv = RoundedDiv/ValueDivisor

Sometimes that can end up producing smaller code as well, but it's a lot of bother and makes it much harder to see what the intent is.

So, the general rule is something like this:
- if you don't want to bother looking at the asm, use 'save(0)'
- if you call ANY routines from the isr, add them to the 'save()' list

That should be safe. It might be overkill, but it should work. If you want to reduce the overhead then you need to do a little digging.

PS - I assumed you meant an interrupt handler, and not a PIC24 exception handler. Two different things.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Context saving in an Exception handler

Postby Timbo » Sun May 17, 2015 9:27 am

Hi Jerry

You're a wealth of great info.

Normally I break up lines of code exactly like you showed, its no issue to me on the readability as I try to comment it well enough for me to figure it out later.

The reason I asked is that in the long past when talking to Dave about how the compiler works he said code size would not be affected as the compiler broke down long lines internally. But as you rightly pointed out there will have to be holding vars for that line.
I'm going to break it down just incase and use save(0)

The code is currently being written for the FireWing18 as I can VSM it. So for its been great boon as I am simulating the mechanical hardware it's connected to with another pic.

I know I have a lot to learn about the inner workings of Firewing but I have to say so far it's a fantastic accomplishment.

Thanks again.
Last edited by Timbo on Sun May 17, 2015 1:03 pm, edited 1 time in total.
Timbo
 
Posts: 93
Joined: Fri May 03, 2013 7:51 pm

Re: Context saving in an Exception handler

Postby Jerry Messina » Sun May 17, 2015 11:52 am

There's one thing you have to watch out for if you break the expression up into smaller pieces.

Lets say all of those variables are 16-bit (ushort) types.
In the original equation
Code: Select all
    RoundedDiv = (ValueNum + ( ValueDivisor / 2)) / ValueDivisor
the compiler's smart enough to recognize that in order to produce a correct result it needs to use 32-bit math, and halfway through the calculations it automatically switches precision, doing the addition and final division as 32-bit.

When you break it up into smaller chunks it may not do this. In the example code I posted the addition and division are done as 16-bit and any overflow from the addition is thrown away, so the results from the two methods can be different. That's one of the reasons the code ends up smaller.

If you know the range of values you're working with that can be ok, but if you want it to use "always produce the correct result for me" mode you're better off with leaving it all as one expression.

David's code is usually pretty good at recognizing this sort of thing. It can make life a lot easier.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am


Return to Language

Who is online

Users browsing this forum: No registered users and 3 guests

cron

x