FIFO是什么?

FIFO( First Input First Output) 简单说就是指先进先出。它是一种数据存储或传输模式,可以硬件实现也可以软件实现,大多数用来缓存数据,减少操作次数,提高传输效率。

串口实现中其实在两处运用了FIFO。一处是串口控制器硬件内部可能会提供收发FIFO支持,一处是在驱动框架层提供了软件实现的数据收发FIFO。这里只介绍硬件FIFO的特性和用法。

没有硬件FIFO的串口只有一个数据接收寄存器和一个数据发送寄存器(这两寄存器可能是同一地址,读时访问接收寄存器,写时访问发送寄存器),每接收或发送一个字节后必须等待收发完成后才能进行下一字节操作,否则就会出现发送或接收处错误,造成数据丢失。而有FIFO的串口控制器,只要收发数据长度不超过FIFO 深度就不会出现溢出错误,同时能大幅减少收发完成中断,减少CPU占用。

无FIFO或FIFO较浅的串口控制器,对系统的实时性要求较高。比如串口以115200波特率进行收发,每字节包括1个起始位8个数据位1个停止位(没考虑有校验位的情况)传输时间大约是86微秒。如果是轮询模式,为保证在满载传输的极限情况下也不丢数据的话,则轮询周期就要小于86微秒,自然每次轮询的执行耗时就必须小于86微秒,对于与一些主频和内存性能比较低的处理器,86微秒的执行耗时还是很有挑战的。同时还要注意轮询任务还可能会被中断和高优先级任务抢占,而中断与中断之间,任务与任务之间也可能是嵌套抢占的,那对于轮询任务就存在一个最大的抢占时间,这个抢占时间加上自身的执行耗时假设为Tmax,则Tmax不超过86微秒才能保证最坏情况下不丢失数据,这个要求其实就很苛刻了。

如果计算性能不够又必须保证最坏情况下也不能丢帧,解决办法有三种方法:

  1. 降低波特率,比如波特率是9600时,Tmax小于1041微秒即可。
  2. 串口控制器提供接受FIFO,FIFO深度越大实时性要求越低。比如同样是115200波特率下,FIFO深度为32时,则Tmax小于2777微秒即可。
  3. 使用DMA模式,DMA模式其实相当于一个深度可任意配置的FIFO。比如同样是115200波特率下,DMA缓冲区设置为128,则Tmax小于11111微秒即可。

发送操作

轮询模式

方法1:

  1. 等待发送FIFO空。
  2. 写入1字节到发送FIFO。
  3. 等待FIFO空,即等待发送完成,返回步骤1再进行一下字节发送。

这中方式的操作步骤和效果其实都和无FIFO下相同,传输效率和FIFO深度无关,CPU消耗时长等于发送数据在串口上的传输时间,效率最低。

方法2:

  1. 等待发送FIFO非满。
  2. 写入n字节到发送FIFO,直到FIFO满或无数据可写入。
  3. 等待FIFO非满,返回步骤1,如此循环直到无数据可写入。

如果一帧数据全部写入,FIFO都未满,则CPU消耗时只等于n字节的内存传输时间。否则因为内存传输远快于串口传输后半段的数据其实是每发送完一字节就要向FIFO添加一字节,效果和方法1相似。应用上如果是间隔的短帧则效率较高,而如果是长帧或连续流数据则效率趋近于方法1。

方法3:

  1. 等待FIFO非满。
  2. 写入n字节到发送FIFO,直到FIFO满或无数据可写入。
  3. 等待FIFO空,返回步骤1,如此循环直到无数据可写入。

应用上如果是间隔的短帧和方法2效果一样。如果是满载发送状态则是填满FIFO后,等待FIFO全空,再重新填满发送,需要轮询的频率就很低,当传输FIFO深度的数据耗时大于系统一个心跳时间时,轮询中就可以加入休眠操作,让出CPU。这样实际的CPU消耗也不会很大,但这需要FIFO深度够长串口波特率够低,系统心跳够快的情况下才可以。

中断模式

有FIFO的串口控制器需要关闭发送完成中断(每发送完成一字节都会触发),打开FIFO空中断。
方法1:
1.写入1字节到发送FIFO。
2. 等待发送FIFO空中断。
3. 在中断服务函数中,如果是发送FIFO空中断,检测是否还有数据要发送,如果有就继续写入1字节到发送FIFO。如此循环直到数据发送完成。

这种方式其实没有起到FIFO的作用,和无FIFO的效果是一样的,启动时字发送1字节,后续发送都是在中断中进行的,每次发送1字节。不需要循环等待发送完成,CPU主要消耗在中断服务上,且每发一字节就要触发一次中断。

方法2:

  1. 写入n字节到发送FIFO,直到FIFO满或无数据可写入。
  2. 等待发送FIFO空中断。
  3. 在中断服务函数中,如果是发送FIFO空中断,检测是否还有数据要发送,如果有就继续写数据到发送FIFO,直到FIFO满或无数据可写入。如此循环直到数据发送完成。

与方法1相比,利用硬件FIFO的支持,大幅减少了中断触发的次数,从而减少了CPU中断服务时间,提高了效率。这种模式在效率上已近很接近于DMA模式了,而且更通用更容易实现,绝大部分的串口驱动都是这种模式。

方法3:
过程与方法2一样,但触发FIFO空的条件并不是FIFO里的数据已完全传输完成,而是FIFO中剩余的数据小于某长度时(如小于2字节)就触发中断。这样处理会使得中断触发次数略微增加,但保证了在需要满载发送时,在串口线路上数据是一直连续没有中断的。

接收操作

轮询模式

方法一:
1.轮询接收FIFO状态是否为空。
2.如果接收FIFO非空,则读取FIFO中的数据,直达接收FIFO为空。

轮询模式下CPU消耗取决于轮询的频率,频率越高接收越实时,CPU消耗也越大;频率越低,CPU消耗越小,但实时性越低,甚至会因为接收不及时造成接收溢出错误而丢失数据。
相比于没有FIFO的串口控制器,有FIFO的可以设置更低的轮询频率而不会出现数据丢失的风险。

中断模式

有FIFO的串口控制器需要关闭接收完成中断(每接收一字节都会触发),打开接收FIFO满中断。
方法1:
1.等待接收FIFO中断。
2.在中断服务函数中,只要接收FIFO非空,就读取全部就收数据。

  • 这种模式下CPU的消耗主要消耗在中断服务上,中断触发的频率越高消耗就越大。
  • 这个过程很简单,但也存在一些问题。主要是应该或能够设置什么条件下触发串口中断。
  • 首先一点,其实无论是任何串口中断触发了中断服务函数的调用过程,都应该去检查接收FIFO是否为空。
  • 如果是接收FIFO非空就触发中断,因为内存访问速度远大于串口传输速度,实际就会是每收1字节就会触发一次中断,中断频率是最高的,和无FIFO串口效果一样。
  • 如果是FIFO全满才触发中断,则能大幅减少中断频率。但也会存在问题,一个是如果中断响应较慢而数据是满载接收的,就会增加接收溢出的概率。再有就是如果接收完一帧数据后FIFO未满,后面又很久无数据接收,就会造成接收响应严重滞后,在很多应用情景下这是不能接收的。
  • 如果是半满或接近于满时触发中断,就不会有接收溢出风险,但接收响应还是可能会严重滞后。

为了解决以上问题,就得增加一种机制,在接收不满且超出一定时间无数据接收后,就要处理已收到的数据。可以通过软件方法来实现,如定时器,轮询线程等,这些方法通用性强但效率低。

这个问题明显存在的,设计串口控制器的工程师自然也能想到,所以很多串口控制器现在都具备一个硬件接收超时或空闲检查功能,在接收状态改变为空闲状态后,超过配置时间还没有数据接收,也会触发一个超时接收中断。

串口驱动中使用FIFO相关推荐

  1. WinCE中串口驱动及接口函数介绍(转载)

    作者:ARM-WinCE 在WinCE中,串口驱动实际上就是一个流设备驱动,具体架构如图: 串口驱动本身分为MDD层和PDD层.MDD层对上层的Device Manager提供了标准的流设备驱动接口( ...

  2. 【转载】WinCE中串口驱动及接口函数介绍

    转载自:http://blog.csdn.net/nanjianhui/article/details/2627755 在WinCE中,串口驱动实际上就是一个流设备驱动,具体架构如图: 串口驱动本身分 ...

  3. WinCE中串口驱动及接口函数介绍

    作者:ARM-WinCE 在WinCE中,串口驱动实际上就是一个流设备驱动,具体架构如图: 串口驱动本身分为MDD层和PDD层.MDD层对上层的Device Manager提供了标准的流设备驱动接口( ...

  4. linux串口驱动分析

    linux串口驱动分析 硬件资源及描写叙述 s3c2440A 通用异步接收器和发送器(UART)提供了三个独立的异步串行 I/O(SIO)port,每一个port都能够在中断模式或 DMA 模式下操作 ...

  5. linux串口驱动分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/11946591 硬件资源及描述 s3c2440A 通用异步接收器和发送器(UART)提供了 ...

  6. GPS NMEA 0183 4.10协议/GPS Linux串口驱动

      NMEA 0183是美国国家海洋电子协会(National Marine Electronics Association)为海用电子设备制定的标准格式.现在已经成为GPS导航设备统一的RTCM(R ...

  7. linux 串口驱动 理解,linux 串口驱动 理解

    linux 串口 驱动 理解 一.核心数据结构 串口驱动有3个核心数据结构,它们都定义在 1.uart_driver uart_driver包含了串口设备名.串口驱动名.主次设备号.串口控制台(可选) ...

  8. 串口驱动程序设计详解---串口打开、发送、接收(下)

    上一篇博客分析了串口驱动初始化部分,下面逐步分析串口驱动中的打开串口,数据发送和接收! 初始化主要工作流程: 先来分析串口打开操作流程,还是先上图: 这里分析还是离不开上篇博客中的两张重要的图: 串口 ...

  9. 从串口驱动到Linux驱动模型,想转Linux的必会!

    关注.星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 本文通过对Linux下串口驱动的分析.由最上层的C库.到操作系统系统调用层的封装.再到tty子系统的核心.再到一系列线路规程.再到 ...

最新文章

  1. (原创)c++中的类型擦除
  2. arcgis重心迁移分析_山东省植被覆盖度变化与气候因子相关性分析
  3. php能打开.shp文件吗,shp文件是什么格式的
  4. oracle更换rac节点,Oracle-rac 更改VIP地址—2节点的
  5. mac 下的实用工具总结
  6. 单片机的最新发展动态_【计算机论文】单片机在节能、语言交流和智能监控上的应用...
  7. 说说从URL输入到页面展现的过程
  8. Vim新手必看:Vim 命令图解
  9. css悬浮在某个span后面,在contenteditable div中的span元素后面设置光标
  10. bzoj 1619: [Usaco2008 Nov]Guarding the Farm 保卫牧场(DFS)
  11. 游戏测试-----------------第3章
  12. U盘量产失败后无法找驱动U盘的解决方法。
  13. MySQL模糊查询用法大全(正则、通配符,mybatis入门
  14. python的文件操作和异常处理
  15. Jzoj4699 Password
  16. 下载好的IDEA双击打不开,解决方法
  17. 螃蟹在剥我的壳,笔记本在写我。 漫天的我落在枫叶上雪花上。 而你在想我。
  18. 大数据和云计算技术周报(第102期)
  19. 递归和循环两种方法完成树的镜像转换
  20. 苹果WWDC将于6月8日夏季发布会苹果WWDC发布会直播地址

热门文章

  1. 华为云-实时流计算服务CS
  2. IGMP PROXY和IGMP SNOOPING 有什么区别?
  3. [转]IT人的学习方法
  4. 计算机和学生的关系的英语作文,学生和老师的关系的英文作文
  5. Rotatable2DMap旋转2D地图
  6. 真假4K电视检测:一张图足矣
  7. 【毕业设计_课程设计】基于大数据个性化音乐推荐算法分析
  8. ITiM v2.0 闪亮发布,十年磨砺,倚天出鞘!
  9. Cesium ClippingPlane剖切 改造 限高分析
  10. 信贷风控指南丨人工智能专家直播解析信贷评分卡模型