增加操作系统RT_THREAD支持
在操作系统进行FIFO操作时,删除了FIFO类型,相关的繁忙标志位及备份缓冲区和回调函数功能。
在使用RT-THREAD时,中断接收数据均 存在缓冲区,数据得以保存。使用互斥量代替了原有的busy标志位,线程通过等待信号量的方式来实现对FIFO元素的互斥操作
增加宏定义SYS_RTT来实现驱动在有误操作系统情况下的切换
#ifndef _FUNC_FIFO_H_
#define _FUNC_FIFO_H_
#define SYS_RTT
/*************************************************************************************************************************
* 头文件
**************************************************************************************************************************/
#ifdef SYS_RTT
#include <rtthread.h>
#else
#endif
#include "config.h"
/*************************************************************************************************************************
* 宏定义
**************************************************************************************************************************/
#define VER_FIFO 200
/*************************************************************************************************************************
* 枚举
**************************************************************************************************************************/
typedef enum
{
FIFO_EOK=0,
FIFO_EINIT,
FIFO_ENUM,
FIFO_EFAILED,
}FifoErr;
#ifdef SYS_RTT
#else
typedef enum
{
FIFO_TYPE_INT_PUSH,
FIFO_TYPE_INT_PULL,
}FifoType;
#endif
/*************************************************************************************************************************
* 结构体
**************************************************************************************************************************/
typedef struct FifoTypeDef
{
#ifdef SYS_RTT
#else
//构成链表。
struct FifoTypeDef* Next;
#endif
//FIFO节本元素。
volatile INT16U Depth; //FIFO的深度
volatile INT16U CntUsed; //使用了的元素个数
INT8U* Push; //写入的位置
INT8U* Pull; //读取的位置。
INT8U* Buf; //数据缓冲区
//FIFO计算元素
INT8U* EndPos; //缓冲区的结尾处指针。
#ifdef SYS_RTT
#else
//FIFO类型
FifoType Type;
#endif
//标志位。 写 读
INT8U InitFlag; // 主颜色初始化 所有FIFO相关函数。
#ifdef SYS_RTT
rt_mutex_t Mutex;
#else
volatile INT8U BusyFlag; // 主函数 中断
volatile INT8U IntFlag; // 中断 定时器中断
//中断写入时的备份缓冲区。
volatile INT16U BackCount;
INT8U* BackBuf;
//定时器中断回调函数
void (*func_timmer)();
#endif
}FifoTypeDef;
/*************************************************************************************************************************
* 函数声明
**************************************************************************************************************************/
extern void func_fifo_Init();
#ifdef SYS_RTT
extern FifoTypeDef* func_fifo_Create(INT16U depth);
#else
extern FifoTypeDef* func_fifo_Create(INT16U depth, FifoType type);
#endif
extern FifoErr func_fifo_Push(FifoTypeDef* fifo, INT16U num, INT8U* data);
#ifdef SYS_RTT
#else
extern FifoErr func_fifo_PushInt(FifoTypeDef* fifo, INT16U num, INT8U* data);
#endif
extern FifoErr func_fifo_Pull(FifoTypeDef* fifo, INT16U num, INT8U* data);
extern FifoErr func_fifo_PullPart(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len);
#ifdef SYS_RTT
#else
extern FifoErr func_fifo_PullPartInt(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len);
#endif
extern FifoErr func_fifo_Copy(FifoTypeDef* fifo , INT16U ind, INT16U len, INT8U* data);
extern FifoErr func_fifo_Delete(FifoTypeDef* fifo , INT16U num);
extern FifoErr func_fifo_Cmp(FifoTypeDef* fifo, INT16U ind, INT16U len, INT8U* data);
extern FifoErr func_fifo_FindDelete(FifoTypeDef* fifo, INT16U len, INT8U* data);
extern FifoErr func_fifo_Find(FifoTypeDef* fifo, INT16U ind, INT8U* data, INT16U len, INT16U* pos);
extern INT16U func_fifo_GetUsed(FifoTypeDef* fifo);
#ifdef SYS_RTT
#else
extern void func_fifo_TimerCallBack();
#endif
#endif
/* 说明:
* FIFO用来实现如下功能
* 1)中断数据的接收,主函数的数据访问解析(串口接收 其他带中断的外设进行数据采集接收)
* 2)主函数向FIFO中写入数据,中断中进行数据处理(串口发送)
*
* 整个驱动文件采用busy标志位来解决中断和主函数间对于全局变量的访问问题。
* busy仅在主函数中可进行写操作,中断中仅进行busy读取的操作。
*
* FIFO写入数据分为两种模式
* 1)普通写入(主函数写入)
* 设置繁忙标志位,直接进行写入。
* 2)中断写入
* 中断写入时,busy不繁忙,直接写入到FIFO中,写入前需要判断备份区域是否存在数据,若存在则将数据先行写入
* 中断写入时,busy繁忙,将数据写入到备份区域。(中断数据若不进行处理,则数据丢失)。
* 当数据被写入到备份区域时可通过如下两种模式将备份区域数据写到fifo中。
* 1),下次中断时,不繁忙,在写入data数据前会处理备份区域数据。
* 2),设定定时器,定时遍历FIFO链表,当检查到FIFO不在中断中且不繁忙时,会将数据写入到fifo中。
*
* 定时器实现的功能
* 1)对于中断接收类型的FIFO,进行备份区域数据的写入,需要注意一下两个条件
* 不在中断中
* 不繁忙
* 2)对中断发送类型的FIFO,进行FIFO使用量查询,当查询到有数据时,通过回调函数进行数据处理。
*
* 使用说明:
* 1)首先进行FIFO的初始化,使用func_fifo_create实现。
* 2)针对创建FIFO类型的不同,通过如下几个函数进行FIFO数据的写入操作。
* func_fifo_Push(FifoTypeDef* fifo, INT16U num, INT8U* data);
* 主函数写入
* func_fifo_PushInt(FifoTypeDef* fifo, INT16U num, INT8U* data);
* 中断写入
* 3)针对不同类型的FIFO,使用如下函数进行FIFO数据操作。
* func_fifo_Pull(FifoTypeDef* fifo, INT16U num, INT8U* data);
* 主函数调用,若fifo内容不足返回错误。
* func_fifo_PullPart(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len);
* 主函数调用,若fifo内容不足,通过参数len返回实际pull的数值。
* func_fifo_PullPartInt(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len);
* 中断调用,若fifo内容不足,通过参数len返回实际pull的数值。
* 4)以下函数实现主函数中对FIFO内部内容的查找,判断和删除的工作。
* func_fifo_Copy(FifoTypeDef* fifo , INT16U ind, INT16U len, INT8U* data);
* 复制FIFO中的数据,不对FIFO元素进行操作。
* func_fifo_Delete(FifoTypeDef* fifo , INT16U num);
* 删除FIFO的元素
* func_fifo_Cmp(FifoTypeDef* fifo, INT16U ind, INT16U len, INT8U* data);
* 比较FIFOA中的元素
* func_fifo_FindDelete(FifoTypeDef* fifo, INT16U len, INT8U* data);
* 查找FIFO中元素,对不符合内容进行删除
* func_fifo_Find(FifoTypeDef* fifo, INT16U ind, INT8U* data, INT16U len, INT16U* pos);
* 查找FIFO中元素,通过pos返回找到的位置
*
*
*************************************************************************************************************************
* @his
* ver:V1.0.0.0
* author:WXL
* date:2021.09.03
* @his
* ver:V2.0.0.0
* author:WXL
* date:2021.09.10
* note:
* 使用信号量代替busy标志,适配RTT
* */
/*************************************************************************************************************************
* 头文件
**************************************************************************************************************************/
#include "func_fifo.h"
/*************************************************************************************************************************
* 宏定义
**************************************************************************************************************************/
#define FIFO_INIT_CHECK(fifo) (fifo->InitFlag == 1? 1:0)
#ifdef SYS_RTT
#define FIFO_MALLOC rt_malloc
#define FIFO_FREE rt_free
#define FIFO_MEMCPY rt_memcpy
#define FIFO_MEMSET rt_memset
#define FIFO_MEMCMP rt_memcmp
#else
#define FIFO_MALLOC malloc
#define FIFO_FREE free
#define FIFO_MEMCPY memcpy
#define FIFO_MEMSET memset
#define FIFO_MEMCMP memcmp
#endif
/*************************************************************************************************************************
* 全局变量
**************************************************************************************************************************/
#ifdef SYS_RTT
#else
FifoTypeDef* FifoChain = NULL;
#endif
/*************************************************************************************************************************
* 局部函数
**************************************************************************************************************************/
#ifdef SYS_RTT
static inline void FIFO_SET_BUSY(FifoTypeDef* fifo)
{
rt_mutex_take(fifo->Mutex, RT_WAITING_FOREVER);
}
static inline void FIFO_RESET_BUSY(FifoTypeDef* fifo)
{
rt_mutex_release(fifo->Mutex);
}
#else
static inline void FIFO_SET_BUSY(FifoTypeDef* fifo)
{
fifo->BusyFlag = 1;
}
static inline void FIFO_RESET_BUSY(FifoTypeDef* fifo)
{
fifo->BusyFlag = 0;
}
static inline INT8U FIFO_GET_BUSY(FifoTypeDef* fifo)
{
return fifo->BusyFlag;
}
static inline void FIFO_SET_INT(FifoTypeDef* fifo)
{
fifo->IntFlag = 1;
}
static inline void FIFO_RESET_INT(FifoTypeDef* fifo)
{
fifo->IntFlag = 0;
}
static inline INT8U FIFO_GET_INT(FifoTypeDef* fifo)
{
return fifo->IntFlag;
}
#endif
static inline void func_fifo_PushOffset(FifoTypeDef* fifo,INT16U offset)
{
fifo->Push += offset;
if(fifo->Push > fifo->EndPos)
{
fifo->Push = fifo->Push - fifo->Depth;
}
}
static inline void func_fifo_PullOffset(FifoTypeDef* fifo,INT16U offset)
{
fifo->Pull += offset;
if(fifo->Pull > fifo->EndPos)
{
fifo->Pull = fifo->Pull - fifo->Depth;
}
}
static inline INT16U func_fifo_CalPoint2end(FifoTypeDef* fifo, INT8U* point)
{
return fifo->EndPos - point + 1;
}
/**
***************************************************
* @brief func_fifo_CmpLower
* @note 比较FIFO重数据的底层函数,不进行标志位操作。
* @param fifo
* 指向待操作的FIFO,
* ind
* 从FIFO的pull后面的第ind个开始
* len
* 比较的长度为len
* data
* 比较的数据
* timeout
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
static FifoErr func_fifo_CmpLower(FifoTypeDef* fifo, const INT16U ind, const INT16U len, const INT8U* data)
{
//判断FIFO中是否有足够的数量进行比较。
if(ind + len > fifo->CntUsed)
{
return FIFO_ENUM;
}
//上面的判断可以保证开始比较的位置+len不会超过FIFO的容量。
INT8U* point = fifo->Pull + ind;
if(point > fifo->EndPos)
point = point - fifo->Depth;
INT16U len2end = func_fifo_CalPoint2end(fifo,point);
if(len2end >= len)
{
if(FIFO_MEMCMP(data,point,len) == 0)
{
return FIFO_EOK;
}
else
{
return FIFO_EFAILED;
}
}
else
{
if(FIFO_MEMCMP(data,point,len2end) == 0 && FIFO_MEMCMP(data+len2end,fifo->Buf,len-len2end) == 0 )
{
return FIFO_EOK;
}
else
{
return FIFO_EFAILED;
}
}
}
/**
***************************************************
* @brief func_fifo_DeleteLower
* @note 删除FIFO数据的底层函数,不进行标志位操作。
* @param fifo
* 指向待操作的FIFO,
* num
* 删除的元素个数
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_DeleteLower(FifoTypeDef* fifo, INT16U num)
{
//删除的数据大于FIFO已使用数据。
if(num > fifo->CntUsed)
{
return FIFO_ENUM;
}
//开始删除数据
INT16U len2end = func_fifo_CalPoint2end(fifo,fifo->Pull);
if(len2end >= num)
{
FIFO_MEMSET(fifo->Pull , 0 , num);
}
else
{
FIFO_MEMSET(fifo->Pull , 0 , len2end);
FIFO_MEMSET(fifo->Buf , 0 , num - len2end);
}
fifo->CntUsed -= num;
func_fifo_PullOffset(fifo,num);
return FIFO_EOK;
}
#ifdef SYS_RTT
/**
***************************************************
* @brief func_fifo_Push2Fifo
* @note 将数据写入到FIFO缓冲区中,仅在FIFO不繁忙时调用,
* 1、首先将Back数据写入到FIFO中。
* 2、将待写入数据写入到FIFO中。
* @param fifo
* 指向待操作的FIFO,
* num
* 删除的元素个数
* data
* 指向写入数据
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
static void func_fifo_Push2Fifo(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
INT16U offset = 0;
INT16U len2end = func_fifo_CalPoint2end(fifo,fifo->Push);
INT16U num2push = 0;
INT8U* srcpos = 0;
INT8U* despos = 0;
INT16U len = 0;
//back数据和data数据之和大于depth,存在back和data丢弃数据的情况。
if(num > fifo->Depth)
{
num2push = fifo->Depth;
offset = num -fifo->Depth;
}
else
{
num2push = num;
}
//到FIFO结尾可以容纳写入的数据,说明不存在覆盖情况。将back和带写入数据写入即可。
if(len2end >= num2push)
{
//写入data
srcpos = data;
despos = fifo->Push;
len = num2push;
FIFO_MEMCPY(despos, srcpos, len);
}
//存在回头写的情况
else
{
//写入到队尾。
srcpos = data + offset;
despos = fifo->Push;
len = len2end;
FIFO_MEMCPY(despos, srcpos, len);
//重头写入
srcpos = srcpos + len;
despos = fifo->Buf;
len = num2push - len2end;
FIFO_MEMCPY(despos, srcpos, len);
}
func_fifo_PushOffset(fifo,num2push);
fifo->CntUsed += num2push;
if(fifo->CntUsed >= fifo->Depth)
{
fifo->CntUsed = fifo->Depth;
fifo->Pull = fifo->Push;
}
}
#else
/**
***************************************************
* @brief func_fifo_Push2Back
* @note 中断中进行FIFO写入操作时,FIFO繁忙调用该函数写入到back
* @param fifo
* 指向待操作的FIFO,
* num
* 删除的元素个数
* data
* 指向写入数据
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
static void func_fifo_Push2Back(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
INT16 offset = 0;
INT8U* srcpos = 0;
INT8U* despos = 0;
INT16U len = 0;
//现有数据和待写入数据的总数大于BACK的容量,进行元素替换操作。
if(num + fifo->BackCount > fifo->Depth)
{
offset = num + fifo->BackCount - fifo->Depth;
//现有元素全部被替换。
if(offset >= fifo->BackCount)
{
offset = num - fifo->Depth;
//写入新数据
srcpos = data+offset;
despos = fifo->BackBuf;
len = fifo->Depth;
FIFO_MEMCPY(despos, srcpos, len);
}
else
{
//更新原有数据
srcpos = fifo->BackBuf + offset;
despos = fifo->BackBuf;
len = fifo->BackCount - offset;
FIFO_MEMCPY(despos, srcpos, len);
//写入新数据。
srcpos = data;
despos = despos + len;
len = num;
FIFO_MEMCPY(despos, srcpos, len);
}
fifo->BackCount = fifo->Depth;
}
//现有数据和待写入数据的总数不大于FIFO的容量,将现有数据附加到back
else
{
srcpos = data;
despos = fifo->BackBuf + fifo->BackCount;
len = num;
fifo->BackCount += num;
FIFO_MEMCPY(despos, srcpos, len);
}
}
/**
***************************************************
* @brief func_fifo_Push2Fifo
* @note 将数据写入到FIFO缓冲区中,仅在FIFO不繁忙时调用,
* 1、首先将Back数据写入到FIFO中。
* 2、将待写入数据写入到FIFO中。
* @param fifo
* 指向待操作的FIFO,
* num
* 删除的元素个数
* data
* 指向写入数据
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
static void func_fifo_Push2Fifo(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
INT16 offset = 0;
INT16 len2end = func_fifo_CalPoint2end(fifo,fifo->Push);
INT16 num2push = 0;
INT8U* srcpos = 0;
INT8U* despos = 0;
INT16U len = 0;
//back数据和data数据之和大于depth,存在back和data丢弃数据的情况。
if(fifo->BackCount + num > fifo->Depth)
{
num2push = fifo->Depth;
offset = fifo->BackCount + num -fifo->Depth;
}
else
{
num2push = fifo->BackCount + num;
}
//到FIFO结尾可以容纳写入的数据,说明不存在覆盖情况。将back和带写入数据写入即可。
if(len2end >= num2push)
{
//写入BACK
srcpos = fifo->BackBuf;
despos = fifo->Push;
len = fifo->BackCount;
FIFO_MEMCPY(despos, srcpos, len);
//写入data
srcpos = data;
despos = despos + len;
len = num;
FIFO_MEMCPY(despos, srcpos, len);
}
//存在回头写的情况
else
{
//偏移量大于back的个数,back区域不执行写入操作。
if(offset >= fifo->BackCount)
{
//写入到队尾。
srcpos = data + offset - fifo->BackCount;
despos = fifo->Push;
len = len2end;
FIFO_MEMCPY(despos, srcpos, len);
//重头写入
srcpos = srcpos + len;
despos = fifo->Buf;
len = num2push - len2end;
FIFO_MEMCPY(despos, srcpos, len);
}
//写入备份区域和数据区域数据。
else
{
INT16U back2push = fifo->BackCount - offset;
if(len2end >= back2push)
{
//写入back
srcpos = fifo->BackBuf + offset;
despos = fifo->Push;
len = back2push;
FIFO_MEMCPY(despos, srcpos, len);
//写入DATA到队尾
srcpos = data;
despos = despos + len;
len = len2end - len;
FIFO_MEMCPY(despos, srcpos, len);
//重头写
srcpos = data + len;
despos = fifo->Buf;
len = num2push - back2push ;
FIFO_MEMCPY(despos, srcpos, len);
}
else
{
//写入back
srcpos = fifo->BackBuf + offset;
despos = fifo->Push;
len = len2end;
FIFO_MEMCPY(despos, srcpos, len);
//重头写BACK
srcpos = srcpos + len;
despos = fifo->Buf;
len = back2push - len;
FIFO_MEMCPY(despos, srcpos, len);
//写DATA
srcpos = data;
despos = despos + len;
len = num2push - back2push;
FIFO_MEMCPY(despos, srcpos, len);
}
}
}
fifo->BackCount = 0;
if(num2push + fifo->CntUsed > fifo->Depth)
{
num2push -= 1;
num2push += 1;
}
func_fifo_PushOffset(fifo,num2push);
fifo->CntUsed += num2push;
if(fifo->CntUsed >= fifo->Depth)
{
fifo->CntUsed = fifo->Depth;
fifo->Pull = fifo->Push;
}
}
#endif
static FifoErr func_fifo_PullLower(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len, INT8U mode)
{
INT16U len2end = func_fifo_CalPoint2end(fifo,fifo->Pull);
INT16U num2pull = 0;
if(fifo->CntUsed == 0)
{
return FIFO_ENUM;
}
//全部模式
if(mode == 0)
{
if(fifo->CntUsed >= num)
{
num2pull = num;
}
else
{
return FIFO_ENUM;
}
}
//PART模式
else
{
if(fifo->CntUsed >= num)
{
num2pull = num;
}
else
{
num2pull = fifo->CntUsed;
}
*len = num2pull;
}
if(len2end >= num2pull)
{
FIFO_MEMCPY(data , fifo->Pull , num2pull);
FIFO_MEMSET(fifo->Pull , 0 , num2pull);
}
//需要重头读取。
else
{
FIFO_MEMCPY(data , fifo->Pull, len2end);
FIFO_MEMSET(fifo->Pull , 0 , len2end);
FIFO_MEMCPY(data+len2end , fifo->Buf , num2pull-len2end);
FIFO_MEMSET(fifo->Buf , 0 , num2pull-len2end);
}
//读位置和使用量更新。
func_fifo_PullOffset(fifo,num2pull);
fifo->CntUsed -= num2pull;
return FIFO_EOK;
}
/*************************************************************************************************************************
* 全局函数
**************************************************************************************************************************/
/**
***************************************************
* @brief func_fifo_GetVer
* @note 获取FIFO文件的版本号。
* @param NONE
* @retval NONE
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
INT16U func_fifo_GetVer()
{
return VER_FIFO;
}
#ifdef SYS_RTT
/**
***************************************************
* @brief func_fifo_Create
* @note 创建FIFO
* @param depth
* FIFO的深度。
* type
* FIFO类型,是中断写入还是中断读取。
* @retval 0:
* 失败
* 其他:
* 成功,FIFO指针
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoTypeDef* func_fifo_Create(INT16U depth)
{
FifoTypeDef* p = RT_NULL;
p = FIFO_MALLOC(sizeof(FifoTypeDef));
if(p == NULL)
{
return NULL;
}
p->Buf = FIFO_MALLOC(depth);
if(p->Buf == NULL)
{
FIFO_FREE(p);
return NULL;
}
FIFO_MEMSET(p->Buf,0,depth);
p->Mutex = rt_mutex_create("MUTEX", 0);
if(p->Mutex == RT_NULL)
{
FIFO_FREE(p->Buf);
FIFO_FREE(p);
return NULL;
}
p->InitFlag = 1;
p->Depth = depth;
p->CntUsed = 0;
p->Push = p->Buf;
p->Pull = p->Buf;
p->EndPos = p->Buf + p->Depth - 1;
return p;
}
#else
/**
***************************************************
* @brief func_fifo_Init
* @note 启动FIFO使用的定时器。
* @param NONE
* @retval NONE
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
void func_fifo_Init()
{
extern TIM_HandleTypeDef htim4;
HAL_TIM_Base_Start_IT(&htim4);
}
/**
***************************************************
* @brief func_fifo_Create
* @note 创建FIFO
* @param depth
* FIFO的深度。
* type
* FIFO类型,是中断写入还是中断读取。
* @retval 0:
* 失败
* 其他:
* 成功,FIFO指针
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoTypeDef* func_fifo_Create(INT16U depth, FifoType type)
{
FifoTypeDef* p = FifoChain;
if(p == NULL)
{
p = FIFO_MALLOC(sizeof(FifoTypeDef));
if(p == NULL)
{
return NULL;
}
FifoChain = p;
}
else
{
while(p->Next != NULL)
{
p = p->Next;
}
p->Next = FIFO_MALLOC(sizeof(FifoTypeDef));
p = p->Next;
if(p == NULL)
{
return NULL;
}
}
p->Buf = FIFO_MALLOC(depth);
if(p->Buf == NULL)
{
if(FifoChain == p)
{
FifoChain = 0;
}
FIFO_FREE(p);
return NULL;
}
FIFO_MEMSET(p->Buf,0,depth);
p->BackBuf = FIFO_MALLOC(depth);
if(p->BackBuf == NULL)
{
if(FifoChain == p)
{
FifoChain = 0;
}
FIFO_FREE(p->Buf);
FIFO_FREE(p);
return NULL;
}
p->BusyFlag = 0;
p->IntFlag = 0;
p->BackCount = 0;
p->Type = type;
p->Next = NULL;
p->InitFlag = 1;
p->Depth = depth;
p->CntUsed = 0;
p->Push = p->Buf;
p->Pull = p->Buf;
p->EndPos = p->Buf + p->Depth - 1;
return p;
}
#endif
/**
***************************************************
* @brief func_fifo_Push
* @note 向FIFO中写入数据
* @param fifo
* 指向待操作的FIFO,
* num
* 写入的数据量
* data
* 指向写入的数据
* timeout
* 等待busy 超时时间,单位ms
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Push(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
func_fifo_Push2Fifo(fifo, num, data);
FIFO_RESET_BUSY(fifo);
return FIFO_EOK;
}
#ifdef SYS_RTT
#else
FifoErr func_fifo_PushInt(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_INT(fifo);
if(FIFO_GET_BUSY(fifo))
{
func_fifo_Push2Back(fifo, num, data);
}
else
{
func_fifo_Push2Fifo(fifo, num, data);
}
FIFO_RESET_INT(fifo);
return FIFO_EOK;
}
#endif
/**
***************************************************
* @brief func_fifo_Pull
* @note 从FIFO中读取数据
* @param fifo
* 指向待操作的FIFO,
* num
* 读取的数据量
* data
* 指向读取数据缓存区
* timeout
* 等待busy 超时时间,单位ms
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Pull(FifoTypeDef* fifo, INT16U num, INT8U* data)
{
FifoErr ret = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
ret = func_fifo_PullLower(fifo, num, data, 0, 0);
FIFO_RESET_BUSY(fifo);
return ret;
}
FifoErr func_fifo_PullPart(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len)
{
FifoErr ret = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
ret = func_fifo_PullLower(fifo, num, data, len, 1);
FIFO_RESET_BUSY(fifo);
return ret;
}
#ifdef SYS_RTT
#else
FifoErr func_fifo_PullPartInt(FifoTypeDef* fifo, INT16U num, INT8U* data, INT16U* len)
{
FifoErr ret = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_INT(fifo);
if(FIFO_GET_BUSY(fifo))
{
ret = FIFO_EFAILED;
}
else
{
ret =func_fifo_PullLower(fifo, num, data, len, 1);
}
FIFO_RESET_INT(fifo);
return ret;
}
#endif
/**
***************************************************
* @brief func_fifo_Copy
* @note 从FIFO中读取数据
* @param fifo
* 指向待操作的FIFO,
* ind
* 从FIFO的pull后面的第ind个开始
* len
* 拷贝数据的长度
* data
* 拷贝数据的缓冲区
* timeout
* 等待busy 超时时间,单位ms
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Copy(FifoTypeDef* fifo , INT16U ind, INT16U len, INT8U* data)
{
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
//读取数据量大于FIFO容量,不进行读取操作。
if(ind + len > fifo->CntUsed)
{
//释放FIFO繁忙标志位。
FIFO_RESET_BUSY(fifo);
return FIFO_ENUM;
}
//开始数据拷贝
INT8U* point = fifo->Pull + ind;
if(point > fifo->EndPos)
{
point = point - fifo->Depth;
}
INT16U len2end = func_fifo_CalPoint2end(fifo,fifo->Pull);
if(len2end >= len)
{
FIFO_MEMCPY(data,point,len);
}
else
{
FIFO_MEMCPY(data , point , len2end);
FIFO_MEMCPY(data+len2end , fifo->Buf , len-len2end);
}
FIFO_RESET_BUSY(fifo);
return FIFO_EOK;
}
/**
***************************************************
* @brief func_fifo_Delete
* @note 从FIFO中删除数据
* @param fifo
* 指向待操作的FIFO,
* num
* 删除数据的个数
* timeout
* 等待busy 超时时间,单位ms
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Delete(FifoTypeDef* fifo , INT16U num)
{
FifoErr err = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
err = func_fifo_DeleteLower(fifo, num);
FIFO_RESET_BUSY(fifo);
return err;
}
/**
***************************************************
* @brief func_fifo_Cmp
* @note 比较FIFO中数据
* @param fifo
* 指向待操作的FIFO,
* ind
* 从FIFO的pull后面的第ind个开始
* len
* 比较的长度为len
* data
* 比较的数据
* timeout
* 等待busy 超时时间,单位ms
* timeout
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Cmp(FifoTypeDef* fifo, INT16U ind, INT16U len, INT8U* data)
{
FifoErr err = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
err = func_fifo_CmpLower(fifo, ind, len, data);
FIFO_RESET_BUSY(fifo);
return err;
}
/**
***************************************************
* @brief func_fifo_FindDelete
* @note 比较FIFO中数据
* @param fifo
* 指向待操作的FIFO,
* ind
* 从FIFO的pull后面的第ind个开始
* len
* 比较的长度为len
* data
* 比较的数据
* timeout
* 等待busy 超时时间,单位ms
* timeout
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_FindDelete(FifoTypeDef* fifo, INT16U len, INT8U* data)
{
INT16U cycle = 0;
FifoErr err = FIFO_EOK;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
err = FIFO_EFAILED;
while((fifo->CntUsed - cycle) >= len)
{
err = func_fifo_CmpLower(fifo, cycle++, len, data);
if(err == FIFO_EOK)
{
break;
}
}
func_fifo_DeleteLower(fifo, cycle-1);
FIFO_RESET_BUSY(fifo);
return err;
}
/**
***************************************************
* @brief func_fifo_FindDelete
* @note 比较FIFO中数据
* @param fifo
* 指向待操作的FIFO,
* ind
* 从FIFO的pull后面的第ind个开始
* len
* 比较的长度为len
* data
* 比较的数据
* timeout
* 等待busy 超时时间,单位ms
* timeout
* @retval FifoErr
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
FifoErr func_fifo_Find(FifoTypeDef* fifo, INT16U ind, INT8U* data, INT16U len, INT16U* pos)
{
FifoErr err = FIFO_EOK;
INT16U cycle = 0;
if(FIFO_INIT_CHECK(fifo) == 0)
{
return FIFO_EINIT;
}
FIFO_SET_BUSY(fifo);
INT16U times = fifo->CntUsed - ind - len - 1;
err = FIFO_EFAILED;
while(cycle < times)
{
if(func_fifo_CmpLower(fifo, ind+cycle, len, data) == FIFO_EOK)
{
err = FIFO_EOK;
*pos = cycle;
break;
}
cycle++;
}
FIFO_RESET_BUSY(fifo);
return err;
}
INT16U func_fifo_GetUsed(FifoTypeDef* fifo)
{
INT16U num = 0;
FIFO_SET_BUSY(fifo);
num = fifo->CntUsed;
FIFO_RESET_BUSY(fifo);
return num;
}
#ifdef SYS_RTT
#else
/**
***************************************************
* @brief func_fifo_TimerCallBack
* @note FIFO链表定时器中断回调
* @param NONE
* @retval NONE
* @data 2021.09.03
* @auth WXL
* @his 1.0.0.0 2021.09.03 WXL
* create
***************************************************
**/
void func_fifo_TimerCallBack()
{
FifoTypeDef* point = FifoChain;
while(point!= NULL)
{
//FIFO 不繁忙 不在中断中
if(FIFO_GET_BUSY(point) == 0 && FIFO_GET_INT(point) == 0)
{
if(point->Type == FIFO_TYPE_INT_PUSH && point->BackCount != 0)
{
func_fifo_Push2Fifo(point, 0, 0);
}
else if(point->Type == FIFO_TYPE_INT_PULL && point->CntUsed != 0)
{
point->func_timmer();
}
}
point = point->Next;
}
}
#endif