【问题标题】:How to (almost) prevent FT232R (uart) receive data loss?如何(几乎)防止 FT232R(uart)接收数据丢失?
【发布时间】:2015-11-09 02:47:20
【问题描述】:

我需要将数据从裸机微控制器系统传输到 2MBaud 的 linux PC。 linux PC 目前运行的是 32bit Kubuntu14.04。

为了存档,我尝试使用基于 FT232R 的 USB-UART 适配器,但有时会发现数据丢失。

只要linux PC主要是空闲的,似乎大部分时间都在工作;但是,我发现很少有数据丢失。

但是当我强制加载 cpu 时(例如重建我的项目),数据丢失会显着增加。

经过一番研究,我读到here,FT232R 包含一个容量仅为 384 字节的接收缓冲区。这意味着,FT232R 必须至少每 1.9 毫秒读取一次(USB 轮询)。好吧,FTDI推荐使用流控,但是由于使用了微控制器系统,我固定不能使用任何流控。

我可以接受这样一个事实,即没有绝对保证不会丢失数据。但是观察到的数据丢失量对于我的需求来说太重了。

所以我试图找到一种方法来提高我的 linux 上“FT232 驱动程序”的优先级,但找不到如何做到这一点。中没有描述 AN220 FTDI Drivers Installation Guide for Linux 和文件 AN107 FTDI Advanced Driver Options 有一个关于“更改驱动程序优先级”的标题,但仅适用于 Windows。

那么,有人知道如何在 linux 中提高 FT232R 驱动程序的优先级吗?

还有什么办法可以解决这个问题吗?

顺便说一句:当我阅读FT232H datasheet 时,它似乎带有 1KiB RX 缓冲区。我现在就订购一个并检查它的行为。编辑:没有显着改善。

【问题讨论】:

  • 您可以查看drivers/usb/serial/ftdi_sio.c,并就您的问题联系该驱动的作者
  • Joe,想一想,您是否考虑过使用一些缩减版本的 TCP 协议来封装您的 UART 连接?
  • @Borgboy:你的意思是,我应该使用 Tcp-Uart 模块而不是 Usb-Uart?你能推荐一个能够支持 2MBaud 的吗?
  • @Joe:不,我的意思是您可能需要考虑在 USB-UART 和您的微控制器之间使用基于软件的握手机制。我确实认为增加 RX 缓冲区会有很大帮助。出于好奇,您的微控制器是否有外部 RAM?这是我拥有的一个 EvK,它在一个板上提供了 MCU、SRAM 和 UART2USB:link。它专为高数据收集和传输而设计。
  • 如何实现 RTS/CTS 流控制?

标签: linux uart ftdi


【解决方案1】:

如果您想要可靠的数据传输,如果没有硬件流控制,并且没有将微控制器中至少所有剩余的 RAM 用作串行缓冲区(或至少在您可以存储约 1 秒的数据之前)。

自从 FT232AM 成为热门新事物以来,我一直在使用 FTDI 设备,以下是我实施它们的方法:

  1. (至少)四根线在桥接器和 MCU 之间走:RXD、TXD、RTS#、CTS#。

  2. 在 PC 端启用了流控制。

  3. 在 MCU 端启用流控制。

  4. MCU 代码仅在可以将完整的回复数据包放入缓冲区时发送通信。否则,它会让它的 PC 端超时并重试请求。对于将数据流回的请求,如果在帧准备好时无法放入传输缓冲区,则整个帧将被丢弃。

  5. 1234563编码您的数据。 HDLC 非常适合该用途,并记录在免费标准中(RFC 和 ITU X 和 Q 系列 - 全部免费!)。
  6. VCP 驱动程序或 D2XX 端口启动设置为根据应用程序的需要设置传输大小和延迟。

  7. 通信协议是框架的,带有 CRC。如果是 X.25/Q.921/HDLC,我通常使用缩减版,对于简单的“哑”命令和响应设备,仅限于 SNRM(E) 模式,对于流数据的设备,我会使用 SABM(E)。

FTDI 缓冲区的大小无关紧要,您的 MCU 应该至少有一个数量级的存储空间来缓冲内容。

如果您正在运行硬实时代码,例如信号处理,请确保考虑到大量“背靠背”运行的传输中断的开销。一旦 FTDI 设备在 USB 传输后清除其缓冲区,并表明它已准备好从您的 MCU 接收更多数据,您的代码可能会一次传输整个 FTDI 缓冲区的数据。

如果您的实时代码中的周期快用完,您可以使用定时器作为发送中断的来源,而不是 UART 中断。然后,您可以将定时器速率设置为远低于 UART 速度。这使您可以在不降低波特率的情况下放慢传输速度。如果您在设置/预操作模式下运行或实时任务负载较低,则可以在不更改波特率的情况下轻松提高传输速率。您可以使用类似的技巧通过在定时器控制下翻转 MCU 上的 RTS# 输出来调整接收速度。当然,这不是问题,只要您使用 DMA 或足够快的 MCU。

如果您没有计时器,请注意许多其他外设也可以重新用作计时器中断源。

无论 USB 主机是什么,此建议都适用。

边栏:诚然,据我所知,Linux USB 串行驱动程序“架构”处于假死状态,因此获得合理的结果可能需要大量工作。恐怕这不是简单的内核线程优先级更改的问题。部分原因是很多 Linux 工作的资金都集中在服务器/企业应用程序上,而 USB 性能充其量只是次要问题。它适用于 USB 存储,但 USB 串行是一团糟,没有人真正关心过大修,大修它需要。看看那个部门的copy-pasta的数量......

【讨论】:

    猜你喜欢
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多