1、概述
该FIFO主要用于处理STM32的相关外设数据接收和发送使用。按照在STM32无操作系统(裸机)情况下使用时FIFO写入位置的不同,将FIFO分为两类。
- 主函数写入
使用场景:
串口发送,主函数将串口数据压入到发送FIFO,调用发送函数将FIFO数据读取到发送缓冲区,发送完成中断时,继续判断FIFO中是否存在新的待发送数据,继续进行发送。
存在的问题:
调用串口发送函数时,串口繁忙,数据积压在FIFO中。进入发送完成中断后,此时FIFO正在写入,完成中断不能实现FIFO剩余数据的发送
解决措施:
使用定时器,定时对发送FIFO的使用量进行监控,不空则进行数据发送。
- 外设中断写入
使用场景:
串口接收,中断中将数据压入到接收FIFO
存在的问题:
串口接收中断时,要将数据写入到FIFO中,此时FIFO正在主函数中进行访问(busy)无法将数据进行写入。数据若不进行备份,则跳出中断后数据丢失。
解决措施:
提供备份缓冲区,当中断写入数据时FIFO繁忙,将数据写入到备份缓冲区
存在问题2:
备份缓冲区数据什么时候写入到FIFO。
解决措施:
再次进入中断时,先将备份缓冲区数据写入到FIFO,再将新接收到的数据写入到FIFO。
若后续无中断进入,通过定时器回调功能实现备份缓冲区数据的写入功能。
- 为什么要设置繁忙标志
因为涉及到主函数与中断同时进行读写FIFO参数的情况,可能出现全局变量错误的情况,导致程序崩溃。程序方面FIFO可能被主函数和中断访问的变量使用volatile进行限制。
- 繁忙标志位什么时候置位
主函数对FIFO进行操作时需要对BUSY进行置位和复位操作
中断操作时进行busy的判断,因为中断高于主函数,不存在中断被主函数打断问题,所以中断不用对busy进行置位复位操作
- 定时器与数据外设(串口)中断优先级问题
定时器的优先级需要高于外设中断优先级。同时在中断中进行FIFO处理时还需要对INT标志位进行置位复位操作
2、FIFO结构体及说明
typedef struct FifoTypeDef
{//构成链表。struct FifoTypeDef* Next;//FIFO节本元素。volatile INT16U Depth; //FIFO的深度volatile INT16U CntUsed; //使用了的元素个数INT8U* Push; //写入的位置INT8U* Pull; //读取的位置。INT8U* Buf; //数据缓冲区//FIFO计算元素INT8U* EndPos; //缓冲区的结尾处指针。//FIFO类型FifoType Type;//标志位。 写 读INT8U InitFlag; // 主颜色初始化 所有FIFO相关函数。volatile INT8U BusyFlag; // 主函数 中断volatile INT8U IntFlag; // 中断 定时器中断//中断写入时的备份缓冲区。volatile INT16U BackCount;INT8U* BackBuf;//定时器中断回调函数void (*func_timmer)();
}FifoTypeDef;
基本元素
- Depth:FIFO的深度,能存储原始的个数(元素的大小为1字节)
- CntUsed:FIFO使用了的个数
- Push:FIFO的写入指针
- Pull:FIFO的读取指针
- Buf:FIFO的缓冲区
扩展元素
- Next:用于构成FIFO链表,定时器中断中进行FIFO的遍历
- EndPos:缓冲区的结尾地址,用于计算
- Type:FIFO的类型,中断写入,还是主函数写入
- InitFlag:初始化标志位
- BusyFlag:FIFO繁忙标志位
- InitFlag:FIFO在中断中进行操作标志位
- BackCount:备份缓冲区使用了的数量
- BackBuf:备份缓冲区
- func_timer():FIFO的定时器回调函数
3、相关函数说明
3.1相关宏定义
#define FIFO_SET_BUSY(fifo) (fifo->BusyFlag = 1)
#define FIFO_RESET_BUSY(fifo) (fifo->BusyFlag = 0)
#define FIFO_GET_BUSY(fifo) (fifo->BusyFlag == 1? 1:0)#define FIFO_SET_INT(fifo) (fifo->IntFlag = 1)
#define FIFO_RESET_INT(fifo) (fifo->IntFlag = 0)
#define FIFO_GET_INT(fifo) (fifo->IntFlag == 1? 1:0)#define FIFO_INIT_CHECK(fifo) (fifo->InitFlag == 1? 1:0)
置位,复位,查询FIFO的繁忙,中断,初始化状态。
3.2内部函数
3.2.1相关指针操作函数
指针的相关操作函数,主要用于对FIFO的push和pull指针进行更新,同时在查询FIFO时查询位置到FIFO缓冲容量结尾的元素个数的计算。
static inline void func_fifo_PushOffset(FifoTypeDef* fifo,INT16U offset)
{fifo->Push += offset;if(fifo->Push > fifo->EndPos){fifo->Push = fifo->Push - fifo->Depth;}
}
更新push指针的位置。需要注意到FIFO的缓冲区结尾时回头的情况
static inline void func_fifo_PullOffset(FifoTypeDef* fifo,INT16U offset)
{fifo->Pull += offset;if(fifo->Pull > fifo->EndPos){fifo->Pull = fifo->Pull - fifo->Depth;}
}
更新pull指针的位置,同上。
static inline INT16U func_fifo_CalPoint2end(FifoTypeDef* fifo, INT8U* point)
{return fifo->EndPos - point + 1;
}
计算某个指针到fifo缓冲末尾的元素个数。
3.2.2底层操作函数
FIFO的底层操作函数,底层操作函数不对FIFO的标志位进行判断,时主函数和中断操作FIFO的具体实现步骤。
/**
***************************************************
* @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(memcmp(data,point,len) == 0){return FIFO_EOK;}else{return FIFO_EFAILED;}}else{if(memcmp(data,point,len2end) == 0 && 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){memset(fifo->Pull , 0 , num);}else{memset(fifo->Pull , 0 , len2end);memset(fifo->Buf , 0 , num - len2end);}fifo->CntUsed -= num;func_fifo_PullOffset(fifo,num);return FIFO_EOK;
}
/**
***************************************************
* @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;memcpy(despos, srcpos, len);}else{//更新原有数据srcpos = fifo->BackBuf + offset;despos = fifo->BackBuf;len = fifo->BackCount - offset;memcpy(despos, srcpos, len);//写入新数据。srcpos = data;despos = despos + len;len = num;memcpy(despos, srcpos, len);}fifo->BackCount = fifo->Depth;}//现有数据和待写入数据的总数不大于FIFO的容量,将现有数据附加到backelse{srcpos = data;despos = fifo->BackBuf + fifo->BackCount;len = num;fifo->BackCount += num;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){//写入BACKsrcpos = fifo->BackBuf;despos = fifo->Push;len = fifo->BackCount;memcpy(despos, srcpos, len);//写入datasrcpos = data;despos = despos + len;len = num;memcpy(despos, srcpos, len);}//存在回头写的情况else{//偏移量大于back的个数,back区域不执行写入操作。if(offset >= fifo->BackCount){//写入到队尾。srcpos = data + offset - fifo->BackCount;despos = fifo->Push;len = len2end;memcpy(despos, srcpos, len);//重头写入srcpos = srcpos + len;despos = fifo->Buf;len = num2push - len2end;memcpy(despos, srcpos, len);}//写入备份区域和数据区域数据。else{INT16U back2push = fifo->BackCount - offset;if(len2end >= back2push){//写入backsrcpos = fifo->BackBuf + offset;despos = fifo->Push;len = back2push;memcpy(despos, srcpos, len);//写入DATA到队尾srcpos = data;despos = despos + len;len = len2end - len;memcpy(despos, srcpos, len);//重头写srcpos = data + len;despos = fifo->Buf;len = num2push - back2push ;memcpy(despos, srcpos, len);}else{//写入backsrcpos = fifo->BackBuf + offset;despos = fifo->Push;len = len2end;memcpy(despos, srcpos, len);//重头写BACKsrcpos = srcpos + len;despos = fifo->Buf;len = back2push - len;memcpy(despos, srcpos, len);//写DATAsrcpos = data;despos = despos + len;len = num2push - back2push;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;}
}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){memcpy(data , fifo->Pull , num2pull);memset(fifo->Pull , 0 , num2pull);}//需要重头读取。else{memcpy(data , fifo->Pull, len2end);memset(fifo->Pull , 0 , len2end);memcpy(data+len2end , fifo->Buf , num2pull-len2end);memset(fifo->Buf , 0 , num2pull-len2end);}//读位置和使用量更新。func_fifo_PullOffset(fifo,num2pull);fifo->CntUsed -= num2pull;return FIFO_EOK;
}
3.2.3FIFO函数实现
获取FIFO驱动的版本和FIFO定时器的初始化。
/**
***************************************************
* @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;
}/**
***************************************************
* @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);
}
创建FIFO,初始化FIFO的相关遍历,初始化FIFO的链表
/**
***************************************************
* @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 = malloc(sizeof(FifoTypeDef));if(p == NULL){return NULL;}FifoChain = p;}else{while(p->Next != NULL){p = p->Next;}p->Next = malloc(sizeof(FifoTypeDef));p = p->Next;if(p == NULL){return NULL;}}p->Buf = malloc(depth);if(p->Buf == NULL){if(FifoChain == p){FifoChain = 0;}free(p);return NULL;}memset(p->Buf,0,depth);p->BackBuf = malloc(depth);if(p->BackBuf == NULL){if(FifoChain == p){FifoChain = 0;}free(p->Buf);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;
}
FIFO元素的写入,包括中断写入和普通写入两种。中断写入首先进行busy标志位判断,busy时将数据写入到back。
/**
***************************************************
* @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;
}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;
}
FIFO数据的读取。分为三个函数
func_fifo_Pull:读取FIFO的数据,若读取个数大于FIFO的使用量返回错误
func_fifo_PullPart:部分读取,当读取数大于FIFO的使用量时,读取FIFO已使用的个数。
func_fifo_PullPartInt:中断中使用,进行部分读取。
/**
***************************************************
* @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;
}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;
}
FIFO数据的拷贝,只进行数据拷贝,不操作FIFO的相关指针
/**
***************************************************
* @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){memcpy(data,point,len);}else{memcpy(data , point , len2end);memcpy(data+len2end , fifo->Buf , len-len2end);}FIFO_RESET_BUSY(fifo);return FIFO_EOK;
}
删除FIFO中的元素
/**
***************************************************
* @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;
}
比较FIFO重的元素,不对FIFO指针进行操作。
/**
***************************************************
* @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;
}
查找FIFO中的元素,对不符合元素进行删除,直到查找到或者FIFO容量不符合查找长度时停止
/**
***************************************************
* @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;
}
从FIFO的指定位置开始查找,不进行元素的删除和相关指针的操作
/**
***************************************************
* @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;
}
获取FIFO的使用量,需要操作busy标志位
INT16U func_fifo_GetUsed(FifoTypeDef* fifo)
{INT16U num = 0;FIFO_SET_BUSY(fifo);num = fifo->CntUsed;FIFO_RESET_BUSY(fifo);return num;
}
FIFO使用定时器的回调函数。回调函数中判断FIFO的标志位。对不同类型的FIFO执行不同的操作。
中断写入类型的FIFO,进行备份去数据的写入
/**
***************************************************
* @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;}
}