|
|
View previous topic :: View next topic |
Author |
Message |
Orcino
Joined: 07 Sep 2003 Posts: 56
|
receive_buffer in CCS V5 |
Posted: Tue Sep 10, 2013 6:56 am |
|
|
Hi, Can anyone give any examples of how to use the RECEIVE_BUFFER, this in version 5 ?
Currently I use the following code and I want to test this new feature of the compiler.
Code: |
#int_rda
void RDA_isr(void)
{
do {
receiveString[next_in]=getc();
if (++next_in >=BUFFERSIZE)
next_in=0;
if(next_in==next_out)
{
if (++next_out >= BUFFERSIZE)
next_out=0;
}
} while(kbhit());
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Sep 10, 2013 8:07 am |
|
|
Stick with the existing....
There is actually nothing whatsoever to do, to use this feature. Just change the #use rs232, adding the following:
RECEIVE_BUFFER=BUFFERSIZE
and get rid of your INT_RDA
However it has problems.
There is no testing at all for the buffer being full. Results in data being completely 'garbaged' if the buffer overflows. Same applies if you use TX buffering.
If this could happen, you end up having to add your own code to intercept their RCV_NEXT_IN_1, and RCV_NEXT_OUT_1 values, and test for overflows. it's more work than just doing it yourself.
I hoped they would do something like set a status bit in RS232_ERRORS when the buffer is full.
You just use kbhit, getc, and puts in your code, and they talk to the buffer instead of to the port.
Best Wishes |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Sep 10, 2013 8:08 am |
|
|
Interesting... I don't have V5 yet. However, I would never manipulate the out/read pointer to my buffer in the in/write ISR. Sure, you want to make sure you don't try to write into a full buffer, but other than that, there's no reason for the ISR to do anything to the out/read pointer/counter.
Due to the fact that any variable other than a byte is not inherently atomic on most PICs (i.e. 16s & 18s), I usually keep buffer lengths to 256 characters or less. I also use a count rather than compare pointers/array indexes, and always go fully circular rather than worrying about message size. I also avoid buffers in structures - as tempting as a object orientated structure approach might be, it involves significant overhead. Even so, read/modify/write buffer operations may need to be critical section locked to avoid buffer corruption. I'd have done something like this totally untested code:
Code: |
// Buffer size should ideally be a power of two and no more than 256 for this code.
#define IN_BUFFERSIZE 128
byte In_Buffer[IN_BUFFERSIZE];
unsigned int8 next_in = 0;
unsigned int8 next_out = 0;
unsigned int8 In_Buf_Count = 0;
// Input buffer write. Note, this increments In_Buf_Count, the read routine
// decrements it.
#int_rda
void RDA_isr(void)
{
byte ch;
// Always read the character.
ch = getc();
// Can we fit this character into the buffer?
if (In_Buf_Count < IN_BUFFERSIZE)
{
// Yes, so store it.
receiveString[next_in++] = ch;
// Wrap the buffer write index.
if (next_in >= IN_BUFFERSIZE)
{
next_in=0;
}
}
}
byte In_Buffer_Read(void)
{
byte ch = 0;
// We will return null if buffer is empty.
if (In_Buf_Count)
{
// There is at least one character in the buffer. Get the next available character.
ch = receiveString[next_out++];
// Wrap the buffer read index.
if (next_out >= IN_BUFFERSIZE)
{
next_out=0;
}
// Decrement the buffer count. It doesn't matter if an interrupt
// has happened since we read it.
In_Buf_Count--;
}
return ch;
}
|
Also, and RDA interrupt means there is a byte available to be read from the UART. Unless there is a FIFO AND there are ISRs or critical sections longer than the time taken to send a character, then you know there will be one and only one character for every RDA interrupt, hence a while (kbhit()) loop is pointless and simply increases ISR execution time.
As I haven't yet got V5 I can't say how it does this sort of thing. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Sep 10, 2013 9:49 am |
|
|
His buffer routine is fine.
He only 'wraps' the pointer when he reaches the end of the buffer (the posted method is the best 'generic' way of doing this whatever the buffer size), and avoids overfilling.
The code is more efficient than using separate addresses and count as you show....
His routine throws away the oldest character, when the buffer fills, which is sometimes preferred.
Best Wishes |
|
|
|
|
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
|