gpt4 book ai didi

c++ - 使用 QNX RTOS 实时接收 UDP 数据包

转载 作者:可可西里 更新时间:2023-11-01 17:59:41 25 4
gpt4 key购买 nike

我有一个源以 819.2 赫兹(~1.2 毫秒)的速率向我的 QNX Neutrino 机器发送 UDP 数据包。我希望以尽可能少的延迟和抖动来接收和处理这些消息。

我的第一个代码基本上是:

SetupUDPSocket(); 
while (true) {
recv(socket, buffer, BufferSize, MSG_WAITALL); // blocks until whole packet is received
processPacket(buffer);
}

问题在于 recv() 仅在系统的每个计时器滴答时检查是否有可用的新数据包。计时器滴答声通常为 1 毫秒。所以,如果我使用它,我会得到一个巨大的抖动,因为我每 1 毫秒或每 2 毫秒处理一个数据包。我可以重置计时器滴答的大小,但这会影响整个系统(以及其他进程的其他计时器等)。而且我仍然会有抖动,因为我肯定永远不会完全匹配 819.2 Hz。

于是,我尝试使用网卡的中断线(5)。但似乎还有其他因素导致中断上升。我曾经使用以下代码:

ThreadCtl(_NTO_TCTL_IO, 0);
SIGEV_INTR_INIT(&event);
iID = InterruptAttachEvent(IRQ5, &event, _NTO_INTR_FLAGS_TRK_MSK);

while(true) {
if (InterruptWait(0, NULL) == -1) {
std::cerr << "errno: " << errno << std::endl;
}

length = recv(socket, buffer, bufferSize, 0); // non-blocking this time

LogTimeAndLength();

InterruptUnmask(IRQ5, iID;
}

这会导致在开始时读取一次成功,然后在 0 次之后读取 0 字节长度。看起来,在执行 InterruptUnmask() 之后,InterruptWait() 根本没有等待,所以一定已经有一个新的中断(或相同?!)。

是否可以用网卡的中断线做类似的事情?是否还有其他可能以 819.2 Hz 的速率接收数据包?

网卡的一些信息:'pci -vvv' 输出:

Class          = Network (Ethernet)
Vendor ID = 8086h, Intel Corporation
Device ID = 107ch, 82541PI Gigabit Ethernet Controller
PCI index = 0h
Class Codes = 020000h
Revision ID = 5h
Bus number = 4
Device number = 15
Function num = 0
Status Reg = 230h
Command Reg = 17h
I/O space access enabled
Memory space access enabled
Bus Master enabled
Special Cycle operations ignored
Memory Write and Invalidate enabled
Palette Snooping disabled
Parity Error Response disabled
Data/Address stepping disabled
SERR# driver disabled
Fast back-to-back transactions to different agents disabled
Header type = 0h Single-function
BIST = 0h Build-in-self-test not supported
Latency Timer = 40h
Cache Line Size= 8h un-cacheable
PCI Mem Address = febc0000h 32bit length 131072 enabled
PCI Mem Address = feba0000h 32bit length 131072 enabled
PCI IO Address = ec00h length 64 enabled
Subsystem Vendor ID = 8086h
Subsystem ID = 1376h
PCI Expansion ROM = feb80000h length 131072 disabled
Max Lat = 0ns
Min Gnt = 255ns
PCI Int Pin = INT A
Interrupt line = 5
CPU Interrupt = 5h
Capabilities Pointer = dch
Capability ID = 1h - Power Management
Capabilities = c822h - 28002000h
Capability ID = 7h - PCI-X
Capabilities = 2h - 400000h
Device Dependent Registers:
0x040: 0000 0000 0000 0000 0000 0000 0000 0000
...
0x0d0: 0000 0000 0000 0000 0000 0000 01e4 22c8
0x0e0: 0020 0028 0700 0200 0000 4000 0000 0000
0x0f0: 0500 8000 0000 0000 0000 0000 0000 0000

和“nicinfo”输出:

wm1: 
INTEL 82544 Gigabit (Copper) Ethernet Controller

Physical Node ID ........................... 000E0C C5F6DD
Current Physical Node ID ................... 000E0C C5F6DD
Current Operation Rate ..................... 100.00 Mb/s full-duplex
Active Interface Type ...................... MII
Active PHY address ....................... 0
Maximum Transmittable data Unit ............ 1500
Maximum Receivable data Unit ............... 0
Hardware Interrupt ......................... 0x5
Memory Aperture ............................ 0xfebc0000 - 0xfebdffff
Promiscuous Mode ........................... Off
Multicast Support .......................... Enabled

感谢阅读!

最佳答案

我不太确定为什么声明 “问题是 recv() 仅在系统的每个计时器滴答时检查是否有可用的新数据包。计时器滴答通常为 1 毫秒。” 对于抢占式操作系统来说是正确的。肯定是系统配置有问题或者网络协议(protocol)栈实现有问题。

几年前,当我为 Yahoo BB Japan 做一些 IPTV STB 项目时,我遇到了 RTP 接收问题。问题不是延迟或抖动,而是我们添加一些 NDS 算法后 STB 中的整体系统性能。我们正在使用 vxWorks,vxWorks 支持以太网 Hook 接口(interface),驱动程序每次收到以太网数据包时都会调用该接口(interface)。

我将一个 API 挂接到它,然后直接从以太网数据包中解析具有指定端口的 UDP。当然我们有一些假设没有碎片,这是由性能问题的网络设置保证的。也许您还可以查看是否可以在 QNX 以太网驱动程序中获得相同的 Hook 。至少您会发现抖动是否来自驱动程序。

关于c++ - 使用 QNX RTOS 实时接收 UDP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11867871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com