嵌入式应用之FIFO模块原理与实现
创作时间:
作者:
@小白创作中心
嵌入式应用之FIFO模块原理与实现
引用
CSDN
1.
https://m.blog.csdn.net/qq_38473009/article/details/139578143
FIFO(First-In First-Out)是一种常见的数据缓冲机制,在嵌入式系统中有着广泛的应用。本文将详细介绍FIFO的基本原理,并通过具体的代码实现,展示如何使用C语言实现一个FIFO模块。
FIFO介绍与原理
FIFO是First-In First-Out的缩写,它是一个具有先入先出特点的缓冲区。FIFO在嵌入式应用中非常广泛,可以说有数据收发的地方,基本就有FIFO的存在。或者为了降低CPU负担,提高数据处理效率,可以在积累到一定的数据量之后,再一次性处理。在嵌入式系统中,FIFO是基于一维数组和结构体实现的循环队列(Queue),或者叫环形队列。可以分为同步FIFO或异步FIO,一般用于数据缓冲,或者不同时钟域之间的数据传递。
FIFO设计中,最重要的满和空的判断条件,需要遵循FIFO读写的两个规则:
- FIFO为空时,不能执行读操作
- FIFO为满时,不能执行写操作
FIFO代码实现
使用一维数组来构造一个环形缓冲区,读写地址循环递增,分别实现FIFO初始化、读写操作、判断空满、获取元素个数等函数,并封装成模块。
msgfifo.h
#ifndef __MQUEUE_H__
#define __MQUEUE_H__
#include <stdio.h>
#include <stdint.h>
#define FIFO_SIZE 6
#define qdata_t uint8_t
typedef enum {
QUEUE_OK,
QUEUE_FULL,
QUEUE_EMPTY
}qstatus_t;
typedef struct {
uint16_t addr_wr;
uint16_t addr_rd;
uint16_t length;
qdata_t fifo[FIFO_SIZE];
}queue_t;
qstatus_t queue_reset(queue_t * q);
qstatus_t queue_read(queue_t *q, qdata_t *pdata);
qstatus_t queue_write(queue_t *q, qdata_t data);
int queue_isFull(queue_t *q);
int queue_isEmpty(queue_t *q);
int queue_print(queue_t *q);
#endif
msgfifo.c
#include "msgfifo.h"
qstatus_t queue_reset(queue_t * q) {
int i = 0;
q->addr_wr = 0;
q->addr_rd = 0;
q->length = FIFO_SIZE;
for(i=0; i<q->length; i++) {
q->fifo[i] = 0;
}
return QUEUE_OK;
}
qstatus_t queue_write(queue_t *q, qdata_t data)
{
if(queue_isFull(q))
{
printf("Write failed(%d), queue is full\n", data);
return QUEUE_FULL;
}
q->fifo[q->addr_wr] = data;
q->addr_wr = (q->addr_wr + 1) % q->length;
printf("write success: %02d\n", data);
queue_print(q);
return QUEUE_OK;
}
qstatus_t queue_read(queue_t *q, qdata_t *pdata)
{
if(queue_isEmpty(q))
{
printf("Read failed, queue is empty\n");
return QUEUE_EMPTY;
}
*pdata = q->fifo[q->addr_rd];
q->addr_rd = (q->addr_rd + 1) % q->length;
printf("read success: %02d\n", *pdata);
queue_print(q);
return QUEUE_OK;
}
int queue_isEmpty(queue_t *q)
{
return (q->addr_wr == q->addr_rd);
}
int queue_isFull(queue_t *q)
{
return ((q->addr_wr + 1) % q->length == q->addr_rd);
}
int queue_count(queue_t *q)
{
if(q->addr_rd <= q->addr_wr)
return (q->addr_wr - q->addr_rd);
//addr_rd > addr_wr;
return (q->length + q->addr_wr - q->addr_rd);
}
int queue_print(queue_t *q)
{
int i = 0;
int j = 0;
for(i = 0; i < q->addr_rd; i++)
printf(" ");
printf("rd=%d", q->addr_rd);
printf("\n");
for(i = 0; i < q->length; i++)
{
if(q->addr_wr > q->addr_rd)
{
if(i >= q->addr_rd && i < q->addr_wr)
printf("[%02d] ", q->fifo[i]);
else
printf("[ ] ");
}
else //addr_rd > addr_wr
{
if(i < q->addr_wr || i >= q->addr_rd)
printf("[%02d] ", q->fifo[i]);
else
printf("[ ] ");
}
}
printf("------count = %d\n", queue_count(q));
for(i = 0; i < q->addr_wr; i++)
printf(" ");
printf("wr=%d", q->addr_wr);
printf("\n");
return QUEUE_OK;
}
fifotest.c
#include "msgfifo.h"
int main(int argc, char * argv[]){
queue_t queue;
qdata_t data;
qdata_t msgd[8] = {'a','b','c','d', 'e', 'f', 'g'};
// queue init
queue_reset(&queue);
queue_write(&queue, msgd[0]);
queue_write(&queue, msgd[1]);
queue_write(&queue, msgd[2]);
queue_read(&queue, &data);
queue_read(&queue, &data);
queue_write(&queue, msgd[3]);
queue_write(&queue, msgd[4]);
queue_write(&queue, msgd[5]);
queue_write(&queue, msgd[6]);
queue_read(&queue, &data);
queue_read(&queue, &data);
queue_read(&queue, &data);
queue_write(&queue, msgd[1]);
queue_write(&queue, msgd[3]);
queue_write(&queue, msgd[5]);
queue_read(&queue, &data);
// system("pause");
return 0;
}
通过以上代码实现,可以完成一个简单的FIFO模块。在实际应用中,可以根据具体需求对FIFO的大小、数据类型等进行相应的调整。
热门推荐
欺负瘫痪乞丐是否犯法?——从法律责任到社会伦理的全面解析
专家评选出的 13 种最聪明的狗品种
国家统计局:2024年居民人均可支配收入增长5.3%,恩格尔系数仍为29.8%
探索江苏洪泽湖:完美旅游攻略与最佳景点路线
洪泽自驾游全攻略:探索自然美景与文化遗迹
旁路由如何处理网络流量
提升英语作文写作能力:从积累到实践的全面指南
无创DNA检查流程大揭秘,操作原理其实没那么复杂
无创DNA产前检查:原理、步骤与结果解读
如何优化健康档案管理系统以提升患者体验与数据安全?
欧洲和中国面积差不多,为啥中国统一千年,欧洲却“散装”至今?
10万预算买车,油车还是新能源?真实数据告诉你答案
长大才懂,为何岳灵珊宁愿死在林平之剑下,也不跟令狐冲在一起?
色坐标对应的颜色及其表示方法
从晒太阳开始,慢慢缓解抑郁症
组织现场投票的技巧:如何设计一个流畅的投票环节
高速公路服务区数字化建设思考
如何正确佩戴耳机:提升音质与舒适度的全方位指南
容器日志管理的最佳实践
月季苗嫁接技术指南:从准备到后期管理的完整攻略
《六世班禅画像》唐卡:民族文化交流交融的历史见证
“挺胸抬头”不是最健康坐姿?教你正确坐姿,远离脊柱问题
东北王张作霖的“必死之局”。详解皇姑屯事件始末
神经衰弱的调理方法:从饮食到药物全方位指南
女孩自学成才,高考624分成功上岸985,初中毕业时被姐姐勒令辍学
黑藻特性、繁殖与应用全解析 | 水鳖科沉水植物百科
普及法律知识,维护公民权益——构建和谐社会的重要基石
冶金作业中的国标、欧标与美标:标准差异与应用场景
甜瓜甜不甜,看一眼这里就识别,一挑一个准甜,多亏资深果农提醒
英语四级怎么报名?一文带你了解报名全过程