This’s a doc recording implementation of a round buffer for serial port or others interface storage access applciations, which completely done by self. yep, you see, somehow it’s necessary and convenient in the event of continously receiving data in case the previous unread data lost.
Hmm, keep in mind the round buffer size limted the maximum data bytes user couldn’t read out in time. the storage would come from scratch again if active unread data size is over the round buffer maximum tolerrance.
definitely those code been tested over and applied to stm projects.
- First, It should be provided a round buffer info structure to tell user where the current pointer is being located in the round buffer.
- Details in the comments coudl explain what they mean to.
// Definition for common round buffer info structure
typedef struct STM_ROUN_BUFFER_INFO
{
uint8_t rbSize; // round buffer size
uint8_t activeBytes; // how many bytes to read out
uint8_t offsetToRD; // the offset where to read available bytes from buffer start.
uint8_t offsetToWR; // the offset where to store received bytes from buffer start.
uint8_t *pBuffStart; // the start address of a round buffer.
}STM_ROUND_BUFFER_INFO;
- This helper function would help provide user how many available data in the round buffer that could be read out.
//----------------------------------------------------------------------------------------------------------------------
/*!
@brief This helper function to get the active data num pending in the round buffer.
@param [in] pRxRbInfo -- The pointer to a round buffer info structure.
@param [in] pNumBytes -- The pointer to store how many active bytes pending in the round buffer.
@retval True if it's well to get pending active bytes number, False if failed.
*/
//----------------------------------------------------------------------------------------------------------------------
static bool STM_SerialPort_RoundBufferActiveData(STM_ROUND_BUFFER_INFO *pRxRbInfo, uint16_t *pNumBytes)
{
bool bRet = false;
// check round buffer info availability
if (NULL != pRxRbInfo)
{
*pNumBytes = pRxRbInfo->activeBytes;
bRet = true;
}
return (bRet);
}
- This helper function would help user data transfer between a user buffer and the round buffer that could continuously receiving as well as storage.
//----------------------------------------------------------------------------------------------------------------------
/*!
@brief This helper function to transfer the data into the round buffer from a user buffer, or from the round buffer
to a user buffer.as well as the boolean variable `isRD` would indicate this direction.
@param [in] pRxRbInfo -- The pointer to a round buffer info structure.
@param [in] numBytes -- The number bytes to transfer.
@param [in] pBuff -- The pointer to data container to transfer to/from.
Note: keep in mind always keeping the user buffer could contain the `bytesNum` bytes. Otherwise, overfolw
risk is underway.
@param [in] isRD -- The boolean to indicate read/write.
@retval True if the round buffer read/write is well. False if failed.
*/
//----------------------------------------------------------------------------------------------------------------------
static bool STM_SerialPort_RoundBufferWRRD(STM_ROUND_BUFFER_INFO *pRxRbInfo, uint16_t numBytes, void *pBuff, bool isRD)
{
bool bRet = false;
uint8_t *pBuffer = (uint8_t *)pBuff;
if (NULL != pRxRbInfo && NULL != pBuffer && numBytes < pRxRbInfo->rbSize)
{
// read out
if (isRD)
{
uint8_t buffLen = (pRxRbInfo->activeBytes < numBytes) ? (pRxRbInfo->activeBytes):(numBytes);
// in the event of overloop case
while (buffLen--)
{
// check the loaction to read is gonna reach the end of the buffer tail.
pRxRbInfo->offsetToRD %= pRxRbInfo->rbSize;
// locate where to start reading.
uint8_t *pSrcToRD = pRxRbInfo->pBuffStart + pRxRbInfo->offsetToRD;
// read out the data from round buffer.
*pBuffer++ = *pSrcToRD;
// increase the read offset.
pRxRbInfo->offsetToRD++;
// decrease the unread available num bytes.
pRxRbInfo->activeBytes--;
}
}
else // write
{
uint8_t buffLen = numBytes;
//
while (buffLen--)
{
// check the loaction to read is gonna reach the end of the buffer tail.
pRxRbInfo->offsetToWR %= pRxRbInfo->rbSize;
// locate where to start writing.
uint8_t *pSrcToWR = pRxRbInfo->pBuffStart + pRxRbInfo->offsetToWR;
// store the data into the round buffer.
*pSrcToWR = *pBuffer++;
// increase the write offset.
pRxRbInfo->offsetToWR++;
// increase the unread available num bytes.
pRxRbInfo->activeBytes++;
}
}
bRet = true;
}
else
{
MCU_OSAPI_Trace(STM_SERIAL_PORT_ERR, STM_SERIAL_PORT_ROUNDBUFFER_READ_FAILED, __LINE__);
}
return (bRet);
}