编写了简单的环形队列出入队函数。实现变长元素出入队。当队列末尾无法储存完整元素时,将元素分割成两份,分别存储在队尾队头。
此代码有更新版本,最新版本
/**
* @brief 向环形队列添加元素,一次入队一个元素
* @param pCirQueue:环形队列结构体
* @param pElements:数据源数组
* @param Elements_Size:元素大小,单位字节,最大值65535
* @return 环形队列状态码
*/
CirQueueStatusTypeDef CirQueue_Add(CirQueueTypeDef *pCirQueue, uint8_t *pElement, uint16_t paramElementSize)
{
uint32_t FirstCopySize = 0, SecondCopySize = 0; //两次传输数据的大小
uint16_t FirstCopyEmementSize = 0, SecondCopyEmementSize = 0; //两次传输元素的大小
uint32_t EndFreeSize = pCirQueue ->Size - pCirQueue ->First; //队列末尾剩余空间
uint32_t TotalCopySize = 0;
uint16_t i = 0;
FirstCopySize = paramElementSize + ELEMENT_SIZE_STORAGE_ROOM;
/*判断是否将要在末尾分割数据*/
if(EndFreeSize < FirstCopySize)
{
/*需要进行数据分割*/
FirstCopyEmementSize = EndFreeSize - ELEMENT_SIZE_STORAGE_ROOM;
SecondCopyEmementSize = paramElementSize - FirstCopyEmementSize;
FirstCopySize = EndFreeSize;
SecondCopySize = SecondCopyEmementSize + ELEMENT_SIZE_STORAGE_ROOM;
}
else
FirstCopyEmementSize = paramElementSize;
/*检查是否将越界*/
TotalCopySize = FirstCopySize + SecondCopySize;
if(pCirQueue ->ElementsSize + TotalCopySize > pCirQueue ->Size)
return CirQueue_ERROR;
/*复制数据*/
pCirQueue ->pBuff[pCirQueue ->First++] = (uint8_t)(FirstCopyEmementSize); //储存元素大小
pCirQueue ->pBuff[pCirQueue ->First++] = (uint8_t)(((FirstCopyEmementSize) & 0xF0) >> 8);
for(i = 0; i < FirstCopyEmementSize; ++i)
{
pCirQueue ->pBuff[pCirQueue ->First++] = *pElement++;
}
/*头地址到末尾回0*/
if(pCirQueue ->First >= pCirQueue ->Size)
{
pCirQueue ->First = 0;
}
/*处理末尾剩下的数据*/
if(SecondCopySize)
{
//储存元素大小
pCirQueue ->pBuff[pCirQueue ->First++] = (uint8_t)(SecondCopyEmementSize);
pCirQueue ->pBuff[pCirQueue ->First++] = (uint8_t)(((SecondCopyEmementSize) & 0xF0) >> 8);
for(i = 0; i < SecondCopyEmementSize; ++i)
{
pCirQueue ->pBuff[pCirQueue ->First++] = *pElement++;
}
}
/*更新环形队列现存元素大小*/
pCirQueue ->ElementsSize += TotalCopySize;
return CirQueue_OK;
}
/**
* @brief 环形队列出队,一次出队一个元素
* @param pCirQueue:环形队列结构体
* @param pElement:出队元素存放地址
* @return 环形队列状态码
*/
CirQueueStatusTypeDef CirQueue_Remove(CirQueueTypeDef *pCirQueue, uint8_t *pElement)
{
uint16_t RemoveElementSize = 0, RemoveElementSize_L = 0, RemoveElementSize_H = 0, i = 0; //元素大小,元素大小低高位,i
/*无数据时报错*/
if(pCirQueue ->First == pCirQueue ->Last)
{
return CirQueue_ERROR;
}
/*计算元素大小*/
RemoveElementSize_L = pCirQueue ->pBuff[pCirQueue ->Last++]; //计算元素大小低位
RemoveElementSize_H = pCirQueue ->pBuff[pCirQueue ->Last++] << 8; //计算元素大小高位
RemoveElementSize = RemoveElementSize_L + RemoveElementSize_H;
/*复制数据*/
for(i = 0; i < RemoveElementSize; ++i)
{
*pElement++ = pCirQueue ->pBuff[pCirQueue ->Last++];
}
/*尾地址到末尾回0*/
if(pCirQueue ->Last >= pCirQueue ->Size)
{
pCirQueue ->Last = 0;
}
/*更新环形队列现存元素大小*/
pCirQueue ->ElementsSize -= RemoveElementSize + ELEMENT_SIZE_STORAGE_ROOM;
return CirQueue_OK;
}