环形队列,任意长度入队和出队

发个自用的串口接收缓存环形队列,实现不定长Buffer的写入和读出

typedef struct
{
//    uint16_t u16RingQLock;//
    uint16_t u16RingHead;//数据从本位读出
    uint16_t u16RingTail;//数据从本位写入
    uint16_t u16Size;//未读数据长度
    uint8_t u8DataBuffer[RING_QUEUE_SIZE];
}tsRingQueue;

uint8_t u8RingQueueinit(tsRingQueue *ptsRingQ)
{
    ptsRingQ->u16RingHead = 0;
    ptsRingQ->u16RingTail = 0;
    ptsRingQ->u16Size = 0;
    memset(ptsRingQ->u8DataBuffer,0,RING_QUEUE_SIZE);
    return SUCCESS;
}
/*
*入队
*pu8Buffer 缓存数据 
*u16Len 要写入的缓存数据长度
*/
uint8_t u8RingQueuePush(tsRingQueue *ptsRingQ, uint8_t *pu8Buffer,uint16_t u16Len)
{
    if(ptsRingQ->u16Size + u16Len > RING_QUEUE_SIZE)
    {
        LOG("缓存空间不足,环形队列将初始化\n\r");
        u8RingQueueinit(ptsRingQ);
        return 1;
    }
    
    if(ptsRingQ->u16RingHead <= ptsRingQ->u16RingTail) 
    {
        if(ptsRingQ->u16RingTail + u16Len <= (RING_QUEUE_SIZE))//位置足够
        {
            memcpy(&ptsRingQ->u8DataBuffer[ptsRingQ->u16RingTail] , pu8Buffer , u16Len);
        }
        else//需要分两段存储
        {
            memcpy(&ptsRingQ->u8DataBuffer[ptsRingQ->u16RingTail] , pu8Buffer , RING_QUEUE_SIZE - ptsRingQ->u16RingTail);//第一段存到buffer尾部
            pu8Buffer += RING_QUEUE_SIZE - ptsRingQ->u16RingTail;
            memcpy(&ptsRingQ->u8DataBuffer[0] , pu8Buffer , u16Len -(RING_QUEUE_SIZE - ptsRingQ->u16RingTail));//复制第二段到buffer头部
        }
    }
    else
    {
        memcpy(&ptsRingQ->u8DataBuffer[ptsRingQ->u16RingTail] , pu8Buffer , u16Len);
    }

    ptsRingQ->u16RingTail = (ptsRingQ->u16RingTail + u16Len) % RING_QUEUE_SIZE;//防止溢出
    ptsRingQ->u16Size += u16Len;
    return 0;
}

/*
*出队
*pu8Buffer 读取数据缓存 
*u16Len 要读取的数据长度
*/
uint8_t u8RingQueuePop(tsRingQueue *ptsRingQ, uint8_t *pu8Buffer,uint16_t u16Len)
{
    if(u16Len > ptsRingQ->u16Size)
    {
        LOG("读取数据长度(%d)超长,未读数据长度%d",u16Len , ptsRingQ->u16Size);
        return 2;
    }
    if((ptsRingQ->u16RingHead >= RING_QUEUE_SIZE) || (ptsRingQ->u16RingTail >= RING_QUEUE_SIZE))
    {
        while(1)
        {
            LOG("/***u8RingQueuePop环形队列位置错误***/\n\r");
        }
    }

    if(ptsRingQ->u16RingHead < ptsRingQ->u16RingTail) 
    {
        memcpy(pu8Buffer,&ptsRingQ->u8DataBuffer[ptsRingQ->u16RingHead],u16Len);
    }
    else
    {
        if(ptsRingQ->u16RingHead + u16Len <= (RING_QUEUE_SIZE))
        {
            memcpy(pu8Buffer , &ptsRingQ->u8DataBuffer[ptsRingQ->u16RingHead] , u16Len);
        }
        else
        {
            memcpy(pu8Buffer , &ptsRingQ->u8DataBuffer[ptsRingQ->u16RingHead] , RING_QUEUE_SIZE - ptsRingQ->u16RingHead);//复制第一段
            pu8Buffer += RING_QUEUE_SIZE - ptsRingQ->u16RingHead;
            memcpy(pu8Buffer , &ptsRingQ->u8DataBuffer[0] , u16Len - (RING_QUEUE_SIZE - ptsRingQ->u16RingHead));//复制第二段
        }
    }
    
    ptsRingQ->u16RingHead = (ptsRingQ->u16RingHead + u16Len) % RING_QUEUE_SIZE;//防止溢出
    ptsRingQ->u16Size -= u16Len;
    
    return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值