|
/****************************************************************************************** * Copyright(c) 2018, Mark Xu WorK Studio. All rights reserved. * * File Name : Xc_CircleQueue.c * * Brief : about the circle queue application * * Author : Mark Xu * * Date : 2018年10月12日 * * Version: V1.0 * * Remark : None * *----------------------------------------------------------------------------------------------------------------------------------------------- * History : * * 1) Author : xx xx * * Modify Date : xx xx xx * * Modify contents : xx xx xx xx xx ******************************************************************************************/ #define XC_CIRCLEQUEUE_IMPLEMENT #include <stdio.h> #include <string.h> #include <stdint.h> #include <stdlib.h> #include "Xc_CircleQueue.h" /************************************************************************************ * 函数名称 : Circle_Queue_Init * * 函数描述 : Initial the queue * * 入口参数 : *rbuf - the queue * * *array - the data buffer * * len - the depth of the queue * * 出口参数 : TRUE - initial successful * * 函数备注 : None *************************************************************************************/ uint8_t Circle_Queue_Init(RingBuf_T *rbuf, uint8_t *array, uint16_t len) { if((len<2)||(array == NULL)) return FALSE; rbuf->Buf = array; rbuf->Depth = len; rbuf->fillCnt = 0; rbuf->Head = 0; rbuf->Tail = 0; return TRUE; } /************************************************************************************ * 函数名称 : RingBuf_Clear * * 函数描述 : clear the queue * * 入口参数 : *rbuf - the queue * * 出口参数 : None * * 函数备注 : None *************************************************************************************/ void RingBuf_Clear(RingBuf_T *rbuf) { rbuf->fillCnt = 0; rbuf->Head = 0; rbuf->Tail = 0; } /************************************************************************************ * 函数名称 : RingBuf_Chk_Full * * 函数描述 : clear the queue * * 入口参数 : *rbuf - the queue * * 出口参数 : true - full false - not full * * 函数备注 : judging condition - (tail+1) % buf_size_max == head *************************************************************************************/ uint16_t RingBuf_Chk_Full(RingBuf_T *rbuf) { return((rbuf->Tail + 1)%rbuf->Depth == rbuf->Head); } /************************************************************************************ * 函数名称 : RingBuf_Chk_Empty * * 函数描述 : check the queue empty or not * * 入口参数 : *rbuf - the queue * * 出口参数 : true - empty false - not empty * * 函数备注 : judging condition - tail == head *************************************************************************************/ uint16_t RingBuf_Chk_Empty(RingBuf_T *rbuf) { return (rbuf->Tail == rbuf->Head); } /************************************************************************************ * 函数名称 : RingBuf_Write_Bytes * * 函数描述 : push the data to queue * * 入口参数 : *rbuf - the queue * * *pValue - the value to be push * * size - the bytes of the value buffer * * 出口参数 : true - success false - fail * * 函数备注 : none *************************************************************************************/ uint16_t RingBuf_Write_Bytes(RingBuf_T *rbuf,uint8_t *pValue, uint16_t size) { uint16_t len = 0; uint16_t ringBuf_bw = rbuf->Tail ; uint16_t ringBuf_len = rbuf->Depth; uint8_t *ringBuf_source = rbuf->Buf; if(RingBuf_Chk_Full(rbuf)) return 0; if((ringBuf_bw + size) <= ringBuf_len) { memcpy((uint8_t *)&ringBuf_source[ringBuf_bw],pValue,size); } else { len = ringBuf_len - ringBuf_bw; memcpy(ringBuf_source+ringBuf_bw,pValue,len); memcpy(ringBuf_source,pValue+ringBuf_bw,(size-len)); } // 计算Tail 的位置 rbuf->Tail = (rbuf->Tail + size) % rbuf->Depth; rbuf->fillCnt += size; return size; } /************************************************************************************ * 函数名称 : RingBuf_Write_Bytes * * 函数描述 : Read the data from the queue * * 入口参数 : *rbuf - the queue * * *pValue - the data buffer to store the read data * * size - the bytes of the value buffer * * 出口参数 : true - success false - fail * * 函数备注 : none *************************************************************************************/ uint16_t RingBuf_Read_Bytes(RingBuf_T *rbuf,uint8_t *pValue,uint16_t size) { uint16_t len = 0; uint16_t ringBuf_br = rbuf->Head; uint16_t ringBuf_len = rbuf->Depth; char *ringBuf_src = rbuf->Buf; // 如果为空则返回0 if(RingBuf_Chk_Empty(rbuf)) return 0; // 当tial等于head时,说明队列为空 if(rbuf->fillCnt == 0) { // printf("Buffer is empty,nothing to be read \r\n"); return 0; } // 只读取有效数据 if(size > rbuf->fillCnt) size = rbuf->fillCnt; if((ringBuf_br + size) <= ringBuf_len) { memcpy(pValue,ringBuf_src + ringBuf_br,size); } else { len = ringBuf_len - ringBuf_br; memcpy(pValue,ringBuf_src + ringBuf_br,len); memcpy(pValue+len, ringBuf_src,(size-len)); } rbuf->Head = (rbuf->Head + size) % rbuf->Depth; rbuf->fillCnt -= size; return size; } |
/****************************************************************************************** * Copyright(c) 2018, Mark Xu Work Studio. All rights reserved. * * 文件名称 : Xc_Queue.h * * 文件描述 : 关于队列模块的一些声明与定义 * * 文件作者 : Mark Xu * * 创建日期 : 2018年10月10日 * * 当前版本 : V1.0 * * 文件备注 : None * *---------------------------------------------------------------------------------------- * 修改记录 : * * 1) 修改人员 : xx xx * * 修改日期 : xx xx xx * * 修改内容 : xx xx xx xx xx ******************************************************************************************/ #ifndef __XC_CIRCLEQUEUE_H__ #define __XC_CIRCLEQUEUE_H__ //------------------------------------------------------------------------------------------------------------------------------------------------ // Precompile //----------------------------------------------------------------------------------------------------------------------------------------------- #ifdef XC_CIRCLEQUEUE_IMPLEMENT #define CIRCLEQUEUE_EXTERN #else #define CIRCLEQUEUE_EXTERN extern #endif /* XC_CIRCLEQUEUE_IMPLEMENT */ #include "stdio.h" #include "stdlib.h" #include "stdint.h" #include "string.h" //------------------------------------------------------------------------------------------------------------------------------------------------ // 数据类型声明 //------------------------------------------------------------------------------------------------------------------------------------------------ /* 说明: 1. fillCnt 是计数队列中的元素个数 2. 当向队列中插入元素时,fillCnt 要增加 3. 当从队列中读取元素时,fillCnt 要减少 4. 当fillCnt为0时说明队列中没有元素,不可读取 */ #pragma pack(4) typedef struct RingBuf_t{ uint8_t *Buf; /* 指向队列数组的指针 */ uint16_t Depth; /* 可存储的元素的个数 */ uint16_t Head; /* 队头,也是读取的指针 */ uint16_t Tail; /* 队尾,也是写的指针 */ uint16_t fillCnt; /* 元素计数 */ }RingBuf_T; #pragma pack() // 指针形式 typedef RingBuf_T* RingBuf_Tp; //------------------------------------------------------------------------------------------------------------------------------------------------ // 函数声明 //------------------------------------------------------------------------------------------------------------------------------------------------ CIRCLEQUEUE_EXTERN uint8_t Circle_Queue_Init(RingBuf_T *rbuf, uint8_t *array, uint16_t len); CIRCLEQUEUE_EXTERN void RingBuf_Clear(RingBuf_T *rbuf); CIRCLEQUEUE_EXTERN uint16_t RingBuf_Chk_Full(RingBuf_T *rbuf); CIRCLEQUEUE_EXTERN uint16_t RingBuf_Chk_Empty(RingBuf_T *rbuf); CIRCLEQUEUE_EXTERN uint16_t RingBuf_Write_Bytes(RingBuf_T *rbuf,uint8_t *pValue, uint16_t size); CIRCLEQUEUE_EXTERN uint16_t RingBuf_Read_Bytes(RingBuf_T *rbuf,uint8_t *pValue,uint16_t size); #endif /* __XC_CIRCLEQUEUE_H__ */ |