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 support@ccsinfo.com

interrupt problem

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



Joined: 04 Feb 2010
Posts: 37

View user's profile Send private message

interrupt problem
PostPosted: Sat Feb 27, 2010 8:06 am     Reply with quote

I have an error as interrupts disabled during call to prevent re-entrancy @DIV88. Do you have any idea what is this ???

Here is my code :
Code:

#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_A0, rcv=PIN_A1, stream=PC)

// Defines the destination's RS485 ID
#define  RS485_DEST_ID        0x11

// Defines the device's RS485 ID
#define  RS485_ID             0x7F
#define  RS485_USE_EXT_INT    TRUE
#include <rs485.c>

int8 buffer[40];
int8 next_in  = 0;
int8 next_out = 0;

#INT_RDA
void serial_isr()
{
   int8 t;

   buffer[next_in] = fgetc(PC);
   t = next_in;
   next_in = (next_in+1) % sizeof(buffer);
   if(next_in == next_out)
      next_in=t;        // Buffer full !!
}

#define bkbhit (next_in != next_out)

int8 bgetc()
{
   int8 c;

   while(!bkbhit);
   c = buffer[next_out];
   next_out = (next_out+1) % sizeof(buffer);
   return c;
}


void main() {
   int8 i, msg[32];

   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   rs485_init();
   
   for(;;) {
      if(rs485_get_message(msg, FALSE)) {
         for(i=0; i<msg[1]; ++i)
            fputc(msg[i+2], PC);
      }

      for(i=0; bkbhit && i<sizeof(msg); ++i)
         msg[i] = bgetc();

      if(i > 0) {
         rs485_wait_for_bus(FALSE);
         while(!rs485_send_message(RS485_DEST_ID, i, msg)) {
            delay_ms(RS485_ID);
         }
      }
   }
}
dyeatman



Joined: 06 Sep 2003
Posts: 1924
Location: Norman, OK

View user's profile Send private message

Try a search
PostPosted: Sat Feb 27, 2010 9:16 am     Reply with quote

This has been asked MANY times before. Why don't you try searching before asking?

Search on:

interrupts disabled during call to prevent re-entrancy

Then select the option Search for All Terms. You will find a lot of hits and information.
_________________
Google and Forum Search are some of your best tools!!!!
Ttelmah
Guest







PostPosted: Sat Feb 27, 2010 10:11 am     Reply with quote

The other comment, is to change the buffer size to a binary multiple. 32, 64 etc..

The problem here is that if you use a 'non binary' size, the compiler has to calculate the modulus funstion, by performing a division. This takes 116 machine cycles, and results in the interrupt disabled message, if the 8 bit division is used elsewhere in the code.
However use a binary size, and the same function can be performed by a bitwise '&'. Only takes a couple of mchine cycles!.....
If you look at the CCS examples, they use a binary multiple size. There really ought to be a warning, to keep to this.....

Best Wishes
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Sat Feb 27, 2010 8:49 pm     Reply with quote

I would have written:
Code:
if (++next_in == sizeof(buffer)) next_in = 0;
if (next_in == next_out) next_in = t;

_________________
Andrew
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Sat Feb 27, 2010 11:14 pm     Reply with quote

And I would have written:

Code:

int8 buffer[32];

...

bit_clear(++next_in, 5);        // If it hits 32, reset to 0

Ttelmah
Guest







PostPosted: Sun Feb 28, 2010 3:28 am     Reply with quote

Yes.
Andrewg's solution, has the advantage of working for any buffer size.
It is well worth looking at the .lst

For the original solution, with a buffer size of 40, you get:
Code:

....................    next_in = (next_in+1) % sizeof(buffer);
00E2:  MOVLW  01
00E4:  ADDWF  42,W
00E6:  MOVWF  49
00E8:  MOVWF  4A
00EA:  MOVLW  28
00EC:  MOVWF  4B
00EE:  BRA    00A2
00F0:  MOVFF  00,42

//and at A2 (the actual division)
00A2:  MOVF   4B,W
00A4:  CLRF   01
00A6:  SUBWF  4A,W
00A8:  BC    00B0
00AA:  MOVFF  4A,00
00AE:  BRA    00C8
00B0:  CLRF   00
00B2:  MOVLW  08
00B4:  MOVWF  4C
00B6:  RLCF   4A,F
00B8:  RLCF   00,F
00BA:  MOVF   4B,W
00BC:  SUBWF  00,W
00BE:  BTFSC  FD8.0
00C0:  MOVWF  00
00C2:  RLCF   01,F
00C4:  DECFSZ 4C,F
00C6:  BRA    00B6
00C8:  GOTO   00F0 (RETURN)

with the central bit of this looping 8 times...

For the original code, with a binary buffer size, this reduces to:
Code:

....................    next_in = (next_in+1) % sizeof(buffer);
00B8:  MOVLW  01
00BA:  ADDWF  3A,W
00BC:  ANDLW  1F
00BE:  MOVWF  3A

Just four instructions.

Andrewg's version, takes one more instruction than this, but works for any buffer size.

John P's version, takes just two instructions, but is again limited to binary buffer sizes.

So, for a binary buffer size, you can beat the compiler's default solution, by going with John P's solution. For a non binary size, switching to Andrewg's solution, costs just one instruction (beating the default solution by 111 instructions). Both avoid using divisions.

You will find all of this has been covered many times in the past....

Best Wishes
koray_duran



Joined: 04 Feb 2010
Posts: 37

View user's profile Send private message

PostPosted: Sun Feb 28, 2010 8:57 am     Reply with quote

Thanks!!!! I've solved the warning. =)
But still my device doesn't work!!! It seems I will work on this for a while.
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