CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Error @DIV1616 when I try to divide at 3.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nailuy



Joined: 21 Sep 2010
Posts: 159

View user's profile Send private message

Error @DIV1616 when I try to divide at 3.
PostPosted: Sun Sep 14, 2014 2:55 pm     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Sep 14, 2014 3:34 pm     Reply with quote

See this thread for a solution:
http://www.ccsinfo.com/forum/viewtopic.php?t=25464

Other related threads:
http://www.ccsinfo.com/forum/viewtopic.php?t=33837
http://www.ccsinfo.com/forum/viewtopic.php?t=41570
http://www.ccsinfo.com/forum/viewtopic.php?t=44721
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Sep 15, 2014 12:31 am     Reply with quote

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.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: Error @DIV1616 when I try to divide at 3.
PostPosted: Mon Sep 15, 2014 2:23 am     Reply with quote

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.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Mon Sep 15, 2014 2:46 am     Reply with quote

Little error in RF_Developers post. Gives *3, not /3......

Been there, had the 'T-shirt'.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Mon Sep 15, 2014 2:52 am     Reply with quote

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.
nailuy



Joined: 21 Sep 2010
Posts: 159

View user's profile Send private message

PostPosted: Tue Sep 16, 2014 8:16 am     Reply with quote

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.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Sep 16, 2014 8:44 am     Reply with quote

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!.
nailuy



Joined: 21 Sep 2010
Posts: 159

View user's profile Send private message

PostPosted: Tue Sep 16, 2014 1:31 pm     Reply with quote

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?
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Sep 16, 2014 2:57 pm     Reply with quote

The compiler automatically replaces /4, with >>2. That is why the problem doesn't appear with these binary division values.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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