C Linux 8250 RS485 RTS故障排除

C Linux 8250 RS485 RTS故障排除,c,linux-kernel,uart,rs485,C,Linux Kernel,Uart,Rs485,通过阅读这些论坛,我学到了很多东西,所以我想问自己一个问题 我正在开发一款嵌入式Linux设备,该设备在Xilinx Zynq平台上使用Linux 4.7内核。我无法让8250串行驱动程序的RS485部分正常工作。使用RTS引脚切换RS485收发器所需的所有功能都已存在于8250_port.c文件中,但我必须在8250_of.c文件中添加一个RS485_config()函数,以支持使用TIOCSRS485 ioctl()调用进行配置 我的问题是,起初,负责设置RTS引脚的函数只在传输开始时调用,

通过阅读这些论坛,我学到了很多东西,所以我想问自己一个问题

我正在开发一款嵌入式Linux设备,该设备在Xilinx Zynq平台上使用Linux 4.7内核。我无法让8250串行驱动程序的RS485部分正常工作。使用RTS引脚切换RS485收发器所需的所有功能都已存在于8250_port.c文件中,但我必须在8250_of.c文件中添加一个RS485_config()函数,以支持使用TIOCSRS485 ioctl()调用进行配置

我的问题是,起初,负责设置RTS引脚的函数只在传输开始时调用,使收发器处于发送模式。我发现8250\u port.c的uu stop\u tx()函数中可能存在错误

static inline void __stop_tx(struct uart_8250_port *p)
{
    struct uart_8250_em485 *em485 = p->em485;

    if (em485) {
        unsigned char lsr = serial_in(p, UART_LSR);
        /*
         * To provide required timeing and allow FIFO transfer,
         * __stop_tx_rs485 must be called only when both FIFO and
         * shift register are empty. It is for device driver to enable
         * interrupt on TEMT.
         */
        if ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
        {
            return;
        }

        del_timer(&em485->start_tx_timer);
        em485->active_timer = NULL;
    }
    __do_stop_tx(p);
    __stop_tx_rs485(p);
}
_EMPTY都转换为LSR寄存器中的THRE和TEMT位。当tx数据已从保持寄存器传输到移位寄存器时,设置THRE,表示cpu可将新字节写入UART。当数据从移位寄存器移出时,即实际通过线路发送时,设置TEMT。因此,TEMT将始终在THRE设置后设置,并延迟行上字节的移位时间,包括开始位、停止位和奇偶校验位

我相信问题是,THRE和TEMT一起测试,但在调用函数时,它们可能没有被设置,特别是在使用低波特率时(在我的例子中是19200 Bd)。我验证了中间的返回总是被占用,甚至在最后一个字节之后,当它被调用的时候,调用它。这就是为什么收发机从未切换回接收

我只是简单地评论了一下返回,它现在开始工作了。但这是我稍后要问的另一个问题。我想先听听你对这个话题的看法。此代码仍然存在于4.12内核文件中


您好,Florian

如果您在这里没有得到回复(您可能没有,因为这是一个关于大多数人都不熟悉的代码的非常具体的问题),您可能会在Linux串行驱动程序邮件列表中询问:
Linux-serial@vger.kernel.org
存在bug的可能性并不大。此外,我还看到了硅芯片上的bug,这些bug适用于大多数版本的Linux串行驱动程序,但不适用于某些芯片。例如,不要让我开始使用AllWinner的内置UART。我也会用Xilinx FAE在这个问题上打圈。@EdH谢谢你的提示,我想我会联系Xilinx,因为我可能在他们的数据表中也发现了一个错误。这个问题是否发生在最新的香草(v4.13-rc6)上?下一步会在linux上发生吗?@0andriy代码仍然存在,但我无法测试它。