69、FIFO缓存发送数据(先入先出)

本文件用于设备数据收发缓冲使用,本fifo采用申请2片内存区,交替使用,写0时1读,写1时0读,避免同时使用相同内存块
fifo区域采用头尾相连的方式循环覆盖,分别记录读和写的位置,相等则数据为空,否则说明有数据
此方法的弊端为,当FIFO输入数据速度大于输出,则会引起数据丢失,若只是短时间数据量大则可以通过分配较大空间避免此问题
内存区使用动态分配
fifo_driver.h

#ifndef _fifo_driver_H_
#define _fifo_driver_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "stdint.h"
#include "stdio.h"
#define dFIFO_LOG(...) printf(__VA_ARGS__) //日志输出

typedef struct
{
    uint8_t state;//fifo状态:0--不可用,!0--可用
    uint32_t size;//fifo分配的缓冲大小
    uint32_t read[2];//读取位置
    uint32_t write[2];//写入位置
    uint8_t id;//当前使用的缓冲区
    uint8_t *pbuf[2];//缓冲区
    void (*SendData)(uint8_t *pData,uint32_t size);//FIFI输出数据函数
}fifo_StructDef;//数据缓冲句柄

int fifo_init(fifo_StructDef *p,uint32_t size,void (*SendData)(uint8_t *pData,uint32_t size));
void fifo_DeInit(fifo_StructDef *p);
void fifo_clear(fifo_StructDef *p);
int fifo_in(fifo_StructDef *p,uint8_t *pdata,uint32_t size);
int fifo_out(fifo_StructDef *p);

#ifdef __cplusplus
}
#endif
#endif

fifo_driver.c

/**********************************************************************
*file:FIFO先入先出队列驱动文件
*author:残梦
*versions:V1.0
*date:2024.3.22
*note:
本文件用于设备数据收发缓冲使用,本fifo采用申请2片内存区,交替使用,写0时1读,写1时0读,避免同时使用相同内存块
fifo区域采用头尾相连的方式循环覆盖,分别记录读和写的位置,相等则数据为空,否则说明有数据
此方法的弊端为,当FIFO输入数据速度大于输出,则会引起数据丢失,若只是短时间数据量大则可以通过分配较大空间避免此问题
使用方法:
#include "fifo_driver.h"
static fifo_StructDef fifo;
void SendData(uint8_t *pData,uint32_t size)
{
    //实现自己的底层发送数据
    //所有输入fifo的数据都通过此函数实际发送输出
}
void main(void)
{
    uint8_t data = 0xFF;

    if(fifo(&fifo,1024,SendData) < 0){printf("初始化失败\n");return}

    for(uint32_t i = 0;i < 1000;i++)
    {
        fifo_in(&fifo,&data,1);//向fifo输入数据
        if(i%1024 == 0)fifo_out(&fifo);//发送数据
    }

    fifo_DeInit(&fifo);
}


**********************************************************************/
#include "fifo_driver.h"
#include "string.h"
#include "stdlib.h"

/****************************************
@function:fifo初始化资源
@param:p--fifo句柄
    size--分配fifo大小;注意实际消耗内存等于size*2字节
    SendData--数据发送函数
@return:
    0:成功
    -1:参数错误
    -2:分配内存失败
@note:
****************************************/
int fifo_init(fifo_StructDef *p,uint32_t size,void (*SendData)(uint8_t *pData,uint32_t size))
{
    if((p == NULL) || (size < 1) || (SendData == NULL))return -1;
    p->state = 0;
    p->pbuf[0] = (uint8_t *)malloc(size);
    p->pbuf[1] = (uint8_t *)malloc(size);
	if ((p->pbuf[0] == NULL) || (p->pbuf[1] == NULL))
	{
        fifo_DeInit(p);
		dFIFO_LOG("Error[%s-line:%d]:memory allocation failure\n", __func__, __LINE__);
		return -2;
	}
    p->size = size;
    p->read[0] = p->read[1] = 0;
    p->write[0] = p->write[1] = 0;
    p->id = 0;
    p->SendData = SendData;
    p->state = 1;
    return 0;
}

/****************************************
@function:fifo资源销毁
@param:p--fifo句柄
@return:void
@note:
****************************************/
void fifo_DeInit(fifo_StructDef *p)
{
    if(p == NULL)return;
    p->state = 0;
    if(p->pbuf[0] != NULL)free(p->pbuf[0]);
    p->pbuf[0] = NULL;
    if(p->pbuf[1] != NULL)free(p->pbuf[1]);
    p->pbuf[1] = NULL;
    p->size = 0;
    p->read[0] = p->read[1] = 0;
    p->write[0] = p->write[1] = 0;
    p->id = 0;
    p->SendData = NULL;
}

/****************************************
@function:fifo清空
@param:p--fifo句柄
@return:void
@note:
****************************************/
void fifo_clear(fifo_StructDef *p)
{
    if(p == NULL)return;
    p->state = 0;
    p->id = 0;    
    p->read[0] = p->read[1] = 0;
    p->write[0] = p->write[1] = 0;
    p->state = 1;
}

/****************************************
@function:fifo数据输入
@param:
    p--fifo句柄
    pdata--数据
    size--字节数
@return:
    0:成功
    -1:参数错误
    -2:写入失败
@note:
****************************************/
int fifo_in(fifo_StructDef *p,uint8_t *pData,uint32_t size)
{
    uint32_t num = 0,pos = 0;
    uint8_t id = 0;

    if((pData == NULL) || (size == 0) || (p == NULL))return -1;
    if(p->state == 0)return -2;

    id = p->id;
    while(pos < size)
    {
        num = (size > (p->size - p->write[id]))?(p->size - p->write[id]):(size-pos);
        memcpy(&(p->pbuf[id][p->write[id]]),(pData + pos),num);
        p->write[id] += num;
        pos += num;
        if(p->write[id] >= p->size)p->write[id] = 0;
    }
    return 0;
}

/****************************************
@function:fifo数据输出
@param:p--fifo句柄
@return:void
@note:
    0:输出成功
    -1:参数错误
    -2:fifo状态不可用
    -3:fifo空
****************************************/
int fifo_out(fifo_StructDef *p)
{
    uint8_t id = 0;
    uint32_t len = 0;

    if(p == NULL)return -1;
    if(p->state == 0)return -2;
    if(p->read[p->id] == p->write[p->id])return -3;
    id = p->id;
    p->id = id?0:1;
    if(p->read[id] < p->write[id])
    {
        len = p->write[id] - p->read[id];
        p->SendData(&(p->pbuf[id][p->read[id]]),len);
        p->read[id] += len;
    }
    else if(p->read[id] > p->write[id])
    {
        len = p->size - p->read[id];
        p->SendData(&(p->pbuf[id][p->read[id]]),len);
        len = p->write[id];
        p->SendData(&(p->pbuf[id][0]),len);
        p->read[id] = len;
    }
    return 0;
}

使用方法:

#include "fifo_driver.h"
static fifo_StructDef fifo;
void SendData(uint8_t *pData,uint32_t size)
{
    //实现自己的底层发送数据
    //所有输入fifo的数据都通过此函数实际发送输出
}
void main(void)
{
    uint8_t data = 0xFF;

    if(fifo(&fifo,1024,SendData) < 0){printf("初始化失败\n");return}

    for(uint32_t i = 0;i < 1000;i++)
    {
        fifo_in(&fifo,&data,1);//向fifo输入数据
        if(i%1024 == 0)fifo_out(&fifo);//发送数据
    }

    fifo_DeInit(&fifo);
}

文件下载:
链接:https://pan.baidu.com/s/1-u8w19RiyPeCtVQjX8hzgw
提取码:zxo1

相关推荐

  1. 69FIFO缓存发送数据

    2024-03-23 12:38:02       45 阅读
  2. 在Go中理解栈和先进原则

    2024-03-23 12:38:02       59 阅读
  3. python --创建固定字符串长度,先进

    2024-03-23 12:38:02       32 阅读
  4. 序+中序还原二叉树【数据结构】

    2024-03-23 12:38:02       65 阅读
  5. 2024-03-23 12:38:02       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-23 12:38:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-23 12:38:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-23 12:38:02       82 阅读
  4. Python语言-面向对象

    2024-03-23 12:38:02       91 阅读

热门阅读

  1. ubuntu生成 设置 core文件

    2024-03-23 12:38:02       38 阅读
  2. Vue 常见面试题(一)

    2024-03-23 12:38:02       39 阅读
  3. 0x01_实验课leetcode

    2024-03-23 12:38:02       41 阅读
  4. [leetcode] 21. 合并两个有序链表

    2024-03-23 12:38:02       45 阅读
  5. 数学系的数字信号处理:傅立叶变换

    2024-03-23 12:38:02       39 阅读
  6. android gdb 调试

    2024-03-23 12:38:02       47 阅读
  7. Android_NDK调试

    2024-03-23 12:38:02       42 阅读
  8. 简单函数_学分绩点

    2024-03-23 12:38:02       41 阅读
  9. LeetCode232:用栈实现队列

    2024-03-23 12:38:02       36 阅读
  10. 复试专业前沿问题问答合集9——密码学

    2024-03-23 12:38:02       38 阅读