重新启动基于中断的数据传输(C ++,数据缓冲区,硬件外设和中断)

时间:2018-05-31 00:12:44

标签: c++ oop buffer interrupt transmission

我最关心的是在"裸机上编写C ++代码"基于微控制器的嵌入式系统(无操作系统或RTOS)。我有一个问题,我曾经多次遇到各种各样的形式,在我看来,没有"优雅的"解决方案。它让我再次困扰我,所以我想我会在这里提出它,看看是否有人能提出更好的方法...

该问题通常涉及在硬件外围设备和存储器中的数据缓冲器之间移动数据以响应硬件外围设备产生的中断。一个简单的例子是通过UART接收和发送数据,输入(接收)字节和输出(发送)字节通过两个基于RAM(通常是环形)的缓冲器缓冲,UART硬件产生两个独立的中断 - 字节接收(又名Receiver Not Empty)和Byte Transmitted(又名Transmitter Empty)。为简单起见,我们假设不涉及硬件FIFO或DMA,不会出现错误情况(奇偶校验错误,缓冲区溢出等),并且没有操作系统或RTOS。

处理传入(接收)数据很容易。每当UART接收到一个字节时,它就会触发它的字节接收中断,并且中断处理程序从UART的接收器读取字节并将其写入输入数据缓冲器。如果"发件人"用完要发送的数据,UART停止接收字节,因此它停止触发它的字节接收中断和中断处理程序代码"自动"停止将数据从UART传输到缓冲区。当"发件人"恢复发送数据,UART恢复接收字节并触发它的字节接收中断,因此中断处理程序代码"自动"恢复将数据从UART传输到缓冲区。其他一些进程可以异步地从传入数据缓冲区中消耗(读取和处理)接收到的字节,并且此代码必须处理的唯一复杂因素是传入缓冲区可能为空(无数据可用)。重要的是,请注意,实现传入数据缓冲区的代码和使用已放入传入缓冲区的接收字节的代码都不需要执行任何操作来启动和停止从UART到传入的接收字节流数据缓冲,因此他们不需要知道任何关于"接收数据的硬件的具体细节以及如何控制它(即UART及其中断)。这个"知识"只需要存在于UART驱动程序和中断处理程序代码中,因此缓冲区和接收到的数据消耗代码可以非常通用"。这一切都非常简单,在我看来“相当优雅"。

但它处理传出(传输)的数据让我很烦恼。让我们开始假设在传出缓冲区中已经有等待传输的字节,我们已经在传输它们了。每次UART发送一个字节时,它都会触发它的字节发送中断,中断处理程序代码从输出数据缓冲区读取下一个字节并将其写入UART的发送器,然后重复该过程。 ..直到传出数据缓冲区中没有更多数据。此时,当UART发送最后一个字节并触发它的字节发送中断时,中断处理程序代码发现输出数据缓冲区为空并且没有更多字节要发送,因此它禁用了UART发送器&#39 ; s中断以阻止它持续发射。之后,其他一些进程异步地将更多字节写入传出数据缓冲区,为UART传输做好准备。但要获得传出的数据"流动"有些事情需要重新启动UART发送周期,可能是通过重新启用UART的字节发送中断,以便中断再次触发,中断处理程序将继续将字节从输出数据缓冲区移动到UART&#39 ;发射器。正如我所看到的,这意味着传出的缓冲区代码,或者将数据写入传出缓冲区的过程,必须知道"关于需要重新启动传出数据流,并且必须做一些特别的事情"启动此操作通常会导致写入的传出缓冲区代码专门用于UART(或其他特定硬件),以便它知道如何重新启用硬件的传输中断。这也很容易做到,而且或多或少都是我迄今为止做到的,但与上面描述的接收过程相比,这似乎总是有点"不够优雅&# 34。

我处理这个问题的另一种方法是让一个独立的代码位定期检查输出缓冲区中是否有任何数据,如果是这样,重新启用发送中断,但这似乎有点"小于优雅&#34 ;.它增加了开销,增加了添加到缓冲区的数据与实际开始传输之间的延迟,如果你不知道这个独立的代码位是从某个地方重复运行的话,很难看出它是如何工作的。

事实上,正如我所看到的,在优雅的#34;我希望解决方案,传入和传出缓冲区应该能够完全相同的代码(同一类的两个实例),并且应该对它们所连接的硬件一无所知"连接到"。类似地,从缓冲区读取和写入缓冲区的应用程序代码也不需要知道缓冲区连接到"的硬件。这将使所有这些代码非常通用,然后应该很容易改变数据缓冲区的哪个硬件接口连接到"通过仅更改哪些中断处理程序"连接到"哪个数据缓冲,无需以任何方式更改缓冲区或应用程序代码......?

但是我认为需要重新启动发送周期"防止这种情况我很想知道是否有人可以推荐解决方案或整体更好的方法。

感谢你,

马丁。

0 个答案:

没有答案