为什么向串口发送字符需要延时?
Why do we need to delay when sending char to serial port?
考虑这段代码 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
?为什么是设计缺陷? delay()
用于 serial_putc() 函数:
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.
串行端口是一种硬件,具有您必须接受的某些语义。它通常有一个移位寄存器,用于将并行数据转换为串行数据。它可以有一个用于下一个要发送的字节的保持寄存器,甚至可以有一个用于多个字节的 FIFO。这就是为什么您必须轮询线路状态寄存器 (LSR) 的原因。
有些硬件修订版无法正常运行。您的代码看起来像是旧硬件中错误的解决方法。这里应该不需要读取端口0x84。
但是当您提高编译器优化级别时,无法优化延迟实现,因为它正在访问 I/O 范围。 运行 如果 运行 时间性能提供的延迟太少,则此代码在最新硬件中可能会出现问题。您必须验证循环中可以等待的最长时间是否足以通过 UART 移出一个字节。请记住,这是波特率相关的,而您的代码示例则不是。
端口 0x84 用于访问 "extra page register" (Overview)。但是读取这个寄存器应该是一个空洞。只有读取操作本身对消耗 CPU 个周期很重要。
考虑这段代码 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
?为什么是设计缺陷? delay()
用于 serial_putc() 函数:
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.
串行端口是一种硬件,具有您必须接受的某些语义。它通常有一个移位寄存器,用于将并行数据转换为串行数据。它可以有一个用于下一个要发送的字节的保持寄存器,甚至可以有一个用于多个字节的 FIFO。这就是为什么您必须轮询线路状态寄存器 (LSR) 的原因。
有些硬件修订版无法正常运行。您的代码看起来像是旧硬件中错误的解决方法。这里应该不需要读取端口0x84。
但是当您提高编译器优化级别时,无法优化延迟实现,因为它正在访问 I/O 范围。 运行 如果 运行 时间性能提供的延迟太少,则此代码在最新硬件中可能会出现问题。您必须验证循环中可以等待的最长时间是否足以通过 UART 移出一个字节。请记住,这是波特率相关的,而您的代码示例则不是。
端口 0x84 用于访问 "extra page register" (Overview)。但是读取这个寄存器应该是一个空洞。只有读取操作本身对消耗 CPU 个周期很重要。