我需要将数据从裸金属微控制器系统传输到带有2MBaud。linux PC当前运行32钻头Kubuntu14.04.
为了将其存档,我曾尝试使用基于FT232R的USB-UART适配器,但有时会发现数据丢失。
只要linux PC主要处于空闲状态,它似乎在大多数时间都能工作;然而,我看到了罕见的数据丢失。
但当我强制加载cpu(例如,重建我的项目)时,数据丢失会显著增加。
经过一些研究,我在这里读到,FT232R由一个容量只有384的接收缓冲器组成字节这意味着,FT232R必须至少每隔1.9次读取一次(USB轮询)嗯,FTDI建议使用流量控制,但由于使用了微控制器系统,我无法使用任何流量控制。
我可以接受这样一个事实,即没有绝对的保证不会丢失数据。但观察到的数据丢失量对我的需求来说太大了。
因此,我试图找到一种方法来提高linux上"FT232驱动程序"的优先级,但找不到如何做到这一点。在Linux版AN220 FTDI驱动程序安装指南和文件AN107 FTDI高级驱动程序选项有一个关于"更改驾驶员优先级"的标题,但仅适用于车窗。
那么,有人知道如何在linux中提高FT232R驱动程序的优先级吗?
有其他解决这个问题的想法吗?
BTW:当我阅读FT232H数据表时,它似乎带有1KiB RX缓冲区。我现在就点一个,看看它的行为。编辑:没有显著改善。
如果您想要可靠的数据传输,如果没有硬件流控制,并且没有将微控制器中至少所有剩余的RAM用作串行缓冲区(或者至少在您可以存储大约1s的数据之前),就绝对无法正确使用任何USB到串行桥。
自从FT232AM成为一个热门的新事物以来,我一直在使用FTDI设备,下面是我如何实现它们的:
-
(至少)桥接器和MCU之间有四条线路:RXD、TXD、RTS#、CTS#。
-
流量控制在电脑端启用。
-
流量控制是在MCU方面启用的。
-
MCU代码只有在能够将完整的应答包放入缓冲区时才发送通信。否则,它会让PC端超时并重试请求。对于流式传输数据的请求,如果在帧准备好时无法放入传输缓冲区,则会丢弃整个帧。
-
如果您希望PC能够可靠地收到新数据的通知,比如说每一个完整的样本/帧,您必须使用事件字符将FTDI缓冲区刷新到历史记录,并对数据进行编码。HDLC非常适合这个目的,并且有免费标准(RFC和ITU X和Q系列-全部免费!)。
-
VCP驱动程序或D2XX端口启动设置为具有根据应用程序需要设置的传输大小和延迟。
-
通信协议是用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串行接口一团糟,没有人真正关心它,也没有人需要大修。看看那个部门复制意大利面的数量