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

Warning 216 : How to prevent function mutualization

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



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

Warning 216 : How to prevent function mutualization
PostPosted: Mon Apr 17, 2017 2:34 pm     Reply with quote

Hello,

I use [] operator inside and outside interruptions. Then i have warning 216.
Compiler mutualize some code into self generated functions (for code volume optimization). I found some explanations on this forum.

I can "solve" warning 216 in many other cases, but not for [] operator (and not for usb driver functions, but it is not an issue). I use a lot of [] operator, and i can not use other solutions. I have bad experience with iterators (of structure pointer) and ccs ... many bugs ...
So, i must use [] operator.

Here a simple example :
Code:

#include <16F1705.h>
#fuses INTRC_IO,NOWDT,NOMCLR,NOPROTECT,NODEBUG,NOLVP
#use delay(clock=32MHZ)

struct SDummy
   {
   byte a;
   unsigned int16 value;
   };

struct SDummyInterruption
   {
   byte a;
   unsigned int16 value;
   };

struct SDummy _dummyTable[20];

#define setDummyTableValue(_offset,_value) {_dummyTable[_offset].value=_value;}
// Try to replace [] operator by arithmetic operation : same result, compiler use sans function in interruption and main.
#define setDummyTableValue2(_offset,_value) {((struct SDummy*)((byte*)_dummyTable+_offset*sizeof(struct SDummy)))->value=_value;}
// Try to use another symbol, with an other equivalent structure (with different call on main and interrupt) : same result, compiler use sans function in interruption and main.
#define setDummyTableValue_Interruption(_offset,_value) {((struct SDummyInterruption*)((byte*)_dummyTable+_offset*sizeof(struct SDummy)))->value=_value;}

#INT_RC
void handler_rc(void)
   {
   unsigned int i;
   for(i=0;i<20;i++)
      {
      setDummyTableValue(i,2);
      }
   clear_interrupt(INT_RC);
   }

void main(void)
   {
   unsigned int i;

   enable_interrupts(INT_RC);
   enable_interrupts(GLOBAL);

   while(true)
      {
      for(i=0;i<20;i++)
         {
         setDummyTableValue(i,1);
         }
      }
   }   


Here is a (not really good) solution, by replacing [] operator with inline function:
Code:

#INLINE
void setDummyTableValueFunction(unsigned int8 offset,unsigned int16 value) {_dummyTable[offset].value=value;}

But it raises code volume.

Any other idea ? By-pass ?
How dissociate [] operator for interruption, and [] operator for main ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 17, 2017 10:08 pm     Reply with quote

You should have posted the full warning message, which is this:
Quote:
>>> Warning 216 "pcm_test.c" Line 51(4,5): Interrupts disabled during call to prevent re-entrancy: (@MUL88)

This tells us the problem is caused by your code calling the CCS math
library routine @MUL88 in the isr, and in main().

This thread explains more about the problem:
http://www.ccsinfo.com/forum/viewtopic.php?t=33837&highlight=org+default

A brute force method of doing it would be to unroll the for() loop in the isr:
Code:

_dummyTable[0].value = 2;
_dummyTable[1].value = 2;
_dummyTable[2].value = 2;
     .
     .
     .
_dummyTable[19].value = 2;

The above method is much faster. Using the Stopwatch feature of MPLAB
vs. 8.92 simulator, I got 42 instruction cycles for the unrolled loop vs.
1386 instruction cycles for the for() loop and associated math operations.

How to use the Stopwatch feature of MPLAB (vs. 8.92) simulator to
find the number of instruction cycles in a segment of your program:
http://www.ccsinfo.com/forum/viewtopic.php?t=38351
tssir



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 3:12 am     Reply with quote

Thank you for answer.

For a general use, i will dissociate interruption function from main function.
Both solutions :

1) I must use only elementary operations on interruption (add, shift, ...).
As this example :
Code:

struct SDummy
   {
   byte a;
   unsigned int16 value;
   };

struct SDummy _dummyTable[20];

struct SDummy * getDummyTablePtr(unsigned int8 offset)
   {
   struct SDummy * res;
   unsigned int8 i;

   res=_dummyTable;
   for(i=0;i<offset;i++)
      {
      res=res+sizeof(struct SDummy);
      }
   return res;
   }
#define setDummyTableValue_forInterruption(_offset,_value) {getDummyTablePtr(_offset)->value=_value;}
#define setDummyTableValue(_offset,_value) {_dummyTable[_offset].value=_value;}

#INT_RC
void handler_rc(void)
   {
   unsigned int i;
   for(i=0;i<20;i++)
      {
      setDummyTableValue_forInterruption(i,2);
      }
   clear_interrupt(INT_RC);
   }

void main(void)
   {
   unsigned int i;

   enable_interrupts(INT_RC);
   enable_interrupts(GLOBAL);

   while(true)
      {
      for(i=0;i<20;i++)
         {
         setDummyTableValue(i,1);
         }
      }
   }   


2) Use #org directive. But it is risky. Especially for a large and evolutive program. You should be aware about addresses.
tssir



Joined: 14 Feb 2016
Posts: 24

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 11:46 am     Reply with quote

#ORG solution not working with a "real world" large program (a 58ko hex file, for my current project). #ORG itself works, and puts isr code at the right place (checked on pic ROM). But [] operator (8 bits multiplication) is not dissociate, despite #ORG.

But it works perfectly with a small test program.

Anyway, i use the first solution : isr only uses elementary operations (not embedded compiler functions or ccs drivers functions).
A getenv() to check if current code is inside an ISR, should be usefull. But without this option, i write two functions for same operation (one for isr, one for main).
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