C语言实现标准FIFO

说明:

本文在C语言中实现了标准FIFO,可以存储任意类型的数据。FIFO返回给应用模块的是一个int类型的索引值,本质是一个指针。通过这层封装,可以简化提供给应用模块的接口。

注意:此FIFO为满时不能写入的类型,如果需要的是满时自动覆蓋,请自行修改。

源码:

itcp_fifo.h:/**

* Copyright (c), 2015-2025

* @file itcp_fifo.h

* @brief fifo头文件

* @author jdh

* @verbatim

* Change Logs:

* Date Author Notes

* 2018-01-24 jdh 新建

* 2018-11-06 jdh 修改成通用格式

* @endverbatim

*/

#ifndef _ITCP_FIFO_H_

#define _ITCP_FIFO_H_

#include "itcp_def.h"

/**

* @brief 创建fifo

* @param item_sum:fifo中元素数.注意不是字节数

* @param item_size: 元素大小.单位: 字节

* @return fifo索引

*/

int itcp_fifo_create(int item_sum, int item_size);

/**

* @brief 删除fifo

* @param fifo_index: fifo索引

*/

void itcp_fifo_delete(int fifo_index);

/**

* @brief fifo检查是否可以写入

* @param fifo_index: fifo索引

* @retval false:不可以写入.true:可以写入

*/

bool itcp_fifo_writeable(int fifo_index);

/**

* @brief fifo写入

* @param fifo_index: fifo索引

* @param frame:写入元素指针

* @return false:失败.true:成功

*/

bool itcp_fifo_write(int fifo_index, void *data);

/**

* @brief fifo批量写入

* @param fifo_index: fifo索引

* @param data: 写入元素指针

* @param item_num:元素数目

* @return false:失败.true:成功

*/

bool itcp_fifo_write_batch(int fifo_index, void *data, int item_num);

/**

* @brief fifo检查是否可以读取

* @param fifo_index: fifo索引

* @return false:不可以读取.true:可以读取

*/

bool itcp_fifo_readable(int fifo_index);

/**

* @brief fifo读取

* @param fifo_index: fifo索引

* @param data: 读取的数据

* @return false: 失败.true: 成功

*/

bool itcp_fifo_read(int fifo_index, void *data);

/**

* @brief fifo批量读取

* @param fifo_index: fifo索引

* @param data: 读取的数据

* @return false: 失败.true: 成功

*/

bool itcp_fifo_read_batch(int fifo_index, void *data, int item_num);

/**

* @brief fifo可读的元素数

* @param fifo_index: fifo索引

* @return 元素数

*/

int itcp_fifo_readable_item_count(int fifo_index);

/**

* @brief fifo可写的元素数

* @param fifo_index: fifo索引

* @return 元素数

*/

int itcp_fifo_writeable_item_count(int fifo_index);

#endif

itcp_fifo.c:/**

* Copyright (c), 2015-2025

* @file itcp_fifo.c

* @brief fifo主文件

* @author jdh

* @verbatim

* Change Logs:

* Date Author Notes

* 2018-01-24 jdh 新建

* 2018-11-06 jdh 修改成通用格式

* @endverbatim

*/

#include "itcp_fifo.h"

/**

* @brief fifo结构

*/

typedef struct

{

int ptr_write;

int ptr_read;

bool is_full;

// fifo中存储的元素数,不是字节大小

int item_sum;

// 元素大小.单位: 字节

int item_size;

void *fifo_ptr;

} ItcpFifo;

/**

* @brief 创建fifo

* @param item_sum:fifo中元素数.注意不是字节数

* @param item_size: 元素大小.单位: 字节

* @return fifo索引

*/

int itcp_fifo_create(int item_sum, int item_size)

{

ItcpFifo *fifo = (ItcpFifo *)malloc(sizeof(ItcpFifo));

fifo->item_sum = item_sum;

fifo->item_size = item_size;

fifo->ptr_write = 0;

fifo->ptr_read = 0;

fifo->is_full = false;

fifo->fifo_ptr = (uint8_t *)malloc(item_sum * item_size);

return (int)fifo;

}

/**

* @brief 删除fifo

* @param fifo_index: fifo索引

*/

void itcp_fifo_delete(int fifo_index)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

free(fifo->fifo_ptr);

fifo->fifo_ptr = NULL;

free(fifo);

fifo = NULL;

}

/**

* @brief fifo检查是否可以写入

* @param fifo_index: fifo索引

* @retval false:不可以写入.true:可以写入

*/

bool itcp_fifo_writeable(int fifo_index)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

return !fifo->is_full;

}

/**

* @brief fifo写入

* @param fifo_index: fifo索引

* @param frame:写入元素指针

* @return false:失败.true:成功

*/

bool itcp_fifo_write(int fifo_index, void *data)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (fifo->is_full)

{

return false;

}

memcpy(fifo->fifo_ptr + fifo->ptr_write * fifo->item_size, data, fifo->item_size);

fifo->ptr_write++;

if (fifo->ptr_write >= fifo->item_sum)

{

fifo->ptr_write = 0;

}

if (fifo->ptr_write == fifo->ptr_read)

{

fifo->is_full = true;

}

return true;

}

/**

* @brief fifo批量写入

* @param fifo_index: fifo索引

* @param data: 写入元素指针

* @param item_num:元素数目

* @return false:失败.true:成功

*/

bool itcp_fifo_write_batch(int fifo_index, void *data, int item_num)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (itcp_fifo_writeable_item_count(fifo) < item_num)

{

return false;

}

memcpy(fifo->fifo_ptr + fifo->ptr_write * fifo->item_size, data, fifo->item_size * item_num);

fifo->ptr_write += item_num;

if (fifo->ptr_write >= fifo->item_sum)

{

fifo->ptr_write = 0;

}

if (fifo->ptr_write == fifo->ptr_read)

{

fifo->is_full = true;

}

return true;

}

/**

* @brief fifo检查是否可以读取

* @param fifo_index: fifo索引

* @return false:不可以读取.true:可以读取

*/

bool itcp_fifo_readable(int fifo_index)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (fifo->ptr_write == fifo->ptr_read && !fifo->is_full)

{

return false;

}

return true;

}

/**

* @brief fifo读取

* @param fifo_index: fifo索引

* @param data: 读取的数据

* @return false: 失败.true: 成功

*/

bool itcp_fifo_read(int fifo_index, void *data)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (fifo->ptr_write == fifo->ptr_read && !fifo->is_full)

{

return false;

}

memcpy(data, fifo->fifo_ptr + fifo->ptr_read * fifo->item_size, fifo->item_size);

fifo->ptr_read++;

if (fifo->ptr_read >= fifo->item_sum)

{

fifo->ptr_read = 0;

}

fifo->is_full = false;

return true;

}

/**

* @brief fifo批量读取

* @param fifo_index: fifo索引

* @param data: 读取的数据

* @return false: 失败.true: 成功

*/

bool itcp_fifo_read_batch(int fifo_index, void *data, int item_num)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (itcp_fifo_readable_item_count(fifo) < item_num)

{

return false;

}

memcpy(data, fifo->fifo_ptr + fifo->ptr_read * fifo->item_size, fifo->item_size * item_num);

fifo->ptr_read += item_num;

if (fifo->ptr_read >= fifo->item_sum)

{

fifo->ptr_read = 0;

}

fifo->is_full = false;

return true;

}

/**

* @brief fifo可读的元素数

* @param fifo_index: fifo索引

* @return 元素数

*/

int itcp_fifo_readable_item_count(int fifo_index)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (fifo->is_full)

{

return fifo->item_sum;

}

else

{

return (fifo->item_sum + fifo->ptr_write - fifo->ptr_read) % fifo->item_sum;

}

}

/**

* @brief fifo可写的元素数

* @param fifo_index: fifo索引

* @return 元素数

*/

int itcp_fifo_writeable_item_count(int fifo_index)

{

ItcpFifo *fifo = (ItcpFifo *)fifo_index;

if (fifo->is_full)

{

return 0;

}

else

{

if (fifo->ptr_write == fifo->ptr_read)

{

return fifo->item_sum;

}

else

{

return (fifo->item_sum + fifo->ptr_read - fifo->ptr_write) % fifo->item_sum;

}

}

}

测试代码:struct _Test

{

uint8_t a;

uint16_t b;

};

// fifo1操作

struct _Test arr;

int fifo1 = itcp_fifo_create(10, sizeof(struct _Test));

for (uint8_t i = 0; i < 10; i++)

{

arr.a = i;

arr.b = 100 + i;

if (itcp_fifo_writeable(fifo1))

{

itcp_fifo_write(fifo1, (void *)&arr);

printf("可写:%d 可读:%d\n", itcp_fifo_writeable_item_count(fifo1), itcp_fifo_readable_item_count(fifo1));

}

}

while (1)

{

if (itcp_fifo_readable(fifo1) == false)

{

break;

}

itcp_fifo_read(fifo1, (void *)&arr);

printf("read:%d %d\n", arr.a, arr.b);

}

// fifo2操作

int fifo2 = itcp_fifo_create(100, 1);

char str_arr[100] = {0};

memcpy(str_arr, "jdh", 3);

itcp_fifo_write_batch(fifo2, str_arr, 3);

printf("fifo2可写:%d 可读:%d\n", itcp_fifo_writeable_item_count(fifo2), itcp_fifo_readable_item_count(fifo2));

str_arr[0] = 0;

itcp_fifo_read_batch(fifo2, str_arr, itcp_fifo_readable_item_count(fifo2));

printf("read:%s\n", str_arr);

测试输出:可写:9 可读:1

可写:8 可读:2

可写:7 可读:3

可写:6 可读:4

可写:5 可读:5

可写:4 可读:6

可写:3 可读:7

可写:2 可读:8

可写:1 可读:9

可写:0 可读:10

read:0 100

read:1 101

read:2 102

read:3 103

read:4 104

read:5 105

read:6 106

read:7 107

read:8 108

read:9 109

fifo2可写:97 可读:3

read:jdh

使用c语言实现的fifo程序,C语言实现标准FIFO相关推荐

  1. c语言课程设计加密程序,C语言课程设计文件加密解密.doc

    C语言课程设计文件加密解密 C语言程序设计 课程设计 学 院 计算机工程 班 级 计算1313 姓 名 学 号 201321121089 成 绩 指导老师 2014年6月26日 计算1313班C语言程 ...

  2. python是语言还是软件_程序开发语言之Python:是追逐还是坚守?

    Python作为计算机程序设计语言的其中一种,最初是被设计用于编写自动化脚本(shell),随着版本的不断更新.语言新功能的添加和机器学习的兴起,Python从2017年开始受到广泛关注. Pytho ...

  3. c语言经典解决实际程序,C语言经典教程1讲.ppt

    <C语言经典教程1讲.ppt>由会员分享,可在线阅读,更多相关<C语言经典教程1讲.ppt(48页珍藏版)>请在人人文库网上搜索. 1.C程序设计,主讲人:任祖华,2,本课程学 ...

  4. c语言怎么返回前一个程序,c语言return返回到哪

    c语言return返回到哪 c语言return,返回给了上一级,比如一个递归程序,从第三层返回到第二层:又比如一个普通的子程序,那就返回到主程序中去. 主程序中return返回给了操作系统. 比如下面 ...

  5. 用c语言做一个五子棋程序,C语言制作简单五子棋游戏

    原标题:C语言制作简单五子棋游戏 C语言制作简单的五子棋游戏 学习C语言的人很多,但是用C语言很少,而用来为自己所用,来做游戏的人就更少了,很多人都是跟着学校学习,学校讲到哪就坐到哪,但是以后却还是不 ...

  6. c语言常考的程序,C语言 一些常考得东西

    C语言基础测试 1.#include "heima.txt" 表示文件在哪个目录?( D) A.系统根目路径 B.编译器路径 C.桌面 D.与当前文件目录一致. 2.C源程序中不能 ...

  7. c语言的一段程序,C语言第一个程序(入门)

    1.文件类型(基本) c语言源文件  为.c 文件扩展名,例如 main.c    编译后将得到 a.out 文件   运行会得到 我们程序执行的结果 2.hello world (第一个程序) #i ...

  8. c语言程序设计实验三程序,c语言程序设计实验三循环.doc

    c语言程序设计实验三循环 高级语言程序设计 实验三 循环控制 一.实验目的和要求 1. 熟练掌握用while语句.do while语句和for语句实现循环的方法.掌握在程序设计中用循的方法实现一些常用 ...

  9. c语言随机抽取小程序_C语言整人小程序,慎用,谨记!

    整人啦!!! 哈喽~ 今天有位朋友留言问有没有比较有趣的C语言小程序? 想了想,给你写几个整人的小程序吧,有趣又好玩... 这里一共给你们准备了三个,分别起名为关机.死机.抖动,都给出了代码,整人指数 ...

最新文章

  1. 清华大学唐杰教授:人工智能的十年总结
  2. opencv矩阵运算(1)
  3. 二分算法php,PHP练习-二分查找算法
  4. App设计灵感之十二组精美的移动支付App设计案例
  5. linux下如何批量替换多个文件中的某个字符串?
  6. 2017西安交大ACM小学期数据结构 [分块、二维矩阵]
  7. java guava限流,Guava的RateLimiter实现接口限流
  8. OpenShift 4 - DevSecOps Workshop (Jenkins版)
  9. 图解TCPIP-ICMP
  10. Git开发错了分支,利用git的暂存完成代码转移到正确的分支
  11. MATLAB 2018b 安装与简介
  12. HDU - 6070 线段树 + 分数规划
  13. deepfake 图片_找到那张假照片!对抗Deepfake之路
  14. 将整数翻译成英文(C++)
  15. 读后感——《软件工程》——软件的本质及软件工程
  16. 不花钱,模拟登录古诗中文网
  17. 穆穆推荐-软件销售行业软件公司销售参考操作手册-之2-软件公司销售团队的组建及岗位分类
  18. Django讲课笔记02:Django环境搭建
  19. 为什么有了IP地址还要有MAC地址??
  20. 新版Win10来了!网友:丑哭了

热门文章

  1. Spring Boot idel 实现热部署
  2. excel减法函数_发现EXCEL隐藏功能,SUMIFS函数居然可以多条件求差值看了不后悔...
  3. H5 -- 微信h5页面中下载第三方app的方法
  4. cml sml区别_.CML与SML有何联系和区别?
  5. 洛谷P3009-[USACO11JAN]Profits S(DP-最大子段和)
  6. 股票权证是什么意思?正股和权证是什么意思?
  7. 领导让程序员帮他加油,看到加油卡余额!网友:中石化老总石锤
  8. 两次获得微信生态支持的如祺出行,如何破局网约车市场?
  9. 2021高考成绩查询抖音,2021抖音高考最后倒计时励志句子
  10. B-Traveling Salesman Problem[CF-Gym-102134][2016-2017 7th BSUIR Open Programming Contest]