OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4246|回复: 0

【分享】fifo数据缓存模块

[复制链接]

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
138
金钱
138
注册时间
2023-4-4
在线时间
18 小时
发表于 2023-4-13 17:49:10 | 显示全部楼层 |阅读模式
分享一份常用的数据缓存模块文件,日常在串口、can等大量数据通信中常用到

#include "Pub_Fifo.h"
#include <string.h>
#include "stdio.h"



/**
  * @brief  注册一个fifo
  * @param  pfifo: fifo结构体指针
                    pfifo_buf: fifo内存块
                    size: 长度
  * @retval none
*/
void Pub_FifoRegister(S_FIFO_INFO *psFifo, uint8_t *pu8FifoBuf, uint32_t u32Size, lockFun lock, lockFun unlock)
{
    psFifo->m_u32BufSize    = u32Size;
    psFifo->m_pu8Buf        = pu8FifoBuf;
    psFifo->m_pu8write      = psFifo->m_pu8Buf;
    psFifo->m_pu8read       = psFifo->m_pu8Buf;
    psFifo->m_u32OccupySize = 0;
    psFifo->m_lock          = lock;
    psFifo->m_unlock        = unlock;
}


/**
  * @brief  释放fifo
  * @param  pfifo: fifo结构体指针
  * @retval none
*/
void Pub_FifoRelease(S_FIFO_INFO *psFifo)
{
    psFifo->m_u32BufSize    = 0;
    psFifo->m_pu8Buf        = NULL;
    psFifo->m_pu8write      = 0;
    psFifo->m_pu8read       = 0;
    psFifo->m_u32OccupySize = 0;
    psFifo->m_lock          = NULL;
    psFifo->m_unlock        = NULL;
}

/**
  * @brief  往fifo写数据
  * @param  pfifo: fifo结构体指针
                    pbuf: 待写数据
                    size: 待写数据大小
  * @retval 实际写大小
*/
uint32_t Pub_FifoWrite(S_FIFO_INFO *psFifo, const uint8_t *pu8Buf, uint32_t u32Size)
{
    uint32_t u32WriteSize= 0;
    uint32_t u32FreeSize = 0;

    if ((0 == u32Size) || (NULL == psFifo) || (NULL == pu8Buf))
    {
        return 0;
    }

    u32FreeSize = Pub_FifoGetFreeSize(psFifo);
    if(0 == u32FreeSize)
    {
        return 0;
    }

    if(u32FreeSize < u32Size)
    {
        u32Size = u32FreeSize;
    }
    u32WriteSize = u32Size;

    if (psFifo->m_lock != NULL)
    {
        psFifo->m_lock();
    }

    while(u32WriteSize-- > 0)
    {
        *psFifo->m_pu8write++ = *pu8Buf++;
        if (psFifo->m_pu8write >= (psFifo->m_pu8Buf + psFifo->m_u32BufSize))
        {
            psFifo->m_pu8write = psFifo->m_pu8Buf;
        }
        psFifo->m_u32OccupySize++;
    }

    if (psFifo->m_unlock != NULL)
    {
       psFifo->m_unlock();
    }

    return u32Size;
}

/**
  * @brief  从fifo读数据
  * @param  pfifo: fifo结构体指针
                    pbuf: 待读数据缓存
                    size: 待读数据大小
  * @retval 实际读大小
*/
uint32_t Pub_FifoRead(S_FIFO_INFO *psFifo, uint8_t *pu8Buf, uint32_t u32Size)
{
    uint32_t u32ReadSize= 0;
    uint32_t u32OccupySize = 0;

    if ((0 == u32Size) || (NULL == psFifo) || (NULL == pu8Buf))
    {
        return 0;
    }

    u32OccupySize = Pub_FifoGetOccupySize(psFifo);
    if(0 == u32OccupySize)
    {
        return 0;
    }

    if(u32OccupySize < u32Size)
    {
        u32Size = u32OccupySize;
    }

    if (psFifo->m_lock != NULL)
    {
        psFifo->m_lock();
    }
    u32ReadSize = u32Size;
    while(u32ReadSize-- > 0)
    {
        *pu8Buf++ = *psFifo->m_pu8read++;
        if (psFifo->m_pu8read >= (psFifo->m_pu8Buf + psFifo->m_u32BufSize))
        {
            psFifo->m_pu8read = psFifo->m_pu8Buf;
        }
        psFifo->m_u32OccupySize--;
    }

    if (psFifo->m_unlock != NULL)
    {
       psFifo->m_unlock();
    }

    return u32Size;
}


/**
  * @brief  获取fifo空闲空间大小
  * @param  pfifo: fifo结构体指针
  * @retval 空闲空间大小
*/
uint32_t Pub_FifoGetFreeSize(S_FIFO_INFO *psFifo)
{
    uint32_t u32Size;

    if (NULL == psFifo)
    {
        return 0;
    }

    u32Size = psFifo->m_u32BufSize - Pub_FifoGetOccupySize(psFifo);

    return u32Size;
}


/**
  * @brief  获取fifo已用空间大小
  * @param  pfifo: fifo结构体指针
  * @retval fifo已用大小
*/
uint32_t Pub_FifoGetOccupySize(S_FIFO_INFO *psFifo)
{
    uint32_t u32Size = 0;

    if (NULL == psFifo)
    {
        return 0;
    }

    if(psFifo->m_pu8write >= psFifo->m_pu8read)
    {
        u32Size =  psFifo->m_pu8write - psFifo->m_pu8read;
    }
    else
    {
        u32Size =  psFifo->m_u32BufSize + psFifo->m_pu8write - psFifo->m_pu8read;
    }

    return  u32Size;
}









#ifndef _PUB_FIFO_H_
#define _PUB_FIFO_H_
#include <stdint.h>

typedef void (*lockFun)(void);

typedef struct
{
    uint8_t  *m_pu8Buf;               /* 缓冲区 */
    uint32_t m_u32BufSize;            /* 缓冲区大小 */
    uint32_t m_u32OccupySize;         /* 有效数据大小 */
    uint8_t  *m_pu8write;             /* 写指针 */
    uint8_t  *m_pu8read;              /* 读指针 */
    void     (*m_lock)(void);         /* 互斥上锁 */
    void     (*m_unlock)(void);       /* 互斥解锁 */
}S_FIFO_INFO;


void Pub_FifoRegister(S_FIFO_INFO *psFifo, uint8_t *pu8FifoBuf, uint32_t u32Size, lockFun lock, lockFun unlock);
void Pub_FifoRelease(S_FIFO_INFO *psFifo);
uint32_t Pub_FifoWrite(S_FIFO_INFO *psFifo, const uint8_t *pu8Buf, uint32_t u32Size);
uint32_t Pub_FifoRead(S_FIFO_INFO *psFifo, uint8_t *pu8Buf, uint32_t u32Size);
uint32_t Pub_FifoGetFreeSize(S_FIFO_INFO *psFifo);
uint32_t Pub_FifoGetOccupySize(S_FIFO_INFO *psFifo);

#endif


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 14:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表