我有一個以819.2Hz(〜1.2ms)的速率向我的QNX Neutrino機器發送UDP數據包的源。我想以儘可能小的延遲和抖動來接收和處理這些消息。使用QNX RTOS實時接收UDP數據包
我的第一代碼基本上是:
SetupUDPSocket();
while (true) {
recv(socket, buffer, BufferSize, MSG_WAITALL); // blocks until whole packet is received
processPacket(buffer);
}
的問題是,的recv()僅在系統的每個計時器滴答檢查是否有可用的新的分組。計時器刻度通常爲1ms。所以,如果我使用這個,我會得到一個巨大的抖動,因爲我每隔1ms或每2ms處理一個數據包。我可以重置計時器滴答的大小,但這會影響整個系統(以及其他進程的其他定時器等)。而且我仍然會有抖動,因爲我絕對不會完全匹配819.2赫茲。
所以,我試圖使用網卡(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()僅在系統的每個計時器滴答時檢查是否有新的數據包可用' - 爲什麼會這樣做?我不知道任何QNX, - 網絡驅動程序不能正常工作嗎?中斷驅動程序應該設置一個事件/信號量並通過操作系統退出,這樣就可以立即設置recv()線程。應該不需要任何「等到計時器打勾」 - 這是無望的 - 也可以使用協作輪詢循環:( – 2012-08-08 16:44:39
像Martin提到的實現細節可能因驅動程序和卡的特定型號而異,但您沒有 – 2012-08-08 17:12:04
@MartinJames和Ben Voigt:對不起,我沒有意識到我的問題可能與驅動程序有關,'nicinfo'表示「INTEL 82544千兆位(銅纜)以太網控制器」和「pci -vvv」輸出「供應商ID = 8086h,英特爾公司 設備ID = 107ch,82541PI千兆位以太網控制器「 – jan 2012-08-09 10:46:31