笔者在实际开发中多次用到串口的循环buffer,最开始在网上搜索了相关文章和资料,感觉通用性不是很高。自己也写过fifo,感觉还是过于臃肿。一直想找个完美的循环buffer。在看linux内核代码时,发现内核里面也经常使用fifo。linux内核代码是最优美、精简的,高效的代码。真是“山穷水尽疑无路,柳暗花明又一村”。特意移植除出来,希望对大家有用。代码设计的相当的巧妙~~~

头文件:

/*******************************************************************************
* @File      : fifo.h
* @Author   : cqx
* @Version  : V0.0.1
* @Date      : 29-november-2016
* @Brief     : This file provides all the fifo functions.
********************************************************************************
* @Attention:
* Non
*
*******************************************************************************//* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _FIFO_H
#define _FIFO_H#include <stm32f10x.h>#ifdef __cplusplusextern "C" {
#endif/* Includes ------------------------------------------------------------------*/
/* Define --------------------------------------------------------------------*/
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif      #define is_power_of_2(x)    ((x) != 0 && (((x) & ((x) - 1)) == 0))/* Private typedef -----------------------------------------------------------*/
struct fifo {unsigned int   in;unsigned int out;unsigned int    mask;unsigned char *data;
}; /* Function prototypes -------------------------------------------------------*/
extern unsigned int fifo_used(struct fifo *fifo);
extern signed int fifo_alloc(struct fifo *fifo, unsigned int size);
extern void         fifo_free(struct fifo *fifo);
extern int          fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size);
extern unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len);
extern unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len);#ifdef __cplusplus
}
#endif#endif

源文件:

/******************************************************************************
* @File      : ringbuffer.c
* @Author   : cqx
* @Version  : V0.0.1
* @Date      : 29-november-2016
* @Brief     : This file provides all the fifo functions.
******************************************************************************
* @Attention:
*
*
******************************************************************************/
/* Includes -----------------------------------------------------------------*/
#include "fifo.h"
#include "stdlib.h"
#include "string.h"
#include "includes.h"/* Variables -----------------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/******************************************************************************//** internal helper to calculate the unused elements in a fifo*/
static __inline unsigned int fifo_unused(struct fifo *fifo)
{return (fifo->mask + 1) - (fifo->in - fifo->out);
}unsigned int fifo_used(struct fifo *fifo)
{return (fifo->in - fifo->out);
}signed int fifo_alloc(struct fifo *fifo, unsigned int size)
{
/** round down to the next power of 2, since our 'let the indices* wrap' technique works only in this case.*/if (!is_power_of_2(size))return -1;fifo->in = 1;fifo->out = 1;if (size < 2){fifo->data = NULL;fifo->mask = 0;return -1;}fifo->data = malloc(size);if (!fifo->data){fifo->mask = 0;return -1;}  fifo->mask = size - 1;return 0;
}void fifo_free(struct fifo *fifo)
{free(fifo->data);fifo->in = 0;fifo->out = 0;fifo->data = NULL;fifo->mask = 0;
}int fifo_init(struct fifo *fifo, unsigned char *buffer, unsigned int size)
{if (!is_power_of_2(size))return -1;fifo->in = 0;fifo->out = 0;fifo->data = buffer;if (size < 2) {fifo->mask = 0;return -1;}fifo->mask = size - 1;return 0;
}static void fifo_copy_in(struct fifo *fifo, unsigned char *src, unsigned int len, unsigned int off)
{unsigned int size = fifo->mask + 1;unsigned int l;off &= fifo->mask;l = min(len, size - off);memcpy(fifo->data + off, src, l);memcpy(fifo->data, src + l, len - l);
}unsigned int fifo_in(struct fifo *fifo, unsigned char *buf, unsigned int len)
{unsigned int l;l = fifo_unused(fifo);if (len > l)len = l;fifo_copy_in(fifo, buf, len, fifo->in);fifo->in += len;return len;
}static void fifo_copy_out(struct fifo *fifo, unsigned char *dst, unsigned int len, unsigned int off)
{unsigned int size = fifo->mask + 1;unsigned int l;off &= fifo->mask;l = min(len, size - off);memcpy(dst, fifo->data + off, l);memcpy(dst + l, fifo->data, len - l);
}unsigned int fifo_out_peek(struct fifo *fifo, unsigned char *buf, unsigned int len)
{unsigned int l;l = fifo->in - fifo->out;if (len > l)len = l;fifo_copy_out(fifo, buf, len, fifo->out);return len;
}unsigned int fifo_out(struct fifo *fifo, unsigned char *buf, unsigned int len)
{len = fifo_out_peek(fifo, buf, len);fifo->out += len;return len;
}

实际的使用例程见下一篇博文:

stm32循环buffer数据处理实例

stm32实用循环buffer相关推荐

  1. linux+循环buffer,说说循环缓冲区(Ring Buffer)

    关于循环缓冲区(Ring Buffer)的概念,其实来自于Linux内核(Maybe),是为解决某些特殊情况下的竞争问题提供了一种免锁的方法.这种特殊的情况就是当生产者和消费者都只有一个,而在其它情况 ...

  2. 圆形缓冲区(循环buffer)实现

    用法 圆形缓冲区的一个有用特性是:当一个数据元素被用掉后,其余数据元素不需要移动其存储位置.相反,一个非圆形缓冲区(例如一个普通的队列)在用掉一个数据元素后,其余数据元素需要向前搬移.换句话说,圆形缓 ...

  3. stm32实用篇3: 字符显示字库生成

    在使用stm32显示文本时,首先要使用字模软件生成字库,如下: 这里,使用的是Consolas字体,点阵大小为16*16(汉字),此时英文字体的大小为8*16,宽度为汉字字体的一半,然后设置选项参数( ...

  4. DMA工作原理-STM32 DMA和ARM9 DMA,彻底理解DMA

    前序 网上文章一大堆都有介绍DMA的作用,是直接内存获取控制器,但由于用途的局限或者用在了复杂的外设上面,导致没有很好的把DMA的作用说的很系统,本人也是根据网上的资料,进行一些DMA的总结,个人觉得 ...

  5. STM32串口DMA接收双缓冲

    STM32高端MCU(F4.F7等)才支持DMA双缓冲,低端MCU(F1)不支持DMA双缓冲,不过有替代方案可实现类型效果. 一.MCU支持DMA双缓冲的情形 不再赘述,参见博客 STM32 串口DM ...

  6. stm32怎么基于ds1302实现闹钟功能,不使用定时器

    在STM32上实现基于DS1302的闹钟功能需要使用I2C总线进行通信. 步骤如下: 配置STM32的I2C接口,并初始化DS1302. 读取DS1302上的时钟数据,并将其存储到STM32的内存中. ...

  7. Java 日志缓存机制的实现--转载

    概述 日志技术为产品的质量和服务提供了重要的支撑.JDK 在 1.4 版本以后加入了日志机制,为 Java 开发人员提供了便利.但这种日志机制是基于静态日志级别的,也就是在程序运行前就需设定下来要打印 ...

  8. java 串口判断报文完整_如何判断串口接收完成一帧数据

    1 使用定时器判断 这种方式建立在两帧数据不可能连续发送的基础上,也是modbus判断帧结束的方式,在接收到第一个字节的时候打开定时器,如果继续接收到数据则更新定时器,在被设定时间内没有接收到数据则定 ...

  9. signal tap

    Signal Tap II有助于观察逻辑内部信号行为,可使不借助外部设备进行设计调试.(当然使用的前提条件是有硬件平台) Signal Tap II ELA 组成框图 采样获得的数据会存储在器件的存储 ...

最新文章

  1. GCC中的内嵌汇编语言
  2. 计算机原理课程设计陈宏,东北大学计算机组成基础原理课程教学设计.doc
  3. 使用Spring Security的多租户应用程序的无状态会话
  4. 设置TextView为下划线的样式
  5. [转] dpkg-deb命令
  6. Java常用性能分析工具 jconsole、jvisualvm、 jstat、jinfo、jmap、jhat、jstack
  7. IOT---(8)四大物联网通信技术差异:NB-IoT 、LTEeMTC、LoRa与SigFox
  8. Struts2学习笔记(十六) 文件上传(File Upload)
  9. IOS NSLayoutConstraint 页面布局(通过代码添加约束)
  10. Android 属性动画简单说明前篇(一)
  11. atitit.MyEclipse10 中增加svn插件故障排除
  12. 数学方法论选讲---第一章 引论
  13. 使用 Entrust Lar…
  14. 2021湖南高考成绩查询考生版,湖南省普通高校招生考试考生综合信息平台入口2021...
  15. python PIL将图片转换成九宫格拼图样式
  16. 卜若的代码笔记-unityshader系列-第十七章:Shader练习.遮罩(Shader采样Image的Sprite)
  17. java 线程管理_Java提供的线程池来创建多线程,进一步优化线程管理。
  18. 奥比中光 ORBBEC Astra Mini Pro简单使用
  19. 智能耳机测试软件,讯飞又一精品,讯飞智能耳机全面评测:商务福音
  20. 技术型产品,既要轻速度,也要重壁垒

热门文章

  1. Web服务器 之 FC4下安装plog快速指南(plog版本:1.01)
  2. PHP日志系统 plog(PHP)
  3. 聚焦核心业务,降本增效
  4. 量子物理史话——上帝掷骰子吗
  5. IDEA WebLogic远程调试
  6. 项目管理中快速制定高质量目标四个步骤
  7. 互联网电视的囚徒困境,价格与营销之外,还得看产品本身
  8. 亏钱的时候,有没有想起我说的。
  9. 古琴:高山流水,难遇知音
  10. 有颜值、会说话的文字,意境满满!