gpt4 book ai didi

c - 基于低延迟中断的传输代码中的不当行为

转载 作者:太空宇宙 更新时间:2023-11-04 02:40:13 24 4
gpt4 key购买 nike

假设您有一些数据传输外围设备,例如 UART,它会在准备好传输更多数据时发出中断信号。我们从一个循环缓冲区发送数据,其中 tail 是数据被移除的地方,head 是你添加数据的地方,tail == head 表示没有更多的数据要传输。

我们还假设外设没有任何缓冲,并且您不能在它忙于发送当前值时将下一个要发送的值传递给它。如果您需要一个具体的、虚构的示例,请考虑将移位寄存器直接连接到 CPU 的并行 I/O 端口。

为了让发送器尽可能忙碌,您可能希望在进入发送中断处理程序后立即发送。当没有数据要传输时,中断被屏蔽掉,即使中断已经准备好,处理程序也不会被调用。系统在屏蔽中断的情况下启动。

我将使用 C 来说明事情,尽管这个问题不是特定于 C 的。中断处理程序和缓冲区设置如下:

char buf[...];
char * head = buf; ///< write pointer
char * tail = buf; ///< read pointer
char * const first = buf; ///< first byte of the buffer
char * const last = buf+sizeof(buf)-1; ///< last byte of the buffer

/// Sends one byte out. The interrupt handler will be invoked as soon
/// as another byte can be sent.
void transmit(char);

void handler() {
transmit(*tail);
if (tail == last)
tail = first;
else
tail++;
if (tail == head)
mask_interrupt();
}

到目前为止,还不错。现在让我们看看如何实现 putch()。我们可以比设备发送数据的速度更快地突发调用 putch()。假设调用者知道不会溢出缓冲区。

void putch(char c) {
*head = c;
if (head == last)
head = first;
else
head++;
/***/
unmask_interrupt();
}

现在假设这些事情发生了:

  1. 发送器正忙,当调用 putch 时,正在发送一个字节。
  2. putch 位于上面标记为 /***/ 的位置时,传输恰好完成。 handler() 正好在那里执行。
  3. handler() 恰好发送缓冲区中数据的最后一个字节 - 我们刚刚在 putch() 的前几行中加载的字节。

处理程序屏蔽了中断,因为没有更多数据要发送,但是 putchhandler() 返回后立即错误地取消屏蔽它。因此 handler 将再次通过缓冲区,并发送缓冲区的陈旧数据直到 tail 再次等于 head

我的问题是:增加延迟并在发送处理程序之前检查空缓冲区的唯一修复方法是什么?修复后的代码如下所示:

void fixed_handler() {
if (head == tail) {
mask_interrupt();
arm_interrupt(); // so that next time we unmask it, we get invoked
return;
}
transmit(*tail);
if (tail == last)
tail = first;
else
tail++;
}

此修复增加了一些延迟,还增加了一个额外的操作 (arm_interrupt),当没有更多数据要发送时执行一次。

对于可能的其他方法,请随意假设至少存在以下操作:

/// Is the interrupt armed and will the handler fire once unmasked?
bool is_armed();
/// Is the interrupt unmasked?
bool is_unmasked();

最佳答案

我一直使用双缓冲来做到这一点,因此在任何时间点,程序和 UART 都“拥有”不同的缓冲区。

当 UART 完成发送其缓冲区时,会发生交换,并屏蔽中断。这样,它就不必屏蔽每个字符的中断。

关于c - 基于低延迟中断的传输代码中的不当行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32766195/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com