| /**
|
| *
|
| * @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;
|
| }
|
| }
|
|
|