title: Realtime receiving of UDP packets with QNX RTOS
body: <p>I have a source which sends UDP packets at a rate of 819.2 Hz (~1.2ms) to my QNX Neutrino machine. I want to receive and process those messages with as little delay and jitter as possible.</p>
  
  <p>My first code was basically:</p>
  
  <pre><code>SetupUDPSocket(); 
  while (true) {
      recv(socket, buffer, BufferSize, MSG_WAITALL); // blocks until whole packet is received
      processPacket(buffer);
  }
  </code></pre>
  
  <p>The problem is that recv() only checks at each timer tick of the system if there is a new packet available. The timer tick is usually 1ms. So, if I use this I will get a huge jitter, because I process a packet every 1ms or every 2ms. I could reset the size of the timer ticks, but that would affect the whole system (and other timers of other processes, etc). And I still would have a jitter, because I certainly would never exactly match the 819.2 Hz.</p>
  
  <p>So, I tried to use the interrupt line of the network card (5). But it seems as there are also other things which causes the interrupt to rise. I used to following code:</p>
  
  <pre><code>ThreadCtl(_NTO_TCTL_IO, 0);
  SIGEV_INTR_INIT(&amp;event);
  iID = InterruptAttachEvent(IRQ5, &amp;event, _NTO_INTR_FLAGS_TRK_MSK);
  
  while(true) {
      if (InterruptWait(0, NULL) == -1) {
          std::cerr &lt;&lt; "errno: " &lt;&lt; errno &lt;&lt; std::endl;
      }
  
      length = recv(socket, buffer, bufferSize, 0); // non-blocking this time
  
      LogTimeAndLength(); 
  
      InterruptUnmask(IRQ5, iID;
  } 
  </code></pre>
  
  <p>This results in a single succesful read in the beginning, followed by reads with 0 byte length after 0 time passing. It seems, that after do the InterruptUnmask(), the InterruptWait() does not wait at all, so there must already be a new interrupt (or the same?!).</p>
  
  <p>Is it possible to do something like that with the interrupt line of the network card? Are there any other possibilties to receive the packets at a rate of 819.2 Hz?</p>
  
  <p>Some information about the network card:
  'pci -vvv' outputs:</p>
  
  <pre><code>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 
  </code></pre>
  
  <p>and 'nicinfo' outputs:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>Thanks for reading!</p>