环形队列,任意长度入队和出队
程序员文章站
2024-03-18 11:47:28
...
发个自用的串口接收缓存环形队列,实现不定长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;
}
上一篇: Java 手写单向链表