Windows 10 RawHID Warning!

Status
Not open for further replies.

yeahtuna

Well-known member
I've been noticing that Windows 10 occasionally drops rawHID packets. On my development machine (desktop) about 1 in every 100 packets gets dropped. On my Surface Pro (2017) with battery saver turned on, it's about 1 in every 50 packets. I believe this to be a Windows 10 only issue, as it has only recently cropped up in the last year or so, and macOS seems to be unaffected. I'll be doing some extensive testing over the next few weeks and report my findings.

Rob
 
Crazy! Even dropping my packet transition rate to 1 packet every 100 ms still results in lost packets!
 
Here's some teensy side code. It sends 1000 packets, but only 936 are received on my Windows desktop machine. I'll provide an .exe for testing as soon as possible.
Code:
void setup() {
  // put your setup code here, to run once:
}


char buf[64];
int numPacketsSent = 0;

elapsedMillis timeSinceLastSent;
elapsedMillis startupDelay;

void loop() {

  // put your main code here, to run repeatedly:
  
  if (numPacketsSent < 1000 && startupDelay > 5000) {
    while (timeSinceLastSent < 10) {
      
    }
    timeSinceLastSent = 0;
    RawHID.send(&buf, 5);
    numPacketsSent++;
  }
}
 
Last edited:
This doesn't have known values to .send()? :: char buf[64];

I get nothing … I went to 'all the things' and then a Serial.print() showed up … but nothing from the RawHID - SerMon or TyComm which used to be how I saw RawHid.

Win 10 latest on a desktop
 
No, it shouldn't matter what's in the buffer. My Teensyduino is several years old already. I'm going to install from scratch on another machine to see if this is a bug that's been fixed
 
I'm using TD 1.42 and even with giving it some "ABC..." known viewable characters I saw nothing. I've never used the .send() - seems it was just TeensyTransfer in RawHid before printing debug text and that worked back then.
 
I've installed Arduino IDE 1.85 and TD 1.42. The test results are about the same. Packets are still being dropped!

Here is a link to a console application I through together. Run the application first, and then plug in in your Teensy.

www.audiofront.net/Test_rawHID.exe

And here is the a link to the Visual Studio project files. Please note that you'll need to have the Windows DDK installed for this to compile:
www.audiofront.net/ConsoleApplication1.zip
 
I wounder if there's a bug in the following code which was pulled from the old rawHID example.

Code:
int rawhid_recv(int num, void *buf, int len, int timeout)
{
	hid_t *hid;
	unsigned char tmpbuf[516];
	OVERLAPPED ov;
	DWORD n, r;

	if (sizeof(tmpbuf) < len + 1) return -1;
	hid = get_hid(num);
	if (!hid || !hid->open) return -1;
	EnterCriticalSection(&rx_mutex);
	ResetEvent(&rx_event);
	memset(&ov, 0, sizeof(ov));
	ov.hEvent = rx_event;
	if (!ReadFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
		if (GetLastError() != ERROR_IO_PENDING) goto return_error;
		r = WaitForSingleObject(rx_event, timeout);
		if (r == WAIT_TIMEOUT) goto return_timeout;
		if (r != WAIT_OBJECT_0) goto return_error;
	}
	if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
	LeaveCriticalSection(&rx_mutex);
	if (n <= 0) return -1;
	n--;
	if (n > len) n = len;
	memcpy(buf, tmpbuf + 1, n);
	return n;
return_timeout:
	CancelIo(hid->handle);
	LeaveCriticalSection(&rx_mutex);
	return 0;
return_error:
	print_win32_err();
	LeaveCriticalSection(&rx_mutex);
	return -1;
}
 
I've found the source of the problem. It's the timeout in the rawhid_recv() method. I've bumped it up to 15 ms, and all the packets arrive as expected.
 
I have no idea and no old machines to test on. I can say that even with a timeout of 15, there are still occasionally dropouts. If there's a steady stream of packets, then all is good. But if the packets are few and far between, then even a timeout of 15 is insufficient.
 
Wonder if you change your teensy app and look at the return value from the rawhid.send(...

Do you get the failure there? like return value -1 (probably not), but maybe 0 which shows timeout...
 
Hi, Kurt. I guess I'm using the wrong terminology. I do check the return value and the packets are in fact timing out (returning 0) as opposed to being dropped, but I would think that 15ms should be enough time to wait. These are supposed to be realtime events for musical applications, and 15ms is a lot of latency. The 1000 packets / second guarantee certainly doesn't seem to be holding up anymore.
 
Sorry, I miss read your post. I do check on the Teensy side of the things and there are no issues there. It's always returning 64 bytes sent.
 
And one last note, with a timeout of 15 ms on my desktop in 'High Performance mode', there are no missing packets whatsoever. Clearly Microsoft has been tweeking things on the Surface to get more battery life.
 
Status
Not open for further replies.
Back
Top