|
|
View previous topic :: View next topic |
Author |
Message |
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
interrupts disabled during call to prevent re-entrancy |
Posted: Fri Dec 01, 2006 3:12 pm |
|
|
I understand what this means and why.
I have an interrupt routine which must do some floating math (special situation), and some main-loop code which also does floating math.
How can I direct the compiler to generate code so that both routines can do floating math without disabling the interrupt in the main loop?
Thanks,
Ken |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Dec 01, 2006 3:27 pm |
|
|
Can you post the interrupt code ?
Also post the PIC and the compiler version. |
|
|
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Fri Dec 01, 2006 3:38 pm |
|
|
Here is a line from the (timer) interrupt code:
Cn *= ( 1.0 - 2.0 / (4 * n + 1));
Cn is a float; n is a 16-bit unsigned integer
This expression evaluates in ~120 usec at 40MHz - not bad.
CCS Compiler Version is 3.249; I cannot yet do any real work with V4xxx
The PIC is an 18F8722;
Thanks,
Ken |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Dec 01, 2006 5:09 pm |
|
|
Where is Cn used? In the interrupt? I can't think of a reason to need a float inside of an interrupt so why not move the computation outside of the interrupt where Cn is accessed. |
|
|
ttelmah Guest
|
|
Posted: Sat Dec 02, 2006 5:57 am |
|
|
The reason it evaluates in 120uSec, is that the first half is being done in integer. The compiler will evaluate 4*n+1 in integer, which involves only two rotations, and an addition. The main time is then taken by the division (which is float), and the following addition. The float division will take a variable time, according to the values involved, with the worst case being probably closer to 200uSec, than 120uSec.
You need to beware of this, since if 'n' can ever be larger than 16383, there will be an arithmetic overflow.
Now the integer arithmetic, will generally be performed 'inline', and hence does not matter having duplicates in the interrupt code and outside.
Personally, I'd agree wholeheartedly with the 'put the maths outside' suggestions. However I'd also wonder if you can do things faster, and avoid the problem, by using an int32. Since you are only using fairly basic arithmetic (+, -, and /), you might want to consider scaling the result to be 65536* the value wanted. The arithmetic using int32, will be a fraction faster (only a tiny amount).
Seperately, it is impossible without knowing what the arithmetic is actually 'for', to see if their may be a shortcut. As an example, for a value that needed to be 'tweaked' by a small factor read from an ADC, rather than using the reciprocal, you may be able to 'cheat', with integer aritmetic (there are a couple of neat ways of getting a very similar result using multiplication, rather than division with this...).
If you absolutely 'must have' fp, then I'm afraid you'll simply have to encode your own library.
Best Wishes |
|
|
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Sat Dec 02, 2006 11:49 am |
|
|
Thank you all for your help. You folks are very knowledgeable and highly respected by yours truly. I scan this forum daily, and learn a little more each day. But this time, you were distracted from the real question by my (seemingly in-experienced) departure from the cardinal isr rule of "keep it short and simple."
I tried to keep my question as simple and direct as possible - "How can I direct the compiler..."
The floating math is used in the timer isr to determine the timer setting for the next timer interrupt. Under the circumstances, this was the best approach. Then management decided that an ASCII user-interface be added to the existing, completed project. This led to the need for floating math in the main loop, hence my question.
The same post was sent to CCS tech support; their response:
[i]"Use #ORG to allocate a segment of memory for one of your functions (and the associated math functions)
as follows and the compiler will generate a second copy of the required functions.
#ORG start,end DEFAULT
// One of your functions here that does floating point math
#ORG DEFAULT
This feature is normally used for a bootloader that can not use the primitive functions
in the main program. It will also work for your situation."[/i]
The program now builds without the "interrupts disasbled" warning.
Hope this is helpful to someone else in this situation.
Thanks again for your help.
Ken |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|