|
|
View previous topic :: View next topic |
Author |
Message |
koray_duran
Joined: 04 Feb 2010 Posts: 37
|
interrupt problem |
Posted: Sat Feb 27, 2010 8:06 am |
|
|
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: 1934 Location: Norman, OK
|
Try a search |
Posted: Sat Feb 27, 2010 9:16 am |
|
|
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
|
|
Posted: Sat Feb 27, 2010 10:11 am |
|
|
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
|
|
Posted: Sat Feb 27, 2010 8:49 pm |
|
|
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
|
|
Posted: Sat Feb 27, 2010 11:14 pm |
|
|
And I would have written:
Code: |
int8 buffer[32];
...
bit_clear(++next_in, 5); // If it hits 32, reset to 0
|
|
|
|
Ttelmah Guest
|
|
Posted: Sun Feb 28, 2010 3:28 am |
|
|
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
|
|
Posted: Sun Feb 28, 2010 8:57 am |
|
|
Thanks!!!! I've solved the warning. =)
But still my device doesn't work!!! It seems I will work on this for a while. |
|
|
|
|
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
|