View previous topic :: View next topic |
Author |
Message |
nailuy
Joined: 21 Sep 2010 Posts: 159
|
Error @DIV1616 when I try to divide at 3. |
Posted: Sun Sep 14, 2014 2:55 pm |
|
|
Hy.
I have program that using interrupt.
Code: | static unsigned int16 X;
#int_CCP1
void CCP1_v1()
{
X=CCP_1/3;
}
|
and compiler show this error:
Interrupts disabled during call to prevent re-entrancy: (@DIV1616)
When I try to divide CCP_1 at 2 or 4 or 8 or 16 is working well, but other's not.
Have someone any solution to work well division at 3?
Thank you. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Mon Sep 15, 2014 12:31 am |
|
|
I have to applaud PCM_programmers choice of threads to list.
If you read them all, they give both the ways to avoid this warning, and the difference between warnings and errors.
One other comment though, which links to some parts of the answers given.
It is well worth being aware of time.
Unless your division absolutely 'must' be /3, you may well be able to get a close solution quicker, by multiplying first.
For instance, if you multiply by 10, and then divide by 32, the division is done using a simple binary shift (which is why you don't get a warning from these), and the multiply takes (on a PIC18), less than 1/10th the time needed for the original division. Gives effectively /3.2, which may well be close enough.
So read the threads, and then 'think' if there may be another solution. On a 40Mhz PIC18, the /3, takes 32uSec. The multiplication, and shift, takes under 10uSec. This can be speeded even further. *2, plus *8 (can again both be done with simple shifts), used together can bring the total time involved under 5uSec. |
|
![](templates/subSilver/images/spacer.gif) |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
Re: Error @DIV1616 when I try to divide at 3. |
Posted: Mon Sep 15, 2014 2:23 am |
|
|
nailuy wrote: | compiler show this error:
Interrupts disabled during call to prevent re-entrancy: (@DIV1616)
|
Its not an error, its a warning. Its telling you that a subroutine, in this case 16 bit integer division, is being called in both interrupt and mainline code, which requires re-entrancy, so the compiler has disabled interrupts around the calls in mainline code. The code will run correctly, and you can choose whether you need to do something about it or not. Disabling interrupts for a short time generally just delays when they are serviced, i.e. increases interrupt latency, which is often not a disaster. However they may be be missed altogether if the interrupt rate is high.
Some of the solutions, while being better ways - smaller and faster code - of dividing by 3, may not fix the warning. Multiplying then dividing by a binary multiple solves the problem of dividing, as the divide by two can be done by simple shifts, but the multiply may also be implemented by a subroutine, in which case you'll still get the same warning, but for a different routine: MUL1616. As its simpler than division, it might be done by in-line code - it wasn't in my test - in which case there will not be a warning. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Mon Sep 15, 2014 2:46 am |
|
|
Little error in RF_Developers post. Gives *3, not /3......
Been there, had the 'T-shirt'. |
|
![](templates/subSilver/images/spacer.gif) |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Sep 15, 2014 2:52 am |
|
|
Ttelmah wrote: | Little error in RF_Developers post. Gives *3, not /3......
Been there, had the 'T-shirt'. |
True :-) And I fixed that in an edit a while ago. |
|
![](templates/subSilver/images/spacer.gif) |
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Tue Sep 16, 2014 8:16 am |
|
|
Thank you for your reply
PCM programmer before I post I make search and found the same links and not understand how to use it:
http://www.ccsinfo.com/forum/viewtopic.php?t=25464
why I must write #org 0x100, 0x17F?
I study other links to solve my problem.
Maybe simple division /4 is best way, but now is not the best.
Thank you to all for explanations.
Best regards for the forward. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Tue Sep 16, 2014 8:44 am |
|
|
The #org, is to tell the compiler 'where' to put the extra code.
What is happening, is you are loading a second copy of the integer maths division routine, and because it has to be near the bottom of memory (interrupt stuff has to be down here), the #org says where to put it.
The 'binary' divisions don't use the maths at all (they are simply done using rotations). Difference between a handful of instructions for /4, and (in execution) about 300 for /3.....
Really much better to do the division outside the interrupt. Avoids the problem, and prevents the possibility of the interrupt interfering with other things.
Even better, change your clock speed, so the division goes back to binary. If (for instance) you ran with 2/3rd the clock rate, you might actually find the code was faster!. |
|
![](templates/subSilver/images/spacer.gif) |
nailuy
Joined: 21 Sep 2010 Posts: 159
|
|
Posted: Tue Sep 16, 2014 1:31 pm |
|
|
I can't use division outside because I must use other 32 of int 16, real time from T1.
Really division /3 is is slower 300 times than /4. I didn't know that.
Maybe best solution by shifting >>2 equivalent of division /4, but much faster.
Yes? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19381
|
|
Posted: Tue Sep 16, 2014 2:57 pm |
|
|
The compiler automatically replaces /4, with >>2. That is why the problem doesn't appear with these binary division values. |
|
![](templates/subSilver/images/spacer.gif) |
|