hidapi通过vid,pid打开设备,输出指令,读取信息
//开线程使用hidapi
AfxBeginThread(&USBHidTestThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0);
根据实际需求写的方法USBHidTestThread:
UINT USBHidTestThread(LPVOID pParam) {
Sleep(200);
int Unplug = 0;//拔插状态
USBTestDlg* pthis = (USBTestDlg*)pParam;
int res = 0;
unsigned char buf[64] = {};
wchar_t wstr[MAX_STR] = {};
hid_device* handle;
CString tempStr = _T("");
int i;
char chstr[128] = {};
struct hid_device_info* devs, * cur_dev;
//有问题 从界面输入指令 而且指令要是0x01 界面输入的是01 这个切割的方式可能有问题
string instruct1, instruct2, instruct3;
instruct1 = (CStringA)Ins;
instruct2 = (CStringA)Ins1;
instruct3 = (CStringA)Ins2;
debuglogpr(L"DebugUSB.log", _T("instruct string =") + Ins + Ins1 + Ins2);
if (hid_init()) {
return 0;//??
}
//将CSTRING转换为unsigned short
//string strv,strp;
//strv = (CStringA)Hid;//CString 转换为 string
unsigned short vids, pids;
string vv = (CStringA)Hid;
const char* cv = vv.c_str();
vids = strtol(cv, NULL, 16);
string pp = (CStringA)Pid;
const char* cp = pp.c_str();
pids = strtol(cp, NULL, 16);
devs = hid_enumerate(vids, pids);
cur_dev = devs;
vector
while (cur_dev) {
vpath.push_back(cur_dev->path);
string str = cur_dev->path;//char* 转换为 string 可以直接赋值
CA2T szr(str.c_str());
tempStr = (LPCTSTR)szr;
//tempStr.Format(_T("%s"), sss);//string 转换为 CString
debuglogpr(L"DebugUSB.log", _T("--HID PATH:") + tempStr);
//将unsigned short 转换为 string
unsigned short us = cur_dev->product_id;
char puf[20];
itoa(us, puf, 16);
string query = puf;
CA2T szc(query.c_str());
tempStr = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", _T("--PID:") + tempStr);
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);
::memset(buf, 0x00, sizeof(buf));//报错:E0266 "memset" 不明确 加::表明调用全局函数
CString log;//输出log用的
for (int d = 0; d < vpath.size(); d++) {
handle = hid_open_path(vpath.at(d).c_str());
string path;
if (!handle)
{
path = "this device path: ";
path += vpath.at(d).c_str();
CA2T szc(path.c_str());
log = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", _T("Path:") + log);
debuglogpr(L"DebugUSB.log", L"--------------------unable to open device ");
continue;
}
debuglogpr(L"DebugUSB.log", L"open device Success !");
// Read the Manufacturer String
wstr[0] = 0x0000;
res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
if (res < 0)
{
debuglogpr(L"DebugUSB.log", L"Unable to read manufacturer string ***");
}
else
{
//QString test = QString::fromWCharArray(wstr);
//tempStr = "manufacturer string =" + test.toStdString();
debuglogpr(L"DebugUSB.log", L"read manufacturer string OK***");
/*writeLog(tempStr);*/
}
hid_set_nonblocking(handle, 1);
debuglogpr(L"DebugUSB.log", L"write ins:");
unsigned short write1, write2, write3;
string sw1 = (CStringA)Ins;
const char* cw1 = sw1.c_str();
write1 = strtol(cw1, NULL, 16);
string sw2 = (CStringA)Ins1;
const char* cw2 = sw2.c_str();
write2 = strtol(cw2, NULL, 16);
string sw3 = (CStringA)Ins2;
const char* cw3 = sw3.c_str();
write3 = strtol(cw3, NULL, 16);
int p = 0;//p是typeCport口的标识,而不是配置界面portd的标识 从1开始
if (write3 == 0x01) {
p = 1;
}
else if (write3 == 0x02) {
p = 2;
}
else if (write3 == 0x03) {
p = 3;
}
else if (write3 == 0x04) {
p = 4;
}
else if (write3 == 0x05) {
p = 5;
}
else if (write3 == 0x06) {
p = 6;
}
::memset(buf, 0x00, sizeof(buf));
buf[0] = 0xFF & write1;
buf[1] = 0xFF & write2;
buf[2] = 0xFF & write3;
int write = 0;//write 是否写入数据成功的标记
res = hid_write(handle, buf, 64);
sprintf_s(chstr, "write info: %02x %02x %02x ...", buf[0], buf[1], buf[2]);
CA2T szc(std::string(chstr).c_str());
log = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", log);
if (res < 0)
{
path = "this device path: ";
path += vpath.at(d).c_str();
CA2T szc(path.c_str());
log = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", log);
debuglogpr(L"DebugUSB.log", L"------------------------Unable to write()");
continue;
}
else {
path = "this device path: ";
path += vpath.at(d).c_str();
CA2T szc(path.c_str());
log = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", log);
debuglogpr(L"DebugUSB.log", L"write Success------------------------");
write = 1;//能够写入成功说明打开设备地址正确
}
res = 0;
std::string result = "";
int num = 0;
CString port;//USBHidTestThread port标识 只针对TypeC
debuglogpr(L"DebugUSB.log", L"read start:");
while (1) {
Sleep(100);
if (aa && bb && !Unplug) {//当前port A/B面均check时 并且USB拔出 跳到下一个接口
port.Format(L"port:%d ,check A+B OK!", p);
debuglogpr(L"DebugUSB.log", port);
p++;
aa = 0;
bb = 0;
//port口从1开始
if (p == 2) {
write3 = 0x02;
}
else if (p == 3) {
write3 = 0x03;
}
else if (p == 4) {
write3 = 0x04;
}
else if (p == 5) {
write3 = 0x05;
}
else if (p == 6) {
write3 = 0x06;
}
}
port.Format(_T("port: %d"), p);
debuglogpr(L"DebugUSB.log", port);
Sleep(50);
if (num > 0) {
hid_set_nonblocking(handle, 1);
debuglogpr(L"DebugUSB.log", L"write ins");
::memset(buf, 0x00, sizeof(buf));
buf[0] = 0xFF & write1;
buf[1] = 0xFF & write2;
buf[2] = 0xFF & write3;
res = hid_write(handle, buf, 64);
sprintf_s(chstr, "write info: %02x %02x %02x ...", buf[0], buf[1], buf[2]);
CA2T szc(std::string(chstr).c_str());
log = (LPCTSTR)szc;
debuglogpr(L"DebugUSB.log", log);
if (res < 0)
{
debuglogpr(L"DebugUSB.log", L" ...........................................write Fail");
continue;
}
else {
debuglogpr(L"DebugUSB.log", L"write Success ...........................................");
}
}
num++;
::memset(buf, 0x00, sizeof(buf));
res = hid_read(handle, buf, sizeof(buf));
tempStr = "read come back =";
result = "";
CString str;
str.Format(_T("%d"), p);
if (res > 0) {
debuglogpr(L"DebugUSB.log", L" Get the returned data:res > 0");
for (i = 0; i < res; i++)
{
sprintf_s(chstr, "%02x", buf[i]);
result += std::string(chstr);
tempStr += std::string(chstr).c_str();
}
debuglogpr(L"DebugUSB.log", tempStr);
string::size_type position;
if ((position = result.find("ad0000")) != result.npos) {
debuglogpr(L"DebugUSB.log", L"Not detected USB,read continue-----");
pthis->SetDlgItemText(IDC_A, L"");
Unplug = 0;
res = 0;
continue;
}
else if ((position = result.find("ad0001")) != result.npos) {
port = str + L"checkA";
debuglogpr(L"DebugUSB.log", port);
if (aa) {//a面已经check
continue;
}
pthis->SetDlgItemText(IDC_A, port);
pthis->GetDlgItem(IDC_A)->ShowWindow(TRUE);
pthis->GetDlgItem(IDC_A)->Invalidate(0);
Unplug = 1;
aa = 1;
portNum++;
}
else if ((position = result.find("ad0002")) != result.npos) {
port = str + L"checkB";
debuglogpr(L"DebugUSB.log", port);
if (bb) {//b面已经check
continue;
}
pthis->SetDlgItemText(IDC_A, port);
pthis->GetDlgItem(IDC_A)->ShowWindow(TRUE);
pthis->GetDlgItem(IDC_A)->Invalidate(0);
Unplug = 1;
bb = 1;
portNum++;
}
}
if (res == 0)
debuglogpr(L"DebugUSB.log", L"REM waiting...");
if (res < 0) {
debuglogpr(L"DebugUSB.log", L"SET ERR=Unable to read");
break;
}
}
if (write) {
break;
}
debuglogpr(L"DebugUSB.log", L"This device write success!!");
}
return 1;
}
-------------
if (Pid == L"0x0384") {//Pid是0x0584是spacex机种 usb2.0在3.0下面后缀也为3. 0x0384是DM usb后缀还是为2.
debuglogpr(L"DebugUSB.log", L"DM-------");
AfxBeginThread(&USBNewThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0);
}
else {
debuglogpr(L"DebugUSB.log", L"SPACEX-------");
AfxBeginThread(&USBSpxThread, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0);
}
----------------
//spacex
UINT USBSpxThread(LPVOID pParam) {
Sleep(300);
CString porttype = L"", portpath = L"";
CString u3btemp = L"", u2btemp = L"";
int a = 0, b = 0, value = 0;
typecValueTemp = 0;
int TypecValue = 0; //tool获取的TypeC正反面特征值
USBTestDlg* pthis = (USBTestDlg*)pParam;
CString log = _T("");
int u3pass = 0;
while (true) {
Sleep(50);
for (int j = 0; j < totalNum && j < 12; j++) //遍历配置的path_Type
{
//if (j < (portNum * 2) && j >= (portNum - 1) * 2) {
for (int i = 0; i < pthis->usbinfo->mUSBInfo.Index; i++)//遍历系统获取到的path_Type
{
getPortTypeCValue.Format(_T("%s_%s"), pthis->usbinfo->mUSBInfo.PORTPATH[i], pthis->usbinfo->mUSBInfo.PORTTYPE[i]);//系统获取到的path_Type
if (readWriteTest[j].needTest)//需要测试读写速度
{
//!readWriteTest[j].isTest && readWriteTest[j].path == pthis->usbinfo->mUSBInfo.uPanReadWriteSpeed[i].UPANPATH && pthis->usbinfo->mUSBInfo.uPanReadWriteSpeed[i].speed > readWriteTest[j].speed
//现在不需要比较盘符
if (!readWriteTest[j].isTest && pthis->usbinfo->mUSBInfo.uPanReadWriteSpeed[i].speed > readWriteTest[j].speed)
{
readWriteTest[j].isTest = true;
log.Format(_T("ReadWriteSpeedTest:%s_%s,%c:%f m/s"), pthis->usbinfo->mUSBInfo.PORTPATH[i], pthis->usbinfo->mUSBInfo.PORTTYPE[i], pthis->usbinfo->mUSBInfo.uPanReadWriteSpeed[i].UPANPATH, pthis->usbinfo->mUSBInfo.uPanReadWriteSpeed[i].speed);
debuglogpr(L"DebugUSB.log", log);
}
else
{
continue;
}
}
//2.0
if (((U2PathTest[j].Find(L"&")) != -1) && ((U2PathTest[j].Find(L"#")) != -1)) {
if (TcFlagTest[j]) {
log = _T("System TypeC 2.0 portPath: ") + getPortTypeCValue;
debuglogpr(L"DebugUSB.log", log);
u2btemp = U2PathTest[j] + _T("_") + _T("3.");//spacex 2.0 后缀也是3
debuglogpr(L"DebugUSB.log", L"u2bpath:" + u2btemp);
if (getPortTypeCValue.Find(u2btemp) != -1) {
debuglogpr(L"DebugUSB.log", L"compareUSB2flag");
if (compareUSB2flag[j] == 0) {
if (aa || bb) {//当TypeC检测到一面时
debuglogpr(L"DebugUSB.log", L"U2path:" + U2PathTest[j] + L" U2path+1:" + U2PathTest[j + 1]);
if (U2PathTest[j] == U2PathTest[j + 1]) {//保证当前TypeC是第一次检测
pthis->SetDlgItemText(IDC_U2_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u2find++;
compareUSB2flag[j] = 1;
pthis->GetDlgItem(IDC_U2_1 + j)->Invalidate(0);
continue;
}
}
if(aa && bb){//当TypeC检测到第二面时
pthis->SetDlgItemText(IDC_U2_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u2find++;
compareUSB2flag[j] = 1;
pthis->GetDlgItem(IDC_U2_1 + j)->Invalidate(0);
continue;
}
}
}
}
else//普通U盘(非typec转接)
{
log = _T("System normal USB2 portPath&portType: ") + getPortTypeCValue;
u2btemp = U2PathTest[j] + _T("_") + _T("3.");
if (getPortTypeCValue.Find(u2btemp) != -1)
{
if (compareUSB2flag[j] == 0)
{
pthis->SetDlgItemText(IDC_U2_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u2find++;
compareUSB2flag[j] = 1;
pthis->GetDlgItem(IDC_U2_1 + j)->Invalidate(0);
continue;
}
}
}
}
//3.0或3.1
CString PN = _T("");
PN.Format(_T("%d"), portNum);
debuglogpr(L"DebugUSB.log", L"USB3ON:" + USB3ON + L";portNum:"+ PN);//USB3ON 此参数只针对是否测 不测哪个port的typec3.0,就配置对应port的数字 —— 不需要不配置就好,暂时未用到
if (USB3ON.Find(PN) !=-1) {//找到对应字符 该port不测3.0
debuglogpr(L"DebugUSB.log", PN+L" don't check 3.0");
}
else {
if (((U3PathTest[j].Find(L"&")) != -1) && ((U3PathTest[j].Find(L"#")) != -1))
{
if (TcFlagTest[j])//是typec转接
{
log = _T("System TypeC 3.0 portPath: ") + getPortTypeCValue;
debuglogpr(L"DebugUSB.log", log);
u3btemp = U3PathTest[j] + _T("_") + _T("3.");//spacex这个机种测出来两个地址是一样 通过系统查不出来标识
debuglogpr(L"DebugUSB.log", L"u3bpath:" + u3btemp);
if (getPortTypeCValue.Find(u3btemp) != -1)
{
debuglogpr(L"DebugUSB.log", L"compareUSB3flag");
if (compareUSB3flag[j] == 0)
{
if (aa || bb) {
debuglogpr(L"DebugUSB.log", L"U3path:" + U3PathTest[j] + L" U3path+1:" + U3PathTest[j + 1]);
if (U3PathTest[j] == U3PathTest[j + 1]) {
pthis->SetDlgItemText(IDC_U3_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u3find++;
compareUSB3flag[j] = 1;
pthis->GetDlgItem(IDC_U3_1 + j)->Invalidate(0);
continue;
}
}
if (aa && bb) {//当TypeC检测到第二面时
pthis->SetDlgItemText(IDC_U3_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u3find++;
compareUSB3flag[j] = 1;
pthis->GetDlgItem(IDC_U3_1 + j)->Invalidate(0);
continue;
}
}
}
//}
}
else//普通U盘(非typec转接)
{
log = _T("System normal USB3 portPath&portType: ") + getPortTypeCValue;
u3btemp = U3PathTest[j] + _T("_") + _T("3.");
if (getPortTypeCValue.Find(u3btemp) != -1)
{
if (compareUSB3flag[j] == 0)
{
pthis->SetDlgItemText(IDC_U3_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u3find++;
compareUSB3flag[j] = 1;
pthis->GetDlgItem(IDC_U3_1 + j)->Invalidate(0);
continue;
}
}
}
}
}
}
/* if (!TcFlagTest[j]) {
log = _T("System normal USB3 portPath&portType: ") + getPortTypeCValue;
u3btemp = U3PathTest[j] + _T("_") + _T("3.");
if (getPortTypeCValue.Find(u3btemp) != -1)
{
if (compareUSB3flag[j] == 0)
{
pthis->SetDlgItemText(IDC_U3_1 + j, L"PASS");
debuglogpr(L"DebugUSB.log", getPortTypeCValue + L":PASS");
u3find++;
compareUSB3flag[j] = 1;
pthis->GetDlgItem(IDC_U3_1 + j)->Invalidate(0);
continue;
}
}
}*/
log.Format(_T("portNum:%d"), portNum);
debuglogpr(L"DebugUSB.log", log);
}
a = _ttoi(U2NumTest[1]);//要测的USB 2.0个数
b = _ttoi(U3NumTest[1]);//要测的USB 3.0个数
if (a == 0)
{
u2p = true;
}
if (b == 0)
{
u3p = true;
}
if ((u2find == a) && (a > 0))
{
pthis->GetDlgItem(IDC_U2Result)->ShowWindow(TRUE);
u2p = true;
pthis->GetDlgItem(IDC_U2Result)->Invalidate(0);
}
if ((u3find == b) && (b > 0))
{
pthis->GetDlgItem(IDC_U3Result)->ShowWindow(TRUE);
u3p = true;
pthis->GetDlgItem(IDC_U2Result)->Invalidate(0);
}
if (u3p && u2p)
{
if (ReTest == 0)//复测功能开放至配置界面
{
CString updateStr = _T("");
updateStr.Format(_T("Update Global set ResUSB = '1';"));
dbUSE->UpdateDB(updateStr);
}
pthis->result_usb = 1;
pthis->WriteXML_USB();
debuglogpr(L"DebugUSB.log", L"USB ALL Test=PASS");
return 1;
}
}
}
该需求USBHidTestThread和USBSpxThread是相辅相成的