OS 会向设备请求中断吗?
Will OS request interrupt to device?
以串口为例
当UART接收到数据时,UART设备(芯片)产生一个中断,SW中断处理程序将处理这个中断,例如:从HW缓冲区读取数据。这部分是合理的。
对于TX情况,是否会OS/driver向设备(UART芯片)产生中断,让UART芯片知道有一些数据需要发送出去?
处理 UART 输入 的典型方法比你说的更进一步:
接收到数据后,UART 会生成硬件中断,中断处理程序会从 UART 读取数据并将其放入 FIFO 缓冲区(通常是循环缓冲区)中。
在更高级别,当 OS 想要接收数据时,它会查看输入缓冲区以查看那里是否有任何数据。
这种机制提供了另一层异步性,这意味着输入数据流控制只需要在接收器的输入缓冲区(几乎)满时阻止远程发送器。
处理 output 的一种典型方法是:
UART 准备好传输数据时会产生一个硬件中断。然后中断处理程序将查看 FIFO 输出缓冲区并将队列中的第一项放入 UART 的发送寄存器中。否则,如果没有数据等待传输,则清除中断状态。
在更高级别上,当 OS 想要传输数据时,它会将项目放入输出缓冲区,并确保 UART 在准备好传输时会生成硬件中断,这可能会立即发生.
这意味着输出数据流仅在输出缓冲区已满时才被阻塞。
这些实际上都不需要 UART 处理级别的软件中断。 SW 中断是应用程序与 OS. 通信的便捷方式
设备生成的硬件中断不是 OS-es 或驱动程序。
通常通信硬件在以下情况下产生中断:
- 它有一些数据
- 已准备好发送数据
- 它处于错误状态。
- 它已结束通信(对于具有 FIFO 等内部缓冲区的硬件尤其重要)
如果硬件使用 DMA,您可能还有其他中断
- DMA 事务结束
- 交易一半
- DMA 错误
为了简单起见,我在这里检查 Linux 1.0 作为代码库。
static void rs_stop(struct tty_struct *tty)
{
...
info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
// you can see UART_IER_THRI is not here, the TX interrupt was disabled.
...
}
static void rs_start(struct tty_struct *tty)
{
info->IER = (UART_IER_MSI | UART_IER_RLSI |
UART_IER_THRI | UART_IER_RDI);
// THRI is enabled here.
}
以串口为例
当UART接收到数据时,UART设备(芯片)产生一个中断,SW中断处理程序将处理这个中断,例如:从HW缓冲区读取数据。这部分是合理的。
对于TX情况,是否会OS/driver向设备(UART芯片)产生中断,让UART芯片知道有一些数据需要发送出去?
处理 UART 输入 的典型方法比你说的更进一步:
接收到数据后,UART 会生成硬件中断,中断处理程序会从 UART 读取数据并将其放入 FIFO 缓冲区(通常是循环缓冲区)中。
在更高级别,当 OS 想要接收数据时,它会查看输入缓冲区以查看那里是否有任何数据。
这种机制提供了另一层异步性,这意味着输入数据流控制只需要在接收器的输入缓冲区(几乎)满时阻止远程发送器。
处理 output 的一种典型方法是:
UART 准备好传输数据时会产生一个硬件中断。然后中断处理程序将查看 FIFO 输出缓冲区并将队列中的第一项放入 UART 的发送寄存器中。否则,如果没有数据等待传输,则清除中断状态。
在更高级别上,当 OS 想要传输数据时,它会将项目放入输出缓冲区,并确保 UART 在准备好传输时会生成硬件中断,这可能会立即发生.
这意味着输出数据流仅在输出缓冲区已满时才被阻塞。
这些实际上都不需要 UART 处理级别的软件中断。 SW 中断是应用程序与 OS. 通信的便捷方式
设备生成的硬件中断不是 OS-es 或驱动程序。
通常通信硬件在以下情况下产生中断:
- 它有一些数据
- 已准备好发送数据
- 它处于错误状态。
- 它已结束通信(对于具有 FIFO 等内部缓冲区的硬件尤其重要)
如果硬件使用 DMA,您可能还有其他中断
- DMA 事务结束
- 交易一半
- DMA 错误
为了简单起见,我在这里检查 Linux 1.0 作为代码库。
static void rs_stop(struct tty_struct *tty)
{
...
info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
// you can see UART_IER_THRI is not here, the TX interrupt was disabled.
...
}
static void rs_start(struct tty_struct *tty)
{
info->IER = (UART_IER_MSI | UART_IER_RLSI |
UART_IER_THRI | UART_IER_RDI);
// THRI is enabled here.
}