为什么在将char发送到串口时需要延迟?

时间:2015-01-05 08:05:41

标签: c kernel

请考虑此代码here

// Stupid I/O delay routine necessitated by historical PC design flaws
static void
delay(void)
{
    inb(0x84);
    inb(0x84);
    inb(0x84);
    inb(0x84);
}

什么是端口0x84?为什么会出现设计缺陷? serial_putc()函数中使用了delay()

static void
serial_putc(int c)
{
    int i;

    for (i = 0;
         !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800;
         i++)
        delay();

    outb(COM1 + COM_TX, c);
}

该文件来自lab1 of the course Operating System Engineering from OCW

1 个答案:

答案 0 :(得分:1)

串口是一块硬件,你必须接受一些语义。它通常有一个移位寄存器,可以实现从并行到串行数据的转换。它可以有一个保持寄存器,用于发送下一个字节,甚至可以有一个FIFO用于多个字节。这就是你必须轮询线路状态寄存器(LSR)的原因。

有一些硬件修订版本无法正常运行。您的代码看起来像旧硬件中的错误的解决方法。这里没有必要读取端口0x84。

但是,当您增加编译器优化级别时,延迟实现无法优化,因为它正在访问I / O范围。如果运行时性能提供太少的延迟,则在最新的硬件中运行此代码可能会有问题。您必须验证循环中可以等待的最长时间是否足以通过UART移出一个字节。请记住,这是波特率依赖的,而代码示例则不是。

端口0x84用于访问“额外页面寄存器”(Overview)。但读这个寄存器应该是一个noop。只有读操作本身对消耗CPU周期很重要。