195 lines
5.5 KiB
C
195 lines
5.5 KiB
C
|
/*
|
||
|
* Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
|
||
|
* exclusively with CVA's microcontroller products. This file can be freely
|
||
|
* distributed within development tools that are supporting such microcontroller
|
||
|
* products.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||
|
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||
|
* CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
|
||
|
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||
|
*/
|
||
|
|
||
|
#ifndef _RINGBUFFER_H_
|
||
|
#define _RINGBUFFER_H_
|
||
|
|
||
|
/*! \brief Contains public interface to various functions related
|
||
|
* to the ring buffer template
|
||
|
*/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* the includes
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include <stdint.h>
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* the defines
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* the typedefs
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*! \brief RingBuffer prototype definition
|
||
|
*/
|
||
|
typedef struct _RingBufferType_
|
||
|
{
|
||
|
void *pBuffer; /*!< The actual buffer holder */
|
||
|
int32_t readIndex; /*!< The current index for the read */
|
||
|
int32_t writeIndex; /*!< The current index for the write */
|
||
|
int32_t usedNum; /*!< The number of used elements */
|
||
|
int32_t totalNum; /*!< The number of total elements */
|
||
|
} RingBufferType;
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* the globals
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* the function prototypes
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*! \brief Initializes the ringbuffer instance
|
||
|
*
|
||
|
* This function initializes a ringbuffer instance
|
||
|
*
|
||
|
* \param[in] obj : pointer to RingBuffer instance
|
||
|
* \param[in] pBuffer : the actual buffer holder
|
||
|
* \param[in] size : the size of actual buffer holder
|
||
|
*/
|
||
|
static inline void RingBuffer_Init(RingBufferType *obj, void *pBuffer, uint32_t size)
|
||
|
{
|
||
|
obj->pBuffer = pBuffer;
|
||
|
obj->readIndex = 0;
|
||
|
obj->writeIndex = 0;
|
||
|
obj->usedNum = 0;
|
||
|
obj->totalNum = size;
|
||
|
}
|
||
|
|
||
|
/*! \brief Puts an element to the ringbuffer.
|
||
|
*
|
||
|
* This function puts an element to the ringbuffer.
|
||
|
*
|
||
|
* \param[in] obj : pointer to RingBuffer instance
|
||
|
* \param[in] pElem : pointer to the element to push into the buffer
|
||
|
* \param[in] size : the size of the element in bytes
|
||
|
* \return the result of the put operation
|
||
|
* true : success
|
||
|
* false : failed because the buffer is full
|
||
|
*/
|
||
|
static inline bool RingBuffer_Put(RingBufferType *obj, const void *pElem, uint32_t size)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
unsigned char *src;
|
||
|
unsigned char *dest;
|
||
|
|
||
|
/* Check if the buffer is full */
|
||
|
if(obj->usedNum >= obj->totalNum)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* Copy the element */
|
||
|
src = (unsigned char *)pElem;
|
||
|
dest = (unsigned char *)obj->pBuffer + (obj->writeIndex * size);
|
||
|
for(i = 0; i < size; i++)
|
||
|
{
|
||
|
*dest++ = *src++;
|
||
|
}
|
||
|
|
||
|
/* Move the index */
|
||
|
obj->writeIndex++;
|
||
|
if(obj->writeIndex >= obj->totalNum)
|
||
|
{
|
||
|
obj->writeIndex = 0;
|
||
|
}
|
||
|
obj->usedNum++;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*! \brief Gets an element from the ringbuffer.
|
||
|
*
|
||
|
* This function gets an element from the ringbuffer.
|
||
|
*
|
||
|
* \param[in] obj : pointer to RingBuffer instance
|
||
|
* \param[in] pElem : pointer to the element to get from the buffer
|
||
|
* \param[in] size : the size of the element in bytes
|
||
|
* \return the result of the put operation
|
||
|
* true : success
|
||
|
* false : failed because the buffer is empty
|
||
|
*/
|
||
|
static inline bool RingBuffer_Get(RingBufferType *obj, void *pElem, uint32_t size)
|
||
|
{
|
||
|
uint32_t i = 0;
|
||
|
unsigned char *src;
|
||
|
unsigned char *dest;
|
||
|
|
||
|
/* Check if the buffer is empty */
|
||
|
if(obj->usedNum <= 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/* Copy the element */
|
||
|
dest = (unsigned char *)pElem;
|
||
|
src = (unsigned char *)obj->pBuffer + (obj->readIndex * size);
|
||
|
for(i = 0; i < size; i++)
|
||
|
{
|
||
|
*dest++ = *src++;
|
||
|
}
|
||
|
|
||
|
/* Move the index */
|
||
|
obj->readIndex++;
|
||
|
if(obj->readIndex >= obj->totalNum)
|
||
|
{
|
||
|
obj->readIndex = 0;
|
||
|
}
|
||
|
obj->usedNum--;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/*! \brief See if the ringbuffer is full.
|
||
|
*
|
||
|
* This function gets if the ringbuffer is full
|
||
|
*
|
||
|
* \param[in] obj : pointer to RingBuffer instance
|
||
|
* \return whether the buffer is full
|
||
|
* true : the buffer is full
|
||
|
* false : the buffer is not full
|
||
|
*/
|
||
|
static inline bool RingBuffer_IsFull(const RingBufferType *obj)
|
||
|
{
|
||
|
return (obj->usedNum >= obj->totalNum);
|
||
|
}
|
||
|
|
||
|
/*! \brief See if the ringbuffer is empty.
|
||
|
*
|
||
|
* This function gets if the ringbuffer is empty
|
||
|
*
|
||
|
* \param[in] obj : pointer to RingBuffer instance
|
||
|
* \return whether the buffer is empty
|
||
|
* true : the buffer is empty
|
||
|
* false : the buffer is not empty
|
||
|
*/
|
||
|
static inline bool RingBuffer_IsEmpty(const RingBufferType *obj)
|
||
|
{
|
||
|
return (obj->usedNum <= 0);
|
||
|
}
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif /* extern "C" */
|
||
|
|
||
|
#endif /* _RINGBUFFER_H_ */
|