涉及到数据通信的软件开发,不能回避的一点是,设计一个实用高效率的数据缓冲区,例如fifo。今天在做项目时候,需要缓存CAN总线上的数据,然后再需要的时候读这些数据。下边给出我自己设计的,采用循环数组实现的FIFO,未经过严格的测试,请您斟酌。需要指出的是,fifo的数组深度是256,采用的数组下标是unchar类型,当下标在0xff加1,到达数组末端时,刚好unchar类型的下标溢出为0,这样免去了手动修改下标。先看代码:

#pragma once

#include <string.h>
#include "afx.h" #define BUF_MAX 256 struct _fifo
{
int buf[BUF_MAX];    /* 预设最大深度256的fifo,这里元素是int,当然可以使其他自定义类型 */
unsigned char in;    /* 下次插入fifo的数组下标 */
unsigned char out;    /* 下次fifo出数据的下标 */
unsigned short num;   /* fifo中数据元素的个数 */
CRITICAL_SECTION cs;  /* 共享数据保护,在windows下采用临界区机制 */
};

/* 初始化fifo结构 */
static void __init_fifo(_fifo* pf)
{
memset(pf->buf, 0, sizeof(pf->buf));
pf->in=0;
pf->out=0;
pf->num=0;
InitializeCriticalSection(&pf->cs);
} static unsigned char __in_fifo(_fifo* pf, int data)
{
unsigned char rt;
EnterCriticalSection(&pf->cs);
pf->buf[pf->in]=data;
pf->in++;
if (pf->in==pf->out)
{
pf->out++;
rt=0xFF;
}
else
{
pf->num++;
rt= 0;
}
LeaveCriticalSection(&pf->cs);
return rt;
} static unsigned char __out_fifo(_fifo* pf, int* data)
{
unsigned char rt;
EnterCriticalSection(&pf->cs);
if (pf->in==pf->out)
{
rt= 0xFE;
}
else
{
*data=pf->buf[pf->out];
pf->out++;
pf->num--;
rt=0;
}
LeaveCriticalSection(&pf->cs);
return rt;
} static void _uninit_fifo(_fifo* pf)
{
DeleteCriticalSection(&pf->cs);
}

向fifo插入数据

(1)条件:任何条件下都允许插入数据;

(2)操作:data-->buf[in]; in++;  此时考虑2中情况,in==out?时,说明队列已经满了,此时将最“老”的数据丢掉,out++;若in!=out,则不需要操作。

(3)返回值:当(2)中发生丢数据时,报出返回值ff,指示数据溢出,fifo还可以正常工作;没有丢数,则正常返回00

从fifo中取数据

(1)条件:需满足,in!=out。

(2)操作:满足(1)时,执行buf[out]-->data, out++.  返回值说明取数据操作是否成功。

如果fifo数组长度BUF_MAX与数组下标(in,out)不满足2^8=256时,则需要增加修改下标的逻辑,在每次++的时候判断即可。

循环数组实现FIFO的更多相关文章

  1. c++利用循环数组建立FIFO模板队列

    可直接编译运行,其中status()方法效果如图: #include <iostream> using std::cout; template<typename T> clas ...

  2. 前端开发:setTimeout与setInterval 定时器与异步循环数组

    前端开发:setTimeout与setInterval 定时器与异步循环数组 前言: 开通博客园三个月以来,随笔记录了工作中遇到的大大小小的难题,也看过无数篇令人启发的文章,我觉得这样的环境是极好的, ...

  3. lintcode循环数组之连续子数组求和

    v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. ...

  4. 51nod 1050 循环数组最大子段和

    题目链接:51nod 1050 循环数组最大子段和 #include<stdio.h> #include<algorithm> using namespace std; ; l ...

  5. 深入理解循环队列----循环数组实现ArrayDeque

    我们知道队列这种数据结构的物理实现方式主要还是两种,一种是链队列(自定义节点类),另一种则是使用数组实现,两者各有优势.此处我们将要介绍的循环队列其实是队列的一种具体实现,由于一般的数组实现的队列结构 ...

  6. 1042 数字0-9的数量 1050 循环数组最大子段和 1062 序列中最大的数 1067 Bash游戏 V2 1092 回文字符串

    1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 给出一段区间a-b,统计这个区间内0-9出现的次数.   比如 10-19,1出现11次 ...

  7. 【循环数组的最大字串和】Maximal-sum Subsequence

    [循环数组的最大字串和]Maximal-sum Subsequence PROBLEM 题目描述 给一个 N×N 的矩阵 M,可以取连续的一段数(必须是横着或者竖着或者斜着,这个矩阵是循环的,具体如下 ...

  8. shell 循环数组

    循环数组 ;i<${#o[*]};i++)) do echo ${o[$i]} done

  9. 整理JavaScript循环数组和对象的方法

    众所周知,常用的循环语句有for.while.do-while.for-in,forEach以及jQuery中提供的循环的方法:以及ES6中提供的很多用来循环对象的方法如map, 在 Javascri ...

随机推荐

  1. Phython-守护线程

    import threading,time def run(n): print("task is ",n) time.sleep(2) print("task done& ...

  2. CSM(Certified Scrum Master) 敏捷认证是什么?

    Scrum 是用于开发和持续支持复杂产品的一个框架.Scrum 基于试验性过程控制理论,借鉴了精益思想.时间盒.模块化设计等,并完整地体现了敏捷宣言和敏捷原则.Scrum 采用一种迭代.增量式的方法来 ...

  3. C#面向对象15 多态

    多态 概念:让一个对象能够表现出多种的状态(类型) 实现多态的3种手段:1.虚方法 2.抽象类 3.接口 1.虚方法 步骤:1.将父类的方法标记为虚方法,使用关键字 virtual,这个函数可以被子类 ...

  4. 解决VS2015 不能设置下面的断点**** 断点未能绑定

    解决VS2015   不能设置下面的断点**** 断点未能绑定 1. 清理解决方案  ,  重新生成解决方案 ,  无效!! 2. 选项-- 调试 -- 启用编辑并继续     无效!! 3.   启 ...

  5. Java8 常用Function、Predicate、Consumer、Supplier接口

    1.常用函数是接口: (1)Function<T, R> => R apply(T t) ———— 接受一个T类型的参数,返回R类型结果. Function<Integer, ...

  6. useradd 报Creating mailbox file: File exists

    问题描述:增加一个用户时,报下面的错误:[root@master ~]# useradd hadoopuseradd: warning: the home directory already exis ...

  7. 第六章· MySQL索引管理及执行计划

    一.索引介绍 1.什么是索引 1)索引就好比一本书的目录,它能让你更快的找到自己想要的内容. 2)让获取的数据更有目的性,从而提高数据库检索数据的性能. 2.索引类型介绍 1)BTREE:B+树索引 ...

  8. Java面向对象(三) 【面向对象深入:抽象类,接口,内部类等】

    面向对象(Object Oriented) 1.抽象类抽象就是将拥有共同方法和属性的对象提取出来.提取后,重新设计一个更加通用.更加大众化的类,就叫抽象类.1)abstract 关键字修饰类.方法,即 ...

  9. RHEL7中配置本地YUM软件源

     1.创建目录,挂载光盘 [root@localhost ~]# mkdir /mnt/iso [root@localhost ~]# mount /dev/sr0  /mnt/iso mount: ...

  10. 7.控制计划任务crontab命令

    at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的Linux 系统上面原本就有非常多的计划 性工作,因此这个系统服务是默认 ...