最好把重点放在吞吐量上。
您忽略了显示任何代码、描述您正在使用的Xilinx 板/系统,或您正在使用的操作系统(例如 FreeRTOS、linux 等)。
您的 RT 数据为:4 字节 * 10 通道 * 100kHz --> 400,000 字节/秒。
根据您的lwip
描述,您有 65536 字节数据包 * 4 数据包/秒 --> 256,000 字节/秒。
这太慢了。而且,它比典型的 TCP / 以太网链接可以处理的速度要慢得多,所以我认为您对最大速率的理解有点偏离。
您可能无法增加数据包大小。
但是,您可能可以增加发送的数据包数量。
你说lwip
不能改变250ms的间隔。我相信它可以。
来自:https ://www.xilinx.com/support/documentation/application_notes/xapp1026.pdf我们有以下部分:使用 RAW API 创建 lwIP 应用程序:
- 设置一个定时器以固定间隔中断。通常,间隔为 250 毫秒左右。在定时器中断中,更新必要的标志以调用 lwIP TCP API
tcp_fasttmr
并tcp_slowtmr
从前面解释的主应用程序循环
“通常”在我看来暗示它是默认值而不是最大值。
但是,您可能不需要增加计时器速率,因为我不认为它决定了数据包速率,只是服务/完成率[在软件中]。
几个猜测...
通常,一旦一个数据包排队到 NIC,其他数据包可能会异步排队。现代 NIC 硬件通常有一个硬件队列。也就是说,NIC H/W 支持多个挂起的请求。它可以在没有 CPU 干预的情况下以线速服务于那些。
250ms可能只是一个定时器中断,它使NIC硬件完成的数据包的数据包描述符退休。
也就是说,每个中断可以处理/完成多个数据包。如果不是这样,那么每秒只能发送 4 个数据包,这将是低得离谱的。
为每个数据包从 NIC 生成中断会产生开销。我的猜测是来自 NIC 的中断被禁用。并且,NIC 以“轮询”模式运行。轮询发生在定时器 ISR 中。
定时器中断每秒会发生 4 次。但是,将处理它看到的任何已完成的数据包。所以,ISR 开销只有 4 个中断/秒。
这增加了吞吐量,因为 ISR 开销减少了。
更新:
感谢您的回复,确实是 4 字节 * 10 通道 * 100kHz --> 4,000,000 字节/秒,但我同意我们离 100Mbit/s 还很远。
警告:我不知道lwip
,所以我所说的大部分内容都是基于我对其他网络堆栈(例如 linux)的经验,但看起来lwip
应该是相似的。
当然,lwip
会提供一种实现全线速度的方法。
关于 250ms 定时器周期的改变,为了达到我想要的效果,它应该降低 10 倍以上,这似乎太多了,它会损害协议的稳定性。
当你这么说的时候,你真的尝试过吗?
而且,同样,您没有发布您的代码或描述您的目标系统,因此很难提供帮助。
问题可能是由于您的目标系统及其 NIC 的功能[或缺乏]。
或者,由于您的代码的结构方式,您没有使用可以使其快速运行的功能。
所以基本上你的建议是在每条消息上启用中断?在这种情况下,如果我理解正确,我可以在 ACK 回调中发送剩余的数据。——马可·马丁内斯
不。
每个数据包的中断模式对于链路使用稀疏/零星的低数据速率很有用。
如果您对每个数据包都有一个中断,那么在更高的数据速率下,进入/退出 ISR(ISR 序言/结语)代码的开销将变得很大 [并且可能无法维持]。
这就是为什么存在基于计时器的回调的原因。累积完成的请求块并[快速]在队列/链上循环并定期完成/回收它们。如果您想了解这个概念,请查看 NAPI:https ://en.wikipedia.org/wiki/New_API
松散地说,在大多数系统上,当您执行 a 时send
,会创建一个请求块,其中包含与给定缓冲区相关的所有信息。然后将该块排队到传输队列。如果发射器空闲,则启动它。对于后续块,该块被附加到队列中。驱动程序 [或 NIC 卡] 将在完成先前的请求后,立即从队列的前面开始一个新的/新的请求。
这使您可以快速排队多个/多个块[并立即返回]。它们将以线路速度按顺序发送。
实际发生的情况取决于系统硬件、NIC 控制器和操作系统以及lwip
您使用的模式。