⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can_buffer.c

📁 can initialization for coldfire microcontorllers
💻 C
字号:
/************************************************************************
*
*  Freescale Semicondactor
*  ALL RIGHTS RESERVED
*  (c) Copyright 2004Freescale Semiconductor
*
*************************************************************************
*
*  FILE NAME: can_buffer.c
*
*  PURPOSE:
*
*  AUTHOR(s): Igor Byeda
*
*************************************************************************/

#include "can_buffer.h"

/************************************************************************
 * NAME: rb_Create
 *
 * DESCRIPTION: create and initialize RingBuffer object
 *
 * PARAMETER(s):
 *	[in] bufSizeWanted -- maximum size of the ring buffer [in packets]
 *
 * RETURN: Pointer to the new RingBuffer structure
 ************************************************************************/
rb_obj_t * rb_Create(uint32 bufSizeWanted)
{
	rb_obj_t * rb = NULL;
	
	// trying to create internal structure
	rb = (rb_obj_t *) malloc(sizeof(rb_obj_t));
	
	if( rb )
	{
		// trying to create buffer itself
		rb->pBuf = (can_Message_t *) malloc( bufSizeWanted*CAN_MSG_LEN );
		if( rb->pBuf )
		{
			rb->nBufSize = bufSizeWanted;
		    // init with zeros
			rb->pRD = 0;
			rb->pWR = 0;
			rb->tmp = 0;
			memset( rb->pBuf, 0x00, (rb->nBufSize*CAN_MSG_LEN) );
				
		} else
			// u-ups... 
			rb = NULL;
	}
		
	return (rb);
}

/************************************************************************
 * NAME: rb_Destroy
 *
 * DESCRIPTION: Destroy Ring Buffer by freeing memory and resetting
 *		       structure variables to zero state
 *
 * PARAMETER(s):
 *	[in/out] rb -- pointer to the RingBuffer object (structure)
 *
 * RETURN: --
 ************************************************************************/
void rb_Destroy(rb_obj_t * rb)
{
	// killing buffer itself
	if ( rb->pBuf ) free(rb->pBuf);

	rb->pBuf = NULL;
	rb->nBufSize = 0;
	rb->pRD = 0;
	rb->pWR = 0;
	
	// and object structure at the end
	if ( rb ) free(rb);
	rb = NULL;
}


/************************************************************************
 * NAME: rb_get_FreeSpace
 *
 * DESCRIPTION: Returns the amount of data [in units] available for
 *		        WRiting in buffer
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object (structure)
 *
 * RETURN: Amount of data [in units] available for WRiting
 ************************************************************************/
uint32 rb_get_FreeSpace(rb_obj_t * rb)
{
	if( rb->pBuf )
	{
		if( rb->pRD == rb->pWR )
			return (rb->nBufSize);
			
		if( rb->pWR < rb->pRD )
			return (rb->pRD - rb->pWR);

		if( rb->pWR > rb->pRD )
			return ((rb->nBufSize - rb->pWR) + rb->pRD);
	}
	
	return (0);
}

/************************************************************************
 * NAME: rb_get_DataToReadSize
 *
 * DESCRIPTION: Returns the amount of data (in units) available for
 *		        ReaDing from the buffer
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object (structure)
 *
 * RETURN: Amount of data [in bytes] available for ReaDing
 ************************************************************************/
uint32 rb_get_DataToReadSize(rb_obj_t * rb)
{
	if( rb->pBuf )
	{
		if( rb->pRD == rb->pWR )
			return (0);
			
		if( rb->pRD < rb->pWR )
			return (rb->pWR - rb->pRD);

		if( rb->pRD > rb->pWR )
			return ((rb->nBufSize - rb->pRD) + rb->pWR);
	}
	
	return (0);
}


/************************************************************************
 * NAME: rb_data_Write
 *
 * DESCRIPTION: write data into RingBuffer
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object
 *	[in] pExtBuf -- Pointer to the external buffer to WR
 *	[in] nExtLen -- Size of the ext. data to WR [in units]
 *
 * RETURN: Amount of data were really written in
 ************************************************************************/
uint32 rb_data_Write(rb_obj_t * rb, can_Message_t * pExtBuf, uint32 nExtLen)
{
	// real buffer size is (nBufSize-1) for safety reason -> 
	// sign '<' instead of '<=' 
	if( nExtLen < rb_get_FreeSpace(rb) )
	{
		// easy case, no wrapping
		if( rb->pWR + nExtLen < rb->nBufSize )
		{
			memcpy( &(rb->pBuf[rb->pWR]), pExtBuf, nExtLen*CAN_MSG_LEN );
			rb->pWR += nExtLen;
		}
		// harder case we need to wrap around
		else 
		{
			rb->tmp = rb->nBufSize - rb->pWR; // First Part size
				
			memcpy( &(rb->pBuf[rb->pWR]), pExtBuf, (rb->tmp)*CAN_MSG_LEN );
			memcpy( &(rb->pBuf[0]), &(rb->pBuf[rb->tmp]), (nExtLen - rb->tmp)*CAN_MSG_LEN );

			rb->pWR = (nExtLen - rb->tmp);
		}
		return (nExtLen);
	}
	
	return (0);
}

/************************************************************************
 * NAME: rb_data_Read
 *
 * DESCRIPTION: read data from RingBuffer
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object
 *	[in/out] pExtBuf -- Pointer to the external buffer to store data
 *	[in] nExtLen -- Size of the data to read out [in bytes]
 *
 * RETURN: Amount of data were really extracted
 ************************************************************************/
uint32 rb_data_Read(rb_obj_t * rb, can_Message_t * pExtBuf, uint32 nExtLen)
{

	if( nExtLen <= rb_get_DataToReadSize(rb) )
	{
		// easy case, no wrapping
		if( (rb->pRD + nExtLen) < rb->nBufSize )
		{
			memcpy( pExtBuf, &(rb->pBuf[rb->pRD]), nExtLen*CAN_MSG_LEN );
			rb->pRD += nExtLen;
		}
		// harder case, buffer wraps around
		else 
		{
			rb->tmp = rb->nBufSize - rb->pRD;	  // First Part size

			memcpy( pExtBuf, &(rb->pBuf[rb->pRD]), (rb->tmp)*CAN_MSG_LEN );
			memcpy( &(pExtBuf[rb->tmp]), &(rb->pBuf[0]), (nExtLen - rb->tmp)*CAN_MSG_LEN );

			rb->pRD = (nExtLen - rb->tmp);
		}
		return (nExtLen);
	}
	return (0);
}


/************************************************************************
 * NAME: rb_data_WriteOneVirtual
 *
 * DESCRIPTION: get pointer to the ONE element to virtually write in
 *				(just fill structure fields). pWR will increase by 1.
 *				USE IT VERY CAREFULLY!!!
 *				This function was developed to use only in interrupts. 
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object
 *
 * RETURN: pointer to the array element to fill up
 ************************************************************************/
can_Message_t * rb_data_WriteOneVirtual(rb_obj_t * rb)
{
	
	if( rb_get_FreeSpace(rb) > 1)
	{
		rb->tmp2 = rb->pWR;
		// easy case, no wrapping
		if( rb->pWR + 1 < rb->nBufSize )
		{
			rb->pWR += 1;
		}
		// case we need to wrap around
		else 
		{
			rb->pWR = 0;
		}
		return( &(rb->pBuf[ rb->tmp2 ]) );
	}
	
	return (NULL);
}

/************************************************************************
 * NAME: rb_data_WriteOneBack
 *
 * DESCRIPTION: place pWR pointer one position back
 *				USE IT VERY, VERY CAREFULLY!!!
 *				This function was developed to use only in interrupts. 
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object
 *
 * RETURN: 1 - if ok, 0 - in any other case
 ************************************************************************/
uint32 rb_data_WriteOneBack(rb_obj_t * rb)
{
	
	if( rb_get_FreeSpace(rb) < rb->nBufSize)
	{
		rb->tmp = rb->pWR;
		// easy case, no wrapping
		if( rb->tmp > 0 )
		{
			rb->tmp -= 1;
		}
		// case we need to wrap around
		else 
		{
			rb->tmp = rb->nBufSize - 1;
		}
		
		// simple checking for safety reason
		if (rb->tmp != rb->tmp2) return (FALSE);
		
		rb->pWR = rb->tmp;
		return (TRUE);
	}
	
	return (FALSE);
}


/************************************************************************
 * NAME: rb_data_ReadOneVirtual
 *
 * DESCRIPTION: get pointer to the ONE element to virtually read it
 *				(just read structure fields by pointer). pRD will increase by 1.
 *				USE IT VERY CAREFULLY!!!
 *				This function was developed to use only in interrupts. 
 *
 * PARAMETER(s): 
 *	[in] rb -- pointer to the RingBuffer object
 *
 * RETURN: pointer to the array element to read out
 ************************************************************************/
can_Message_t * rb_data_ReadOneVirtual(rb_obj_t * rb)
{

	if( rb_get_DataToReadSize(rb) >= 1 )
	{
		rb->tmp = rb->pRD;
		// easy case, no wrapping
		if( rb->pRD + 1 < rb->nBufSize )
		{
			rb->pRD += 1;
		}
		// harder case, buffer wraps around
		else 
		{
			rb->pRD = 0;
		}
		return ( &(rb->pBuf[ rb->tmp ]) );
	}
	return (NULL);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -