Hi R,Ring buffers are far simpler to use than linear, once you get your head around the concept.
I always use power-of-two sizes, which means you can just AND the pointers with an appropriate mask after each increment to make them "wrap" in the buffer space.
You then never have to be bothered with the absolute positions within the buffer.
eg. for a 32 location ring buffer, use a 32 location array, then AND the index pointers with 0x1F after each increment.
I've never used it, but from fragments I've seen it seems straightforward.Can you read Oshonsoft?
Hi R,I've never used it, but from fragments I've seen it seems straightforward.
From a quick look at the language reference, to make eg. a receive buffer:
Dim rxbuf_in as byte
Dim rxbuf_out as byte
Dim rxbuffer(16) as byte
In your initialisation section:
rxbuf_in = 0
rxbuf_out = 0
Buffer in routine, eg. in your receive interrupt:
rxbuffer(rxbuf_in) = recievedata_value, wherever that comes from
rxbuf_in = rxbuf_in + 1
rxbuf_in = rxbuf_in And %00001111
Optionally, check for overflow at that point
If rxbuf_in = rxbuf_out then
error, do something.....
Endif
In the main programs loop, check for new characters:
if rxbuf_out <> rxbuf_in then
Some data in the buffer do something with it
newdata = rxbuffer(rxbuf_out)
rxbuf_out = rxbuf_out + 1
rxbuf_out = rxbuf_out And %00001111
Do whatever you need with newdata...
Endif
Or you can wait until the recieve character matches a marker (using another If comparison on the received data after storing a copy), a carriage return or whatever, then set another variable to tell the main program to copy the content from the buffer..
There are many ways to handle such things.
There should only be one buffer, if you have two then something is horribly wrong.my program makes the 1st buffer, inside the INTERRUPT, and now I'm looking at the MAIN LOOP where the second buffer/STRING will be.
Hi M,There should only be one buffer, if you have two then something is horribly wrong.
The code above (rjenkingsgb) is short and very easy to follow.
Mike.
Hi M,It's called a ring buffer because the end is joined to the start - not physically but in code. Think of it as a snake with a head and tail - and kinda eating itself. Initially, the snake has no length - the buffer is empty so head and tail have the same value. When a value arrives we add it to the front of the buffer (the head) and move the head (pointer) along one. In our main code we check the length of the snake (length=head-tail) and if it's not zero we can remove a byte from the tail end and move the tail along one. If we're tied up doing something else then the snake can just grow longer. Maybe not a good analogy but if you can visualize it in a different way then it may help you.
Mike.
Hi,
It's been pointed out to me that a RING BUFFER would 'eat' too much memory for my project (PIC), so I've reverted back to a LINEAR BUFFER.
Hi N and I,I agree... A ring buffer can be smaller than a linear one.. It's how you service the buffer that counts... Ring buffers work extremly well with software / hardware hand shaking as you can control the input speed to coinside with your processing speed..
I've been racking my brains.. I'm sure I did a ring buffer in Oshonsoft for you sometime since... But I cannot find it.
Hi I,I've been racking my brains.. I'm sure I did a ring buffer in Oshonsoft for you sometime since... But I cannot find it.
else if(PIE3bits.RC1IE == 1 && PIR3bits.RC1IF == 1)
{
if(1 == RC1STAbits.OERR)
{
// EUSART1 error - restart
RC1STAbits.CREN = 0;
RC1STAbits.CREN = 1;
}
// buffer overruns are ignored
eusart1RxBuffer[eusart1RxHead++] = RC1REG;
if(sizeof(eusart1RxBuffer) <= eusart1RxHead)
{
eusart1RxHead = 0;
}
eusart1RxCount++;
}
unsigned char EUSART1_Read(void)
{
unsigned char readValue = 0;
while(0 == eusart1RxCount)
{
}
readValue = eusart1RxBuffer[eusart1RxTail++];
if(sizeof(eusart1RxBuffer) <= eusart1RxTail)
{
eusart1RxTail = 0;
}
PIE3bits.RC1IE = 0;
eusart1RxCount--;
PIE3bits.RC1IE = 1;
return readValue;
}
Hi N,This is what MCC generates (in C) as a serial ring buffer interrupt routine:
C:else if(PIE3bits.RC1IE == 1 && PIR3bits.RC1IF == 1) { if(1 == RC1STAbits.OERR) { // EUSART1 error - restart RC1STAbits.CREN = 0; RC1STAbits.CREN = 1; } // buffer overruns are ignored eusart1RxBuffer[eusart1RxHead++] = RC1REG; if(sizeof(eusart1RxBuffer) <= eusart1RxHead) { eusart1RxHead = 0; } eusart1RxCount++; }
To read bytes out of the buffer, it generates this:
C:unsigned char EUSART1_Read(void) { unsigned char readValue = 0; while(0 == eusart1RxCount) { } readValue = eusart1RxBuffer[eusart1RxTail++]; if(sizeof(eusart1RxBuffer) <= eusart1RxTail) { eusart1RxTail = 0; } PIE3bits.RC1IE = 0; eusart1RxCount--; PIE3bits.RC1IE = 1; return readValue; }
I know it's in C, but it should be fairly easy to understand.
A buffer - eusart1RxBuffer[]
Head variable - eusart1RxHead
Tail variable - eusart1RxTail
And a count of how many bytes are in the buffer - eusart1RxCount (used to check if there's anything in the buffer or not)
When you have a complete message in the buffer, can't you switch the Usart to another message source and write it's characters to second buffer.Hi N and I,
I, I don't think I can control the DATA input speed, (GPS MODULE) (I'll look for your previous CODE)
I'm on two forums, a member from the other one, who has helped me a great deal with the project I'm working on, reminded me that the PIC I'm using may run out of memory if I'm not careful.
Regarding Linear or Ring Buffers, I'm having difficulty with both of them.
I was advised to make the Ring buffer twice as long as the longest sentence, so I complied, but my logic said, that as the MAIN LOOP must be faster that the DATA input, then the MAIN LOOP shold overtake the DATA writing, so a long buffer shouldn't be needed.
With both types, I'm unable to increment through and READ the saved DATA without affecting the incoming DATA being WRITTEN.
C
Hi J,When you have a complete message in the buffer, can't you switch the Usart to another message source and write it's characters to second buffer.
Meanwhile the main program can parse the completed message or do something useful.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?