This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM623:UART:如何无间隙发送超过 64 个字节

Guru**** 2645485 points

Other Parts Discussed in Thread: SK-AM62

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1581088/am623-uart-how-to-send-more-than-64-bytes-without-gaps

器件型号: AM623
主题中讨论的其他器件: SK-AM62

尊敬的 TI 支持团队:

我们基于 AM6232 Linux 的器件使用多达四个 UART 接口、与外部外设进行通信、波特率为 921600。 通信基于电报、电报长度高达 500 字节。 接收器期望连续数据流在字节之间具有最大 10µs 间隙。

在 TX 线上进行测量期间、我们观察到当发送大于 64 字节的数据块时、传输暂停 10–40µs。 这些间隙会导致接收器侧出现问题。 我们怀疑原因是 UART FIFO 运行为空、并等待驱动程序重新填充。 通过器件树调整 TX 阈值未解决问题。

我们正在考虑使用 DMA 来确保连续传输。 请告知:

  1. 对于此用例、您会建议进行哪些 UART 和 DMA 设置?
  2. 如何在 AM6232 上的设备树中为 UART 配置 DMA?
  3. 在 AM62x 上将 DMA 与 UART 配合使用时、是否存在已知限制或性能注意事项?

注意:我们之前基于 AM33xx 的产品处理此用例没有任何问题。

提前感谢您的支持。

此致、
Andreas Martin

示例:传输 64 个字节后的 17us 间隙

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    不建议在 UART 传输中使用 DMA、DMA 通道设置时间并不重要、因此 DMA 对 UART 不会有任何帮助。

    您在 AM6232 上使用的是哪个 SDK/内核版本?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们使用的是 Vanilla 6.1.1xx 内核。 目前为 6.1.141.

    我们对任何解决方案都持开放态度、而不是专注于使用 DMA。 我们以前的 AM33xx 器件在此用例中采用 DMA、因此从未出现此类时序问题。

    我还尝试通过器件树设置 TX 阈值、但我没有看到行为有区别。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    我将尝试看看是否可以使用基于 kerenl 6.1.32 的 SDK9.0 来复制问题 SK-AM62 EVM、然后进行研究。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    我可以在 EVM 上重现问题、以下内核补丁可以消除这一差距。 但是、性能不是最优的、该补丁似乎在每传输 3 个字节时会生成 UART TX 中断。 我将继续努力。

    diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
    index cf68d9f6924f..69c38e8351af 100644
    --- a/drivers/tty/serial/8250/8250_omap.c
    +++ b/drivers/tty/serial/8250/8250_omap.c
    @@ -89,7 +89,7 @@
     #define OMAP_UART_WER_MOD_WKUP 0x7f
     #define OMAP_UART_TX_WAKEUP_EN (1 << 7)
     
    -#define TX_TRIGGER     1
    +#define TX_TRIGGER     48
     #define RX_TRIGGER     48
     
     #define OMAP_UART_TCR_RESTORE(x)       ((x / 4) << 4)
    @@ -482,7 +482,7 @@ static void omap_8250_set_termios(struct uart_port *port,
            up->fcr |= TRIGGER_FCR_MASK(priv->tx_trigger) << OMAP_UART_FCR_TX_TRIG;
            up->fcr |= TRIGGER_FCR_MASK(priv->rx_trigger) << OMAP_UART_FCR_RX_TRIG;
     
    -       priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY |
    +       priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK |
                    OMAP_UART_SCR_TX_TRIG_GRANU1_MASK;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    除 921600 之外、您的项目中是否使用其他波特率?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    请应用以下内核补丁、以解决 UART TX 间隙问题。 如果您使用的波特率高于 921600、此补丁中设置的 TX_TRIGGER 值可能必须进一步降低。

    e2e.ti.com/.../uart_2D00_tx_2D00_use_2D00_lvl_2D00_trigger_2D00_interrupt.diff

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很抱歉晚回复。 我的 TI 账户出现问题。

    感谢您提供补丁。 在四个接口上使用我们的最大波特率 921600 时,它仍然不稳定,但要好得多。 我必须将 TX_TRIGGER 降低到 48。 使用该值、器件成功完成了长时间运行的应力测试。

    有关补丁处理的两个问题:

    1. 此 补丁是否会发送到上游内核?
    2. 除其他外、TX_TRIGGER 的值应由器件树设置进行控制。 例如、有一些设置、如 tx-threshold、在我看来、这些设置是相同的、但在 8250 OMAP 驱动程序中没有实现。 为什么对设置进行硬编码?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Andreas:

    否、正如您已经指出的、此补丁不是正确的实现、因此不会将其发送到内核上游。

    轻松实施时存在多个问题:

    盲目设置 TX 阈值触发器(通过将驱动程序硬编码为我的补丁或在器件树中进行硬编码)对于 UART 接收器不关心该间隙的用例来说并不是最适合的、因为它没有充分利用 TX FIFO 并会生成更多 TX 中断。

    您已经发现、必须根据 UART 用例、并行运行的 UART 端口数量和波特率来调整 TX 阈值触发值。 在器件树中设置值不是一个解决方案、因为 UART 用例可能会在 Linux 运行时发生变化。

    另一个问题是、此阈值会触发 UART 阈值中断、通常在内核 8250 框架中未处理该中断。 8250 端口驱动程序有函数 serial8250_tx_threshold_handle_irq() 来处理此阈值中断、但它目前仅用于 UART 类型 ALTR_16550_*。

    我认为真正的问题在于 UART 器件具有固定/严格的 RX 超时值。 在本例中、在 921600 波特时、10us 基本上只是一个字节的时间。 大多数 UART 控制器具有更大的默认 RX 超时值、它是可配置的。 例如、AM62x 上的 UART 模块的默认 TX 超时约为 5 字节时间、并可以在 UART 寄存器中进行调整。