blob: 6e56633ec307f7f34a790c2c8dd72cc1f7e20eef [file] [log] [blame]
/**
*
* @file ringbuf.c
* @brief
* This file is part of tools.
* ring buffer
*
* @details
* @author Tools Team.
* @email
* @copyright Copyright (C) 2013 Sanechips Technology Co., Ltd.
* @warning
* @date 2019/02/02
* @version 1.1
* @pre
* @post
*
* @par
* Change History :
* ---------------------------------------------------------------------------
* date version author description
* ---------------------------------------------------------------------------
* 2013/01/21 1.0 lu.xieji Create file
* 2019/02/02 1.1 jiang.fenglin ÐÞ¸Ä×¢ÊÍ·½Ê½Îªdoxygen
* ---------------------------------------------------------------------------
*
*
*/
#include "ringbuf.h"
#include <linux/uaccess.h>
#define SYMBOL_VALUE ZCAT_IPC_ESTABLISHED
/**
* @brief Åжϻº³åÇøÊÇ·ñÓÐЧ
* @param[in] ringBuf »·Ðλº³å
* @return ÊÇ·µ»ØTRUE,·ñ·µ»ØFALSE
* @note
* @see
*/
BOOL IsRingBufferValid(T_RINGBUFFER *ringBuf)
{
return (ringBuf != NULL && ringBuf->symbol == SYMBOL_VALUE);
}
/**
* @brief ´´½¨ÐèÒªµÄ»º³åÇø,²¢ÇÒÖ¸¶¨±ê¼ÇλµÄÖµ
* Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
* @param[in] buf »º³åÇøµØÖ·
* @param[in] bufSize »º³åÇø´óС
* @param[in] bufSize ±ê¼Çλ
* @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
* @note
* @see
*/
T_RINGBUFFER *CreateRingBufferWithSymbol(UINT8 *buf, UINT32 bufSize, UINT32 symbol)
{
T_RINGBUFFER *ringBuf = NULL;
if (bufSize <= sizeof(T_RINGBUFFER))
{
return NULL;
}
if (buf == NULL)
{
//ringBuf = (T_RINGBUFFER *)kmalloc(ALIGNED_SIZE(bufSize, 3), GFP_KERNEL);
//if (ringBuf == NULL)
{
return NULL;
}
}
else
{
ringBuf = (T_RINGBUFFER *)buf;
}
ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
ringBuf->readPoint = 0;
ringBuf->writePoint = 0;
ringBuf->symbol = symbol;
return ringBuf;
}
/**
* @brief ´´½¨ÐèÒªµÄ»º³åÇø
* Èç¹ûbuf²»ÎªNULL£¬ÔòÔÚÖ¸¶¨µØÖ·´´½¨»º³åÇø£»·ñÔò£¬ÉêÇëÒ»¿éÄÚ´æ×÷Ϊ»º³åÇø
* @param[in] buf »º³åÇøµØÖ·
* @param[in] bufSize »º³åÇø´óС
* @return ³É¹¦·µ»ØÖ¸Ïò»º³åÇø½á¹¹ÌåµÄÖ¸Õ룬·ñÔò·µ»ØNULL
* @note
* @see
*/
T_RINGBUFFER *CreateRingBuffer(UINT8 *buf, UINT32 bufSize)
{
T_RINGBUFFER *ringBuf = NULL;
if (bufSize <= sizeof(T_RINGBUFFER))
{
return NULL;
}
if (buf == NULL)
{
//ringBuf = (T_RINGBUFFER *)kmalloc(ALIGNED_SIZE(bufSize, 3), GFP_KERNEL);
//if (ringBuf == NULL)
{
return NULL;
}
}
else
{
ringBuf = (T_RINGBUFFER *)buf;
}
ringBuf->capacity = bufSize - sizeof(T_RINGBUFFER);
ringBuf->readPoint = 0;
ringBuf->writePoint = 0;
ringBuf->symbol = SYMBOL_VALUE;
return ringBuf;
}
/**
* @brief ½«Êý¾ÝдÈë»·Ðλº³å
* @param[in] ringBuf »·Ðλº³åÖ¸Õë
* @param[in] buf Êý¾Ý»º´æÖ¸Õë
* @param[in] len Êý¾Ý³¤¶È
* @param[in] flags Êý¾Ý»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
* @return ·µ»ØÐ´ÈëµÄʵ¼Ê³¤¶È
* @note
* @see
*/
UINT32 WriteRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags)
{
UINT32 writeLen = 0;
UINT32 writePoint = ringBuf->writePoint;
UINT32 readPoint = ringBuf->readPoint;
/* Èë²ÎÅÐ¶Ï */
if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
{
return 0;
}
if( writePoint >= ringBuf->capacity || readPoint >= ringBuf->capacity )
{
return 0;
}
if (writePoint >= readPoint)
{
if (ringBuf->capacity - writePoint > len)
{
if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, len); }
else { memcpy(ringBuf->buf + writePoint, buf, len); }
ringBuf->writePoint += len;
writeLen = len;
}
else if ((ringBuf->capacity - writePoint + readPoint - 1) >= len)
{
UINT32 copyLen = ringBuf->capacity - writePoint;
if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, copyLen); }
else { memcpy(ringBuf->buf + writePoint, buf, copyLen); }
copyLen = len - copyLen;
if (copyLen > 0)
{
if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf, buf + (len - copyLen), copyLen); }
else { memcpy(ringBuf->buf, buf + (len - copyLen), copyLen); }
}
ringBuf->writePoint = copyLen;
writeLen = len;
}
}
else
{
if (readPoint - writePoint - 1 >= len)
{
if (ZCAT_MEM_TYPE_USER == flags) { copy_from_user(ringBuf->buf + writePoint, buf, len); }
else { memcpy(ringBuf->buf + writePoint, buf, len); }
ringBuf->writePoint += len;
writeLen = len;
}
}
return writeLen;
}
/**
* @brief ¶Áȡһ¶Î»·Ðλº³åÇøµÄÊý¾Ýµ½Ä¿±ê»º´æ
* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
* @param[in] buf Ä¿±ê»º´æÖ¸Õë
* @param[in] len Ä¿±ê»º´æ³¤¶È
* @param[in] flags Ä¿±ê»º´æÄÚ´æÀàÐÍ£º0:ÄÚºË̬,1:Óû§Ì¬
* @return ·µ»Ø¶ÁÈ¡³¤¶È
* @note
* @see
*/
UINT32 ReadRingBuffer(T_RINGBUFFER *ringBuf, UINT8 *buf, UINT32 len, UINT32 flags)
{
UINT32 readLen = 0;
UINT32 writePoint = ringBuf->writePoint;
UINT32 readPoint = ringBuf->readPoint;
/* ²ÎÊý¼ì²é */
if (!IsRingBufferValid(ringBuf) || buf == NULL || len == 0)
{
return 0;
}
if( writePoint >= ringBuf->capacity || readPoint >= ringBuf->capacity )
{
return 0;
}
if (writePoint > readPoint)
{
readLen = writePoint - readPoint;
readLen = (readLen >= len) ? len : readLen;
if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, readLen); }
else { memcpy(buf, ringBuf->buf + readPoint, readLen); }
ringBuf->readPoint += readLen;
}
else if (writePoint < readPoint)
{
readLen = ringBuf->capacity - readPoint + writePoint;
readLen = (readLen >= len) ? len : readLen;
if (ringBuf->capacity - readPoint >= readLen)
{
if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, readLen); }
else { memcpy(buf, ringBuf->buf + readPoint, readLen); }
ringBuf->readPoint = (ringBuf->readPoint + readLen) % ringBuf->capacity;
}
else
{
UINT32 copyLen = ringBuf->capacity - readPoint;
if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf, ringBuf->buf + readPoint, copyLen); }
else { memcpy(buf, ringBuf->buf + readPoint, copyLen); }
copyLen = readLen - copyLen;
if (ZCAT_MEM_TYPE_USER == flags) { copy_to_user(buf + (readLen - copyLen), ringBuf->buf, copyLen); }
else { memcpy(buf + (readLen - copyLen), ringBuf->buf, copyLen);}
ringBuf->readPoint = copyLen;
}
}
return readLen;
}
/**
* @brief »ñÈ¡µ±Ç°Ring BufferÖпÕÏÐÇøµÄ´óС
* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
* @return ·µ»Ø×Ö½ÚÊý
* @note
* @see
*/
UINT32 GetRingBufferSize(T_RINGBUFFER *ringBuf)
{
UINT32 writePoint = ringBuf->writePoint;
UINT32 readPoint = ringBuf->readPoint;
UINT32 bufSize = 0;
if (!IsRingBufferValid(ringBuf))
{
return 0;
}
if (writePoint > readPoint)
{
bufSize = writePoint - readPoint;
}
else if (writePoint < readPoint)
{
bufSize = ringBuf->capacity - readPoint + writePoint;
}
return bufSize;
}
/**
* @brief ½«»º³åÇøÖÿÕ
* @param[in] ringBuf »·Ðλº³åÇøÖ¸Õë
* @return void
* @note
* @see
*/
VOID EmptyRingBuffer(T_RINGBUFFER *ringBuf)
{
if (IsRingBufferValid(ringBuf))
{
ringBuf->readPoint = ringBuf->writePoint;
}
}