USB-HID相關筆記

HID是Human Interface Device的縮寫,由其名稱可以瞭解HID設備是直接與人交互的設備,例如鍵盤、鼠標與遊戲杆等。不過HID設備並不一定要有人機接口,只要符合HID類別規範的設備都是HID設備。HID設備一般只有兩種傳輸:中斷傳輸和控制傳輸。一般自己定義的使用是中斷傳輸,(肯定有個控制端點和IN端點,也可以擁有OUT端點)一個HID包最大爲64個字節。這就意味着我們自己定義的協議如果超過64個字節,那麼就要多個包發送。
 g_HID_au8DeviceReportDescriptor[] =
{

 	0x05, 0x01, // USAGE_PAGE (Generic Desktop)
 	0x09, 0x00, // USAGE (0)
 	0xA1, 0x01, // COLLECTION (Application)
 	0x15, 0x00, //     LOGICAL_MINIMUM (0)
 	0x25, 0xFF, //     LOGICAL_MAXIMUM (255)
 	0x19, 0x01, //     USAGE_MINIMUM (1)
 	0x29, 0x08, //     USAGE_MAXIMUM (8) 
 	0x95, MAX_PACKET_SIZE_INT_OUT, //     REPORT_COUNT (8)
 	0x75, 0x08, //     REPORT_SIZE (8)
 	0x81, 0x02, //     INPUT (Data,Var,Abs)
 	0x19, 0x01, //     USAGE_MINIMUM (1)
 	0x29, 0x08, //     USAGE_MAXIMUM (8) 
 	0x91, 0x02, //   OUTPUT (Data,Var,Abs)
 	0xC0        // END_COLLECTION
};

上面是我下位機USB設備報告描述符,這個關於具體發送格式,這個具體怎麼用,我也不知道,因爲是自定義協議,我也沒有去管理。以後有時間在分析。

關於如何操作HID,這個可以使用HID先關的API,先關頭文件和庫在DDK或者WDK包裏面,請自己去下載。我主要講講如何讀寫設備。關於讀寫設備windows爲我們提供了相關函數ReadFile()和WriteFile()。但是有一點要住,讀寫一定要HID包大小去操作。

INT CHidUsb::WriteDevice(HANDLE hUsbDevice, const CHAR *lpszBuf, INT nSize, BOOL bNeedRead)
{
	DWORD dwSizeWritten;
	OVERLAPPED OverLapped;
	DWORD dwErrCode;
	INT nWriteSize;
	INT nNeedWriteSize;
	CHAR szHidBuf[HID_PACKAGE_SIZE + 1];

	nNeedWriteSize = nSize;
	nWriteSize = 0;

	// 只能已HID包的格式發送
	memset(&OverLapped, 0, sizeof(OverLapped));
	OverLapped.hEvent = m_hWriteEvent;

	while (1)
	{
		if (nSize < 0)
		{
			break;
		}

		nNeedWriteSize = HID_PACKAGE_SIZE;
		if (nNeedWriteSize > nSize)
		{
			nNeedWriteSize = nSize;
		}
		nSize -= nNeedWriteSize;

		memset(szHidBuf, 0xff, HID_PACKAGE_SIZE + 1);
		<span style="color:#ff0000;">szHidBuf[0] = 0</span>;// 這裏一定不要忘記,這個是ID,定義爲0,所以加上64個字節,所以一次操作爲65個字節
		memcpy(szHidBuf + 1, lpszBuf, nNeedWriteSize);
		lpszBuf += nNeedWriteSize;

		<span style="color:#ff0000;">if (!::WriteFile(m_hUsbDevice, szHidBuf, HID_PACKAGE_SIZE + 1, &dwSizeWritten, &OverLapped))</span>
		{
			dwErrCode = GetLastError();
			break;
		}

		assert(dwSizeWritten == HID_PACKAGE_SIZE + 1);
		nWriteSize += dwSizeWritten;

	}
	if (bNeedRead)
	{
		SetEvent(m_hWaitEvent);
	}


	return nWriteSize;
}
這個是我封裝寫函數,注意事項有註明,關於USB設備還有很多不是很明白,太複雜了。有時間還得繼續研究。如果想看USB數據發送和接受,可以使用bus hound。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章