环形buffer实现

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值