嵌入式 - UART使用进阶

news2024/11/15 21:00:11

UART – Advanced Features

概要 / Overview

最简单直接的使用UART接口的方式,是在轮循操作中来设置和处理UART接口。 轮询式UART的问题是轮询方式本身就是低效率的。 如果我们的UART被配置为115200的波特率和8N1,那么传输一个字符需要多长时间?  每个字节的数据需要10个符号来发送。 这意味着我们每秒钟可以传输11520个字符。 这意味着1个字符大约需要86微秒的时间来发送。

86微秒可能看起来并不长,但如果我们的微处理器以50Mhz的速度运行,这相当于每个字符发送需要4341个时钟周期。 这是一个相当多的时钟周期,为了发送一串字符中的下一个字符而要一直等待。

我们将研究一些硬件和软件技术,以减少我们等待数据传输或接收的时间。

中断 / Interrupts

减少等待UART的时钟周期数的最明显方法之一是让UART产生中断。 UART中断允许主应用程序在UART不活动时执行其他任务。 UART通常产生接收和发送中断。 当有新数据到达时,UART会产生一个接收中断。 对于接收中断,应用程序和ISR之间的交互是非常直接的。  中断服务例程将新数据放入SRAM,提醒主应用程序,并清除中断。 由于中断只在数据被接收时发生,处理器可以自由地进行其他操作。

发送中断有一点不同。  一些微控制器的UART在发送缓冲区为空时产生一个中断。 这个中断是为了指示应用程序可以通过UART发送下一个字节。  我们想要避免的是这样的情况,即应用程序没有传输数据,结果UART不断产生发送数据为空的中断。这种情况会使应用程序处于空转状态,因为UART处理程序会被不断执行。 如果你使用的微控制器在Tx硬件FIFO中没有数据时不断产生Tx空中断,你可以使用以下过程来消除主应用程序的空转:

1,当UART的循环发送缓冲区为空时,UART处理程序会禁用它自己的发送空中断。 这可以防止中断的连续产生。

2,当应用程序希望发送数据时,它将数据添加到UART FIFO中,然后重新启用发送数据为空的中断。

 管道 FIFOs

在某些情况下,仅靠中断是无法减少浪费的时钟周期的。 一个例子是打印出一长串的字符。 我们可以立即发送字符串中的第一个字符到UART暂存寄存器,但我们仍然要依次发送字符串中的一个个字符,发完一个等待发送下一个。 中断可以帮助我们确定何时可以发送下一个字符,但它们并不能消除这样一个事实,即在主程序传送完所有字符之前,应用程序不能继续往前跑。

一个可以减少等待发送(或接收)字符的时间的机制是UART FIFO。 具有硬件FIFO的UART允许应用程序向UART写入一个以上的字符。 UART将写入的字符放入队列,然后一个个发送,直到FIFO为空。 我们不再需要等待单个字符的传输。 我们可以向UART发送一个字符块并立即返回。

FIFO的结果是减少中断。 只有在传输/接收了一个数据块后才会出现传输和接收中断。 每个中断都会导致上下文切换和ISR的执行。 减少中断的数量可以减少对UART中断做出反应所占用的时钟周期。

在使用FIFO时,我们需要考虑的一个特殊情况是当UART产生一个接收中断时。 带有FIFO的UART只有在接收FIFO满(或接近满)时才可能产生中断。 那么,当收到一个单字节的数据,而FIFO被配置为只在FIFO满时产生中断时,会发生什么? 我们不希望发生的是数据被卡在接收FIFO中,因为FIFO没有满。 为了避免这种情况,通常有一个接收超时中断。 当数据在接收FIFO中,但没有足够的数据来触发FIFO满的中断时,这个中断会被定期触发。

Circular Buffers( Ring buffer) 环形缓冲区

硬件FIFO也不能解决我们所有的等待问题。 硬件FIFO的大小是固定的。 如果打印的字符串超过了硬件FIFO的容量,应用程序仍将忙于等待。 由于我们不能动态地增加硬件FIFO的大小,我们将在内存中创建一个软件的数据结构来缓冲运往UART的字符。 最常用的软件结构是一个循环缓冲器。

那么,为什么我们要使用循环缓冲器而不是链表呢? 链表让我们可以自由地缓冲字符,直到SRAM用完。  我们不使用链表的原因是内存利用率。 对于存储在链接列表中的每一个字节,我们还必须分配一个下一个指针,这需要消耗4个字节。  这大概是在一个链接列表中存储字符的80%的内存开销。 由于我们的微处理器(microprocessor)中只有几KB的SRAM,这不是一个可以接受的解决方案。

另一方面,循环缓冲器的开销很小。 循环缓冲区必须存储一些关于在哪里插入下一个字符的信息,但总的来说,循环缓冲区只是一个数组。 循环缓冲区的缺点是,我们不能轻易地动态增加缓冲区的大小。 如果向循环缓冲区添加数据的速度大于从循环缓冲区删除数据的速度,数据就会被覆盖并丢失。

Producer Consumer Model 生产消费者模型

我们的UART实现将包括硬件FIFO、软件循环缓冲器、中断处理程序和主应用程序。 我们将使用生产者-消费者模型来确定何时以及如何在应用程序和中断服务程序之间进行数据通信。 发送和接收操作都需要各自的循环缓冲器,并独立检查。

  • Receive 接收

当接收数据时,UART中断服务例程将作为生产者,将字符插入到接收循环缓冲器中。 当接收或接收超时中断被激活时,ISR将从硬件FIFO中移除数据,直到硬件FIFO为空。 每个数据条目都被放入接收循环缓冲区。 当硬件FIFO为空时,ISR将清除接收中断并返回。

主应用程序充当接收FIFO的消费者。 该应用程序不直接从UART抓取数据。循环缓冲器不为空时,应用程序处理接收循环缓冲器的数据,然后删除里面的数据条目。 如果循环缓冲器中没有数据,应用程序可以选择等待(阻塞)直到数据到达,或继续进行其他操作。

我们必须考虑的一个设计问题是,当接收循环缓冲区满了,发生接收中断的情况。 当接收数据的速度超过主程序的消耗速度时,就会出现这种情况。 这种情况总是会导致数据丢失。 问题是,哪些数据会被丢弃? 最老的数据还是最新的数据? 根据我的经验,最古老的数据会被丢弃,但这个问题没有正确的答案。 在这种情况下,我们唯一真正的解决方案是实施一种流量控制(flow control)。

Application Receive Routine Flow Diagram 应用程序接收数据的流程图

ISR Receive Flow Diagram 接收中断流程图

  • Transmit 发送

当发送数据时,应用程序通过将字符插入发送循环缓冲器来提供数据。 当一个发送数据为空的中断发生时,UART ISR作为消费者,从发送循环缓冲区中取得然后删除数据。

当使用循环缓冲器发送数据时,当循环缓冲器满了会发生什么? 我们可以覆盖最旧的数据,但在大多数情况下,你应该持续等待,直到循环缓冲区不再满。 持续等待并不是最佳选择,但总比丢失数据要好。

我们要解决的另一个情况是,如果发送数据为空的中断被禁用,数据如何被发送。 如上所述,在应用程序没有数据要发送时,发送数据为空的中断被禁用。 这避免了UART ISR的不断调用。 如果我们的应用程序将数据添加到发送循环缓冲区,并且发送数据为空的中断被禁用,那么发送数据为空的中断就不会被触发,循环缓冲区中的数据也不会被UART消耗。

当我们发送数据时,应用程序将检查循环缓冲区。 如果循环缓冲区是空的,而且硬件FIFO没有满,我们将把数据直接放入硬件FIFO,并重新启用发送空中断。 其结果是UART传输硬件FIFO中的字符,当硬件FIFO为空时将产生一个新的传输中断。 然后UART ISR将检查发送循环缓冲器。 如果循环缓冲区内有数据,ISR会消耗字符,直到硬件FIFO满或循环缓冲区空。 UART将继续发送字符并产生中断,直到UART ISR检测到发送循环缓冲区为空,此时UART ISR将禁用发送空中断。

Application Transmit Routine Flow Diagram 应用程序发送数据的流程图

ISR Transmit Routine Flow Diagram 发送数据中断处理程序流程图

Race condition 竞争条件

当应用程序从循环缓冲区移除(或添加)数据时,我们必须确保修改循环缓冲区的操作是原子性的(atomic)。 原子操作的意思是,所有涉及到修改循环缓冲区的操作不能被打断。  如果我们不确保这些操作是原子的,那么就会出现一个race condition,当主程序试图修改循环缓冲区的内容时,发生UART中断,也去修改循环缓冲区内容。

由于一个指令序列只能被更高优先级的中断打断,我们不需要担心UART ISR会被应用程序打断。 另一方面,我们确实需要防止应用程序在向循环缓冲区添加或移除数据时被中断。 我们可以使用某种形式的信号semaphore,但最简单的方法是让主程序在修改循环缓冲区之前暂时禁用中断,然后在修改数据后重新启用中断。

参考:

1,UART使用进阶

UART – Advanced Features – ECE353: Introduction to Microprocessor Systems – UW–Madison

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一款支持AI思维导图的AI助手——ChatMindAI

写在前面 Hello大家好, 我是【麟-小白】,一位软件工程专业的学生,喜好计算机知识。希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正&#xff0…

“智慧水利”怎么建?这份智慧水利整体解决方案 值得参?

2021年,补齐水利信息化突出短板,提升强监管支撑能力。 2025 年,全面提升水利数字化、网络化水平,明显提升重点领域智能化水平。 2035 年,全面支撑水治理体系和治理能力现代化。 构建天空地一体化水利感知网&#xf…

python怎么使用Pillow库来添加图片水印

当使用Pillow库来添加图片水印时,下面是一个示例代码: 请确保在运行示例代码之前,已经安装了Pillow库(可以使用pip install pillow命令进行安装)。示例代码中,打开原始图片、创建透明的水印图层、绘制水印文…

计模式篇(Java):桥接模式

上一篇:计模式篇(Java):适配器模式 九、桥接模式 需求示例 当我们对不同手机类型的不同品牌实现操作编程,如图: 那么它对应的类图就是 传统方式解决需求分析: 扩展性问题,如果需要在增加手机的样式&#x…

什么是业务逻辑攻击 (BLA),大家为什么一定要要关注它?

想象一下:您的开发团队刚推出了一款令人惊叹的全新应用程序,它具有顶级的API安全性,通过客户端保护对其进行了强化,甚至还设置了针对机器人攻击的防御措施。你感到这款产品很有安全保障,自己的团队出色地完成了工作。 …

SAP从入门到放弃系列之生产执行-领用与消耗概述

文章目录导航 一、生产物资领用1.1、概述1.2、项目中自开发领料功能方式一:创建预留的方式方式二:创建UB订单方式 二、生产投料 一、生产物资领用 1.1、概述 生产的备料方式因为企业的行业特点以及企业对材料库存管理的流程设置,企业使用的…

MATLAB | 高斯变量概率密度函数的理论与实际对比

一、仿真实验目的 生成一组高斯变量,并基于生成的数据统计其概率密度函数,与理论高斯概率密度函数进行对比,观察生成的高斯变量的概率分布。 二、解决思路 (1)利用randn函数生成高斯随机变量 (2&#xf…

利用Visual Studio 2022 导出目标dll API接口

利用Visual Studio 2022 导出目标dll API接口 操作路径: 指令如下: dumpbin /exports /out:C:\\Users\\Administrator\\Desktop\\PlantSimCore.txt C:\\Users\\Administrator\\Desktop\\PlantSimCore.dll dumpbin /exports /out:C:\\Users\\Administrator\\Desktop\\

Ubuntu18.04安装Qt5.14.2

一、安装 第一步: 官网Index of /archive/qt 下载安装包, 或者国内网址下载 https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.9/5.9.0/ 我安装的是QT5.14.2 中的 qt-opensource-linux-x64-5.14.2.run ; 第二步:ctrlT 打开终端输入命…

Python的Logging模块

1.日志的相关概念🍃 日志是指记录系统或应用程序运行状态、事件和错误信息的文件或数据。在计算机系统中,日志通常用于故障排除、性能分析、安全审计等方面。日志可以记录各种信息,如系统启动和关闭时间、应用程序的运行状态、用户登录和操作…

数字化就是做系统?广州数字化转型服务公司推荐

数字化转型是一个与数字化技术密切相关的概念,很多不了解数字化转型的企业往往会认为数字化转型就是提升企业的数字化技术应用水平和不断增加数字化系统的功能,也就是将数字化转型认为是做系统。但实际上,开利网络认为,数字化转型…

使用vtk在一个窗口中创建多个几何体

引言 该示例为官网上的例子。在一个窗口中创建了多个不同的几何体。 其效果如下: 示例 开发环境 使用QtCreator4.11.2,Qt5.14.2。使用的vtk9.2的库及其头文件。创建空项目。 示例代码 其pro文件中的内容: QT core#greaterThan(QT_MAJOR_V…

【产品文档】埋点需求文档模板

今天和大家免费分享埋点需求文档模板。埋点文档的目的是帮助开发人员准确地实施埋点,并确保收集到的数据符合预期,以便后续分析和改进产品。 【模板下载】 这个模板可以在 Axure高保真原型哦 小程序里免费下载哦 【文档截图】

微搭低代码实现横向滚动效果

目录 1 添加滚动容器2 滚动内容设置总结 在小程序场景中,有很多横向滚动的效果,比如我们的官方模板电商展示里就有一个横向滚动的效果,本篇我们解读一下横向滚动该如何实现 1 添加滚动容器 不管是横向滚动还是纵向滚动,我们都是依…

【Python】NLP参数控制模板

前言 学过AI的都知道训练一个模型需要调整很多参数,为了有效的管理这些参数、不至于让代码的参数写的乱七八糟,有必要写一套控制参数的模板。 argparser argparser是python当中的参数解析器,在NLP当中主要是用来接受和使用参数的。一个使用它…

Word技巧【自用】

表格断开 做到类似这样的效果,很简单,用边框刷就可以 设定边框的横线,以及磅值,就可以像画三线表一样断开了

vue el-dialog嵌入video实现视频播放功能

video嵌入dialog实现视频播放 业务需求1、实现的效果图3、全部代码(复制粘贴即可实现) 业务需求 弹窗实现视频播放&#xff0c;并且切换不同选项卡播放不同视频 1、实现的效果图 3、全部代码(复制粘贴即可实现) <template><el-button style"margin-left: 60px&q…

警惕: 新的 “RustBucket “恶意软件变种针对macOS用户

研究人员已经揭开了苹果macOS恶意软件RustBucket更新版本的序幕&#xff0c;该版本具有改进的能力&#xff0c;可以建立持久性并避免被安全软件发现。 安全实验室的研究人员在本周发表的一份报告中表示&#xff1a;RustBucket的变种是一个针对macOS系统的恶意软件集合&#xf…

Cisco ISR 1000 Series IOS XE Release Dublin-17.11.1a ED

Cisco ISR 1000 Series IOS XE Release Dublin-17.11.1a ED 思科 1000 系列集成多业务路由器 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-isr-1000/&#xff0c;查看最新版。原创<品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 思科 1000…