异步读取HID丢数

Mr.Black1213 2017-11-24 05:36:24
问题:
在做Windows应用与HID设备通讯时,异步读取发现丢数据的问题,发现驱动层接收到的数据并不是马上存入接收缓存中等待应用去读取,而是丢失不定长的数据后再存入缓存中。

具体操作如下:
1、打开文件是以异步读取方式打开:
hd = CreateFile(HidFunctionClassData->DevicePath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

2、打开后设置接收缓存大小,并读出设置值确认设置成功:
HidD_SetNumInputBuffers(hd, 128);
HidD_GetNumInputBuffers(hd, &inputBufSize);

3、用ReadFile读取数据:
ReadFile(handle, rBuffer, Capabilities.InputReportByteLength, &dwRet, &rOverLap);
WaitForSingleObject(rOverLap.hEvent, 100) ;

4、启动一个专门接收数据的线程,轮询读取;

具体现象:
下位机每隔15ms上传一帧数据,上位机每隔20ms接收一次,发现刚开始每接收一帧就会丢失一帧,接收了不定长的数据后才不丢数据,直到接收缓存满;

分析:
如果驱动层接收的数据都会进入接收缓存,那么在接收缓存未满之前是不会丢失数据的,所以现在怀疑是不是刚开始的数据没有进入缓存,或者已经被接收了;
...全文
803 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
libai 2020-01-04
  • 打赏
  • 举报
回复
做了HID的通讯也是异步经常丢数据,没办法只好用同步了,
我做得协议很简单,上位机传数据给下位机,下位机收到了给个应答就行了,
用异步的经常会卡在没有应答那块,上位机发条命令,然后等待应答,经常会一直没数据,有时候可以,大部分时间收不到

后面实在没办法搞成同步的了
Mr.Black1213 2017-11-27
  • 打赏
  • 举报
回复
引用 2 楼 LOVE_ELEC 的回复:
看了下楼主的代码,对于bRet = min(dwRet, dwSize);有一定的疑问,我理解的意思是楼主是若File中的数据长度大于你要读取的长度就读取你要读取的内容,这样肯定没问题;但是若你读到的结果是File中的数据长度小于你要读取的数据长度,那么你会将File中的数据全部读走,对于这部分小于你要读取的数据长度的数据,你是怎么处理的呢?如果直接丢掉那么你这边下次再接收数据的时候就会可能造成串包的可能!
HID读取长度是固定的;
LOVE_ELEC 2017-11-24
  • 打赏
  • 举报
回复
看了下楼主的代码,对于bRet = min(dwRet, dwSize);有一定的疑问,我理解的意思是楼主是若File中的数据长度大于你要读取的长度就读取你要读取的内容,这样肯定没问题;但是若你读到的结果是File中的数据长度小于你要读取的数据长度,那么你会将File中的数据全部读走,对于这部分小于你要读取的数据长度的数据,你是怎么处理的呢?如果直接丢掉那么你这边下次再接收数据的时候就会可能造成串包的可能!
Mr.Black1213 2017-11-24
  • 打赏
  • 举报
回复
读取函数如下:

int HIDDeviceRead(HANDLE handle, LPVOID lpBuffer, DWORD dwSize)
{
	if (handle == NULL || handle == INVALID_HANDLE_VALUE)
		return 0;
	if (rOverLap.hEvent == NULL || rOverLap.hEvent == INVALID_HANDLE_VALUE)
		return 0;
	if (lpBuffer == NULL)
		return 0;

	BYTE rBuffer[512] = { 0 };
	DWORD dwRet;
	BOOL bRet = 0;
	DWORD err;
	char log[128];

	rBuffer[0] = 0x00;

	//调用成功,返回非0,调用不成功, 返回为0
	if (!ReadFile(handle, rBuffer, Capabilities.InputReportByteLength, &dwRet, &rOverLap))
	{
		if ((err = GetLastError()) != ERROR_IO_PENDING)
		{
			sprintf(log, "Read data err:%d.\r\n", err);
			_cprintf(log);
			return bRet;
		}

		if (::WaitForSingleObject(rOverLap.hEvent, 100) != WAIT_TIMEOUT)
		{
			//::GetOverlappedResult(handle, &rOverLap, &dwRet, TRUE);
			dwRet = rOverLap.InternalHigh;

			bRet = min(dwRet, dwSize);
			memcpy(lpBuffer, &rBuffer[1], bRet);
		}

	}
	else
	{
		bRet = min(dwRet, dwSize);
		memcpy(lpBuffer, &rBuffer[1], bRet);
	}
	ResetEvent(wOverLap.hEvent);

	return bRet;
}

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧