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