烧脑作品-ST的FIFO写法

笔记:

CircularQueue循环队列 等价于FIFO


#define MIN(X,Y) (((X) > (Y)) ? (Y) : (X))
#define MOD(X,Y) (((X) >= (Y)) ? ((X)-(Y)) : (X))
//#define MOD(X,Y) (X % Y)
宏定义 比求模更简单 因为程序会控制住 比如
curBuffPosition = MOD(curBuffPosition, q->queueMaxSize); 后者是一个常量比如3 前面的数比如是5的话就话变成2 不会超越后者2倍

typedef struct {
	uint8_t* 	qBuff;	        	/* queue buffer, , provided by init fct */
   	uint32_t 	queueMaxSize;   	/* size of the queue, provided by init fct (in bytes)*/
   	uint16_t 	elementSize;    	/* -1 variable. If variable elemenet size the size is stored in the 4 first of the queue element */
   	uint32_t 	first;          	/* position of first element */
   	uint32_t 	last;           	/* position of last element */
   	uint32_t  	byteCount;     	/* number of bytes in the queue */
   	uint32_t 	elementCount;   	/* number of element in the queue */
} queue_t;

为什么有个 elementCount 等 分析

分配内存给FIFO
* @param  elementSize: Size of an element in the queue. if =0, the queue will manage variable sizze elements
分析 也就是elementSize标识这个FIFO内部管理的结构体单元 如果是0就是一个一个的U8这样没有组织的 如果是4就表示一个一个size是4的结构体单元
int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize)
{
	q->qBuff = queueBuffer;
	q->first = 0;
	q->last = 0; //queueSize-1;
	q->byteCount = 0;
	q->elementCount = 0;
	q->queueMaxSize = queueSize;
	q->elementSize = elementSize;
	return 0;
}

问题 它只有写 没有读啊?他这个模块怎么用的?
他ADD的时候返回的那个指针有用到吗?

 

 

模块代码:

	/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
* File Name        : queue.h
* Author             : Frederic MACCOTTA
* Version            : 
* Date                : 
* Description      : Circurlar FIFO management
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __QUEUE_H
#define __QUEUE_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>

/* Exported define -----------------------------------------------------------*/
#if !defined(TRUE)
#define TRUE  (1)
#endif

#if !defined(FALSE)
#define FALSE (0)
#endif

/* Exported types ------------------------------------------------------------*/
typedef struct {
	uint8_t* 	qBuff;	        	/* queue buffer, , provided by init fct */
   	uint32_t 	queueMaxSize;   	/* size of the queue, provided by init fct (in bytes)*/
   	uint16_t 	elementSize;    	/* -1 variable. If variable elemenet size the size is stored in the 4 first of the queue element */
   	uint32_t 	first;          	/* position of first element */
   	uint32_t 	last;           	/* position of last element */
   	uint32_t  	byteCount;     	/* number of bytes in the queue */
   	uint32_t 	elementCount;   	/* number of element in the queue */
} queue_t;

/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize);
uint8_t* CircularQueue_Add(queue_t *q, uint8_t* x, uint16_t elementSize, uint32_t nbElements);
uint8_t* CircularQueue_Remove(queue_t *q, uint16_t* elementSize);
uint8_t* CircularQueue_Sense(queue_t *q, uint16_t* elementSize);
int CircularQueue_Empty(queue_t *q);
int CircularQueue_NbElement(queue_t *q);

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
#endif











/******************** (C) COPYRIGHT 2013 STMicroelectronics ********************
* File Name         : queue.c
* Author              : Frederic MACCOTTA 
* Version            : 
* Date                 : 
* Description       : Circurlar FIFO queue management code 
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/


/* #include "StdAfx.h"  // specific vc++ */
#include <string.h>

#include "queue_buffer.h"

/* Private define ------------------------------------------------------------*/
/* Private typedef -------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define MOD(X,Y) (((X) >= (Y)) ? ((X)-(Y)) : (X))
#define MIN(X,Y) (((X) > (Y)) ? (Y) : (X))

//#define MOD(X,Y) (X % Y)

/* Private variables ---------------------------------------------------------*/
/* Global variables ----------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

/**
  * @brief   Initilaiilze queue strcuture .
  * @note   This function is used to initialize the global queue strcuture.  
  * @param  q: pointer on queue strcture to be initialised 
  * @param  queueBuffer: pointer on Queue Buffer
  * @param  queueSize:  Size of Queue Buffer
  * @param  elementSize: Size of an element in the queue. if =0, the queue will manage variable sizze elements
  * @retval   always 0
  */

int CircularQueue_Init(queue_t *q, uint8_t* queueBuffer, uint32_t queueSize, uint16_t elementSize)
{
	q->qBuff = queueBuffer;
	q->first = 0;
	q->last = 0; //queueSize-1;
	q->byteCount = 0;
	q->elementCount = 0;
	q->queueMaxSize = queueSize;
	q->elementSize = elementSize;
	return 0;
}

/**
  * @brief   Add  element to the queue .
  * @note   This function is used to add one or more  element(s) to the Circular Queue .  
  * @param  q: pointer on queue structure   to be handled
  * @param  X; pointer on element(s) to be added 
  * @param  elementSize:  Size of element to be added to the queue. Only used if the queue manage variable size elements
  * @param  nbElements:  number of elements in the in buffer pointed by x
  * //@retval   number of elements in the queue, -1 if the element to be added do not fit in the queue (too big)
  * @retval  pointer on element last element just added to the queue, NULL if the element to be added do not fit in the queue (too big)
  */
uint8_t* CircularQueue_Add(queue_t *q, uint8_t* x, uint16_t elementSize, uint32_t nbElements)
{
	// TODO: Assert sur elementSize
	// TODO: Assert sur x

	uint8_t* ptr = NULL;	                 /* fct return ptr to the element freshly added, if no room fct return NULL */
	uint16_t curElementSize = 0;             /* the size of the element currently  stored at q->last position */
	uint8_t  elemSizeStorageRoom  = 0;
	uint32_t curBuffPosition;                /* the current position in the queue buffer */
	uint32_t i;          	                 /* loop counter */
	uint32_t NbBytesToCopy =0 ;

	elemSizeStorageRoom  = (q->elementSize == 0) ? 2 : 0;

	/* retrieve the size of last element sored: the value stored at the beginning of the queue element if element size is variable otherwise take it from fixed element Size member */
	if (q->byteCount) 
	{
		curElementSize = (q->elementSize == 0) ? q->qBuff[q->last] + ((q->qBuff[MOD((q->last+1), q->queueMaxSize)])<<8) + 2 : q->elementSize;
	}
	/* if queue element have fixed size , reset the elementSize arg with fixed element size value */
	if (q->elementSize > 0)               
	{
		elementSize = q->elementSize;
	}

  	/* Store now the elements */
	if (elementSize && (q->byteCount + ((elementSize + elemSizeStorageRoom )*nbElements)) <= q->queueMaxSize) 
	{ 
		for (i=0; i < nbElements; i++) 
    	{
			q->last = MOD ((q->last + curElementSize),q->queueMaxSize);
			curBuffPosition = q->last;

			/* store the element  */
			/* store fisrt the element size if element size is varaible */
			if (q->elementSize == 0) 
      		{
				q->qBuff[curBuffPosition++]= elementSize & 0xFF;
        		curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
 				q->qBuff[curBuffPosition++]= (elementSize & 0xFF00) >> 8 ;
        		curBuffPosition = MOD(curBuffPosition, q->queueMaxSize);
			}		 

      
			/* Copy First Par from current position up to the end  of the buffer queue (or before if enough room) if any) */
			NbBytesToCopy = MIN((q->queueMaxSize-curBuffPosition),elementSize);
			if (NbBytesToCopy)
			{
				memcpy(&q->qBuff[curBuffPosition],&x[i*elementSize],NbBytesToCopy);
			}
			curBuffPosition = MOD((curBuffPosition+NbBytesToCopy),q->queueMaxSize);
				
			/* Copy second Part to beginning of buffer queue */
			if (NbBytesToCopy != elementSize)
			{
				memcpy(&q->qBuff[curBuffPosition],&x[(i*elementSize)+NbBytesToCopy],elementSize-NbBytesToCopy);
			}
			curElementSize = (elementSize) + elemSizeStorageRoom ;
		}
               
		q->byteCount+=((elementSize + elemSizeStorageRoom )*nbElements);
		q->elementCount+=nbElements;
		ptr = q->qBuff + (MOD((q->last+elemSizeStorageRoom ),q->queueMaxSize));
	}

	return ptr;
}


/**
  * @brief  Remove element from  the queue.
  * @note   This function is used to remove and element from  the Circular Queue .  
  * @param  q: pointer on queue structure  to be handled
  * @param  elementSize: Pointer to return Size of element to be removed  
  * @retval Pointer on removed element. NULL if queue was empty
  */
uint8_t* CircularQueue_Remove(queue_t *q, uint16_t* elementSize)
{
	uint8_t  elemSizeStorageRoom = 0;
	uint8_t* ptr= NULL;
	
	elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
	*elementSize = 0;
	if (q->byteCount > 0) 
  	{
    	*elementSize = (q->elementSize == 0) ? q->qBuff[q->first]+ ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
		ptr = q->qBuff + (MOD((q->first+elemSizeStorageRoom ),q->queueMaxSize));
		q->byteCount -= (*elementSize + elemSizeStorageRoom) ;
		if (q->byteCount > 0)
		{
		  q->first = MOD((q->first + *elementSize + elemSizeStorageRoom ), q->queueMaxSize);
		}
	}
	
  	return ptr;
}



/**
  * @brief  "Sense" first element of the quque, without removing it.
  * @note   This function is used to return a pointer on the first element of the queue without removing it.  
  * @param  q: pointer on queue structure  to be handled
  * @param  elementSize:  Pointer to return Size of element to be removed  
  * @retval Pointer on sensed element. NULL if queue was empty
  */
uint8_t* CircularQueue_Sense(queue_t *q, uint16_t* elementSize)
{
	//int ret = -1;
	uint8_t  elemSizeStorageRoom = 0;
	uint8_t* x= NULL;
	
	elemSizeStorageRoom = (q->elementSize == 0) ? 2 : 0;
	*elementSize = 0;
	if (q->byteCount > 0) 
  	{
		*elementSize = (q->elementSize == 0) ? q->qBuff[q->first]+ ((q->qBuff[MOD((q->first+1), q->queueMaxSize)])<<8) : q->elementSize;
		x = q->qBuff + (MOD((q->first+elemSizeStorageRoom), q->queueMaxSize));
	}
	
  	return x;
}

/**
  * @brief   Check if queue is empty.
  * @note    This function is used to to check if the queue is empty.  
  * @param  q: pointer on queue structure  to be handled
  * @retval   TRUE (1) if the queue is empyu otherwise FALSE (0) 
  */
int CircularQueue_Empty(queue_t *q)
{
  int ret=FALSE;
  if (q->byteCount <= 0) 
  {
    ret=TRUE;
  } 
  return ret;
}

int CircularQueue_NbElement(queue_t *q)
{
  return q->elementCount;
}







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值