Linux 8250 RS485 RTS故障排除

时间:2017-08-22 09:26:27

标签: c linux-kernel uart rs485

我从阅读这些论坛中学到了很多东西,所以我想自己提问。

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

我的问题是,首先,负责设置RTS引脚的功能仅在传输开始时调用,使收发器处于发送模式。我发现8250_port.c的__stop_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);
}

BOTH_EMPTY转换为LSR寄存器中的THRE和TEMT位。当tx数据从保持寄存器传输到移位寄存器时,THRE置位,指示cpu可以向UART写入新字节。当数据移出移位寄存器时,TEMT置位,即。实际上是通过线路发送的。因此,TEMT将始终在THRE置位后设置,延迟线路上的字节移位所需的时间,包括开始,停止和奇偶校验位。

我认为问题是,THRE和TEMT是一起测试的,但是在调用函数时它们可能没有被设置,特别是当使用低波特率时(在我的情况下为19200 Bd)。我确认中间的返回总是被占用,即使在最后一个字节之后,也应该调用__stop_tx_rs485()。这就是收发器从未切换回接收的原因。

我只是评论退货并且现在正在工作,有点儿。但这是我稍后会问的另一个问题/问题。我想首先听听你对这个话题的看法。此代码仍存在于4.12内核文件中。

问候,弗洛里安

0 个答案:

没有答案