Changed Ringbuf API: Ringbuf_Pop_Front is now Ringbuf_Pop, and now it copies the buffer into parameter and returns boolean. Original method was not safe since it returned a pointer to the element but freed the buffer element. Changed Ringbuf_Get_Front to Ringbuf_Peek with no change in functionality, to make names more consistent.

Updated all the MS/TP datalink layer implementations that use Ringbuf library.
This commit is contained in:
skarg
2013-01-08 20:48:34 +00:00
parent 3bc404dbe9
commit cf882642a8
8 changed files with 107 additions and 65 deletions
+16 -4
View File
@@ -49,13 +49,17 @@ extern "C" {
RING_BUFFER const *b); RING_BUFFER const *b);
bool Ringbuf_Empty( bool Ringbuf_Empty(
RING_BUFFER const *b); RING_BUFFER const *b);
volatile uint8_t *Ringbuf_Get_Front( volatile uint8_t *Ringbuf_Peek(
RING_BUFFER const *b); RING_BUFFER const *b);
volatile uint8_t *Ringbuf_Pop_Front( bool Ringbuf_Pop(
RING_BUFFER * b); RING_BUFFER * b,
uint8_t *data_element);
bool Ringbuf_Put( bool Ringbuf_Put(
RING_BUFFER * b, /* ring buffer structure */ RING_BUFFER * b, /* ring buffer structure */
volatile uint8_t * data_element); /* one element to add to the ring */ uint8_t *data_element); /* one element to add to the ring */
bool Ringbuf_Put_Front(
RING_BUFFER * b, /* ring buffer structure */
uint8_t *data_element);
volatile uint8_t *Ringbuf_Alloc( volatile uint8_t *Ringbuf_Alloc(
RING_BUFFER * b); RING_BUFFER * b);
/* Note: element_count must be a power of two */ /* Note: element_count must be a power of two */
@@ -65,6 +69,14 @@ extern "C" {
unsigned element_size, /* size of one element in the data block */ unsigned element_size, /* size of one element in the data block */
unsigned element_count); /* number of elements in the data block */ unsigned element_count); /* number of elements in the data block */
#ifdef TEST
#include "ctest.h"
void testRingBufSize16(
Test * pTest);
void testRingBufSize32(
Test * pTest);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
+6 -5
View File
@@ -763,7 +763,7 @@ static bool MSTP_Master_Node_FSM(
transition_now = true; transition_now = true;
} else { } else {
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -790,6 +790,7 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break; break;
} }
(void) Ringbuf_Pop(&PDU_Queue, NULL);
} }
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
@@ -1091,7 +1092,7 @@ static bool MSTP_Master_Node_FSM(
/* BACnet Data Expecting Reply, a Test_Request, or */ /* BACnet Data Expecting Reply, a Test_Request, or */
/* a proprietary frame that expects a reply is received. */ /* a proprietary frame that expects a reply is received. */
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0], dlmstp_compare_data_expecting_reply(&InputBuffer[0],
@@ -1109,7 +1110,6 @@ static bool MSTP_Master_Node_FSM(
/* then call MSTP_Send_Frame to transmit the reply frame */ /* then call MSTP_Send_Frame to transmit the reply frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -1117,6 +1117,7 @@ static bool MSTP_Master_Node_FSM(
} }
MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station, MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
(uint8_t *) & pkt->buffer[0], pkt->length); (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
@@ -1180,7 +1181,7 @@ static void MSTP_Slave_Node_FSM(
} }
} else if (MSTP_Flag.ReceivePacketPending) { } else if (MSTP_Flag.ReceivePacketPending) {
if (!Ringbuf_Empty(&PDU_Queue)) { if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
matched = matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0], dlmstp_compare_data_expecting_reply(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0], pkt->length, DataLength, SourceAddress, &pkt->buffer[0], pkt->length,
@@ -1194,7 +1195,6 @@ static void MSTP_Slave_Node_FSM(
/* then call MSTP_Send_Frame to transmit the reply frame */ /* then call MSTP_Send_Frame to transmit the reply frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -1202,6 +1202,7 @@ static void MSTP_Slave_Node_FSM(
} }
MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station, MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
(uint8_t *) & pkt->buffer[0], pkt->length); (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
} }
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivePacketPending = false; MSTP_Flag.ReceivePacketPending = false;
+5 -3
View File
@@ -785,7 +785,7 @@ static bool MSTP_Master_Node_FSM(
transition_now = true; transition_now = true;
} else { } else {
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -812,6 +812,7 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break; break;
} }
(void) Ringbuf_Pop(&PDU_Queue, NULL);
} }
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
@@ -1123,7 +1124,7 @@ static bool MSTP_Master_Node_FSM(
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
} else { } else {
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0], dlmstp_compare_data_expecting_reply(&InputBuffer[0],
@@ -1141,7 +1142,6 @@ static bool MSTP_Master_Node_FSM(
/* then call MSTP_Send_Frame to transmit the reply frame */ /* then call MSTP_Send_Frame to transmit the reply frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -1152,6 +1152,8 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
/* clear the queue */
(void) Ringbuf_Pop(&PDU_Queue, NULL);
} else if (pkt != NULL) { } else if (pkt != NULL) {
/* DeferredReply */ /* DeferredReply */
/* If no reply will be available from the higher layers */ /* If no reply will be available from the higher layers */
+4 -3
View File
@@ -316,7 +316,7 @@ uint16_t MSTP_Get_Send(
if (Ringbuf_Empty(&PDU_Queue)) { if (Ringbuf_Empty(&PDU_Queue)) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -326,6 +326,7 @@ uint16_t MSTP_Get_Send(
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
return pdu_len; return pdu_len;
} }
@@ -498,7 +499,7 @@ uint16_t MSTP_Get_Reply(
if (Ringbuf_Empty(&PDU_Queue)) { if (Ringbuf_Empty(&PDU_Queue)) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
/* is this the reply to the DER? */ /* is this the reply to the DER? */
matched = matched =
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0], dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
@@ -507,7 +508,6 @@ uint16_t MSTP_Get_Reply(
if (!matched) { if (!matched) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -517,6 +517,7 @@ uint16_t MSTP_Get_Reply(
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
return pdu_len; return pdu_len;
} }
+4 -3
View File
@@ -387,7 +387,7 @@ uint16_t MSTP_Get_Send(
if (Ringbuf_Empty(&poSharedData->PDU_Queue)) { if (Ringbuf_Empty(&poSharedData->PDU_Queue)) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&poSharedData->PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&poSharedData->PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -397,6 +397,7 @@ uint16_t MSTP_Get_Send(
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&poSharedData->PDU_Queue, NULL);
return pdu_len; return pdu_len;
} }
@@ -574,7 +575,7 @@ uint16_t MSTP_Get_Reply(
if (Ringbuf_Empty(&poSharedData->PDU_Queue)) { if (Ringbuf_Empty(&poSharedData->PDU_Queue)) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&poSharedData->PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&poSharedData->PDU_Queue);
/* is this the reply to the DER? */ /* is this the reply to the DER? */
matched = matched =
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0], dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
@@ -583,7 +584,6 @@ uint16_t MSTP_Get_Reply(
if (!matched) { if (!matched) {
return 0; return 0;
} }
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&poSharedData->PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -593,6 +593,7 @@ uint16_t MSTP_Get_Reply(
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&poSharedData->PDU_Queue, NULL);
return pdu_len; return pdu_len;
} }
+5 -5
View File
@@ -379,7 +379,7 @@ static bool MSTP_Transmit_FSM(
if (!Ringbuf_Empty(&Transmit_Queue)) { if (!Ringbuf_Empty(&Transmit_Queue)) {
/* get the packet - but don't remove it from queue */ /* get the packet - but don't remove it from queue */
pkt = (struct mstp_tx_packet *) pkt = (struct mstp_tx_packet *)
Ringbuf_Get_Front(&Transmit_Queue); Ringbuf_Peek(&Transmit_Queue);
state = MSTP_TX_STATE_SILENCE_WAIT; state = MSTP_TX_STATE_SILENCE_WAIT;
} }
break; break;
@@ -410,7 +410,7 @@ static bool MSTP_Transmit_FSM(
if (rs485_byte_sent() && rs485_frame_sent()) { if (rs485_byte_sent() && rs485_frame_sent()) {
rs485_rts_enable(false); rs485_rts_enable(false);
/* remove the packet from the queue */ /* remove the packet from the queue */
(void) Ringbuf_Pop_Front(&Transmit_Queue); (void) Ringbuf_Pop(&Transmit_Queue, NULL);
state = MSTP_TX_STATE_IDLE; state = MSTP_TX_STATE_IDLE;
} }
break; break;
@@ -873,7 +873,7 @@ static bool MSTP_Master_Node_FSM(
transition_now = true; transition_now = true;
} else { } else {
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
@@ -900,6 +900,7 @@ static bool MSTP_Master_Node_FSM(
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
break; break;
} }
(void) Ringbuf_Pop(&PDU_Queue, NULL);
} }
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
@@ -1206,7 +1207,7 @@ static bool MSTP_Master_Node_FSM(
/* BACnet Data Expecting Reply, a Test_Request, or */ /* BACnet Data Expecting Reply, a Test_Request, or */
/* a proprietary frame that expects a reply is received. */ /* a proprietary frame that expects a reply is received. */
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
pkt = (struct mstp_pdu_packet *) Ringbuf_Get_Front(&PDU_Queue); pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched =
dlmstp_compare_data_expecting_reply(&InputBuffer[0], dlmstp_compare_data_expecting_reply(&InputBuffer[0],
@@ -1224,7 +1225,6 @@ static bool MSTP_Master_Node_FSM(
/* then call MSTP_Send_Frame to transmit the reply frame */ /* then call MSTP_Send_Frame to transmit the reply frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
uint8_t frame_type; uint8_t frame_type;
pkt = (struct mstp_pdu_packet *) Ringbuf_Pop_Front(&PDU_Queue);
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
+3 -2
View File
@@ -1239,7 +1239,7 @@ static void Load_Input_Buffer(
} }
/* empty any the existing data */ /* empty any the existing data */
while (!Ringbuf_Empty(&Test_Buffer)) { while (!Ringbuf_Empty(&Test_Buffer)) {
(void) Ringbuf_Pop_Front(&Test_Buffer); (void) Ringbuf_Pop(&Test_Buffer, NULL);
} }
if (buffer) { if (buffer) {
@@ -1257,11 +1257,12 @@ void RS485_Check_UART_Data(
char *data; char *data;
if (!Ringbuf_Empty(&Test_Buffer) && mstp_port && if (!Ringbuf_Empty(&Test_Buffer) && mstp_port &&
(mstp_port->DataAvailable == false)) { (mstp_port->DataAvailable == false)) {
data = Ringbuf_Pop_Front(&Test_Buffer); data = Ringbuf_Peek(&Test_Buffer);
if (data) { if (data) {
mstp_port->DataRegister = *data; mstp_port->DataRegister = *data;
mstp_port->DataAvailable = true; mstp_port->DataAvailable = true;
} }
(void)Ringbuf_Pop(&Test_Buffer, NULL);
} }
} }
+64 -40
View File
@@ -91,7 +91,7 @@ bool Ringbuf_Empty(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
volatile uint8_t *Ringbuf_Get_Front( volatile uint8_t *Ringbuf_Peek(
RING_BUFFER const *b) RING_BUFFER const *b)
{ {
volatile uint8_t *data_element = NULL; /* return value */ volatile uint8_t *data_element = NULL; /* return value */
@@ -105,23 +105,32 @@ volatile uint8_t *Ringbuf_Get_Front(
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Gets the data from the front of the list, and removes it * DESCRIPTION: Copy the data from the front of the list, and removes it
* RETURN: pointer to the data, or NULL if nothing in the list * RETURN: true if data was copied, false if list is empty
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
volatile uint8_t *Ringbuf_Pop_Front( bool Ringbuf_Pop(
RING_BUFFER * b) RING_BUFFER * b,
uint8_t *data_element)
{ {
volatile uint8_t *data_element = NULL; bool status = false; /* return value */
volatile uint8_t *ring_data = NULL; /* used to help point ring data */
unsigned i; /* loop counter */
if (!Ringbuf_Empty(b)) { if (!Ringbuf_Empty(b)) {
data_element = b->buffer; ring_data = b->buffer;
data_element += ((b->tail % b->element_count) * b->element_size); ring_data += ((b->tail % b->element_count) * b->element_size);
if (data_element) {
for (i = 0; i < b->element_size; i++) {
data_element[i] = ring_data[i];
}
}
b->tail++; b->tail++;
status = true;
} }
return data_element; return status;
} }
/**************************************************************************** /****************************************************************************
@@ -132,7 +141,7 @@ volatile uint8_t *Ringbuf_Pop_Front(
*****************************************************************************/ *****************************************************************************/
bool Ringbuf_Put( bool Ringbuf_Put(
RING_BUFFER * b, /* ring buffer structure */ RING_BUFFER * b, /* ring buffer structure */
volatile uint8_t * data_element) uint8_t *data_element)
{ /* one element to add to the ring */ { /* one element to add to the ring */
bool status = false; /* return value */ bool status = false; /* return value */
volatile uint8_t *ring_data = NULL; /* used to help point ring data */ volatile uint8_t *ring_data = NULL; /* used to help point ring data */
@@ -154,6 +163,39 @@ bool Ringbuf_Put(
return status; return status;
} }
/****************************************************************************
* DESCRIPTION: Adds an element of data to the front of the ring buffer
* RETURN: true on succesful add, false if not added
* ALGORITHM: none
* NOTES: moves the tail on add instead of head, so this function
* can't be used if keeping producer and consumer
* as separate processes (i.e. interrupts)
*****************************************************************************/
bool Ringbuf_Put_Front(
RING_BUFFER * b, /* ring buffer structure */
uint8_t *data_element)
{ /* one element to add to the front of the ring */
bool status = false; /* return value */
volatile uint8_t *ring_data = NULL; /* used to help point ring data */
unsigned i = 0; /* loop counter */
if (b && data_element) {
/* limit the amount of elements that we accept */
if (!Ringbuf_Full(b)) {
b->tail--;
ring_data = b->buffer;
ring_data += ((b->tail % b->element_count) * b->element_size);
/* copy the data to the ring data element */
for (i = 0; i < b->element_size; i++) {
ring_data[i] = data_element[i];
}
status = true;
}
}
return status;
}
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Reserves and gets the next data portion of the buffer. * DESCRIPTION: Reserves and gets the next data portion of the buffer.
* RETURN: pointer to the data, or NULL if the list is full * RETURN: pointer to the data, or NULL if the list is full
@@ -208,14 +250,14 @@ void Ringbuf_Init(
#include "ctest.h" #include "ctest.h"
/* test the ring buffer */ /* test the ring buffer */
void testRingAroundBuffer( static void testRingAroundBuffer(
Test * pTest, Test * pTest,
RING_BUFFER * test_buffer, RING_BUFFER * test_buffer,
uint8_t * data_element, uint8_t * data_element,
unsigned element_size, unsigned element_size,
unsigned element_count) unsigned element_count)
{ {
uint8_t *test_data; volatile uint8_t *test_data;
unsigned index; unsigned index;
unsigned data_index; unsigned data_index;
unsigned count; unsigned count;
@@ -236,28 +278,21 @@ void testRingAroundBuffer(
for (count = 1; count < 4; count++) { for (count = 1; count < 4; count++) {
dummy = index * count; dummy = index * count;
test_data = Ringbuf_Get_Front(test_buffer); test_data = Ringbuf_Peek(test_buffer);
ct_test(pTest, test_data);
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == dummy);
}
}
test_data = Ringbuf_Pop_Front(test_buffer);
ct_test(pTest, test_data); ct_test(pTest, test_data);
if (test_data) { if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) { for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == dummy); ct_test(pTest, test_data[data_index] == dummy);
} }
} }
(void)Ringbuf_Pop(test_buffer, NULL);
} }
} }
ct_test(pTest, Ringbuf_Empty(test_buffer)); ct_test(pTest, Ringbuf_Empty(test_buffer));
} }
/* test the ring buffer */ /* test the ring buffer */
void testRingBuf( static void testRingBuf(
Test * pTest, Test * pTest,
uint8_t * data_store, uint8_t * data_store,
uint8_t * data_element, uint8_t * data_element,
@@ -265,7 +300,7 @@ void testRingBuf(
unsigned element_count) unsigned element_count)
{ {
RING_BUFFER test_buffer; RING_BUFFER test_buffer;
uint8_t *test_data; volatile uint8_t *test_data;
unsigned index; unsigned index;
unsigned data_index; unsigned data_index;
bool status; bool status;
@@ -280,16 +315,12 @@ void testRingBuf(
ct_test(pTest, status == true); ct_test(pTest, status == true);
ct_test(pTest, !Ringbuf_Empty(&test_buffer)); ct_test(pTest, !Ringbuf_Empty(&test_buffer));
test_data = Ringbuf_Get_Front(&test_buffer); test_data = Ringbuf_Peek(&test_buffer);
for (data_index = 0; data_index < element_size; data_index++) { for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == data_element[data_index]); ct_test(pTest, test_data[data_index] == data_element[data_index]);
} }
ct_test(pTest, !Ringbuf_Empty(&test_buffer)); ct_test(pTest, !Ringbuf_Empty(&test_buffer));
(void)Ringbuf_Pop(&test_buffer, NULL);
test_data = Ringbuf_Pop_Front(&test_buffer);
for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == data_element[data_index]);
}
ct_test(pTest, Ringbuf_Empty(&test_buffer)); ct_test(pTest, Ringbuf_Empty(&test_buffer));
/* fill to max */ /* fill to max */
@@ -313,21 +344,14 @@ void testRingBuf(
/* check buffer full */ /* check buffer full */
for (index = 0; index < element_count; index++) { for (index = 0; index < element_count; index++) {
test_data = Ringbuf_Get_Front(&test_buffer); test_data = Ringbuf_Peek(&test_buffer);
ct_test(pTest, test_data);
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == index);
}
}
test_data = Ringbuf_Pop_Front(&test_buffer);
ct_test(pTest, test_data); ct_test(pTest, test_data);
if (test_data) { if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) { for (data_index = 0; data_index < element_size; data_index++) {
ct_test(pTest, test_data[data_index] == index); ct_test(pTest, test_data[data_index] == index);
} }
} }
(void)Ringbuf_Pop(&test_buffer, NULL);
} }
ct_test(pTest, Ringbuf_Empty(&test_buffer)); ct_test(pTest, Ringbuf_Empty(&test_buffer));
@@ -365,14 +389,14 @@ void testRingBufSize32(
} }
#ifdef TEST_RINGBUF #ifdef TEST_RING_BUFFER
int main( int main(
void) void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("ringbuf", NULL); pTest = ct_create("Ring Buffer", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, testRingBufSize16); rc = ct_addTestFunction(pTest, testRingBufSize16);