У меня есть мост USB-UART XR21V1410. Согласно даташиту, он может отправлять/принимать (в том числе) символы UART в формате 9N1 - девять значащих бит, без бита чётности, с одним битом подтверждения. Данный формат символов применяется в шине MDB (Multi-Drop Bus) - но не суть. Для работы с символами в подобном формате мост следует переключить в так называемый "расширенный" режим - wide mode. Делается это отправкой команды (control transfer) XR_SET_REG, которую драйвер данного моста поддерживает наряду со стандартными для мостов USB-UART командами SET_LINE_CODING, GET_LINE_CODING и SET_CONTROL_LINE_STATE. WinAPI прячет работу с последними тремя командами "под капот". Для настройки у неё есть SetCommState(), для непосредственного обмена данными - запись и чтение из файла. Я погуглил и нашёл пример использования XR_SET_REG. Но оно, видимо, для Линукса. А мне хотелось бы сконфигурировать мой мост на чистом WinAPI. Я начал искать, как отправить control transfer устройству USB на WinAPI. Для этого я прочитал пример Майкрософта "How to send a USB control transfer". Но он исключительно про драйверы KMDF/UMDF. В моём же случае драйверы уже имеются. Затем я прочитал пример Майкрософта "Access a USB device by using WinUSB functions". Там есть такой код: Код (C): int _tmain(int argc, _TCHAR* argv[]) { GUID guidDeviceInterface = OSR_DEVICE_INTERFACE; //in the INF file HANDLE hDeviceHandle = INVALID_HANDLE_VALUE; WINUSB_INTERFACE_HANDLE hWinUSBHandle = INVALID_HANDLE_VALUE; // ...ещё несколько переменных... bResult = GetDeviceHandle(guidDeviceInterface, &hDeviceHandle); bResult = GetWinUSBHandle(hDeviceHandle, &hWinUSBHandle); // ...БАМ-БАМ-БАМ, проворачиваем кучу всего интересного по хэндлу hWinUSBHandle, например... bResult = ReadFromBulkEndpoint(hWinUSBHandle, &PipeID.PipeInId, cbSize); system("PAUSE"); done: CloseHandle(hDeviceHandle); WinUsb_Free(hWinUSBHandle); return 0; } Константа OSR_DEVICE_INTERFACE встречается в примере всего один раз, с эдакой самоочевидностью "ну вы знаете, этот OSR_DEVICE_INTERFACE - кто его не знает". И у меня возник вопрос, если я знаю VID/PID моего устройства и нужный мне эндпойнт, как мне выяснить OSR_DEVICE_INTERFACE? Возможно ли его выяснить через последовательность, вроде такой: Код (C): deviceInfoSet = SetupDiCreateDeviceInfoList(&GUID_DEVCLASS_USB, NULL); allDevices = SetupDiGetClassDevsExA(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES, deviceInfoSet, NULL, NULL); for(devIndex = 0; SetupDiGetDeviceInfo(allDevices, devIndex, &deviceInfo);devIndex++) { SetupDiGetDeviceInstanceIdA(deviceInfoSet, &deviceInfo, devId, 1024, &devIdLen); if(...условие, что в этой итерации просматривается именно нужное мне устройство...) { // ...получение OSR_DEVICE_INTERFACE ... } }
Как мне кажется, комментарий как бы намекает, что для конкретного девайса это может быть константа, которую можно подсмотреть в .inf файле, например.
Говорите без намёков, здесь все свои. При подключении устройства, в диспетчере устройств появляются два новых пункта. Одно в разделе "Контроллеры USB" - "Составное USB устройство", второе в разделе "Порты (COM и LPT)" - "Устройство с последовательным интерфейсом USB (COM28)". Я зашёл в свойства обоих устройств, на вкладку "Сведения". Там в выпадающем списке "Свойства" я выбрал пункт "ИД оборудования". Для COM28 значение этого пункта USB\VID_04E2&PID_1410&REV_0001&MI_00 USB\VID_04E2&PID_1410&MI_00 Для составного USB-устройства значение этого пункта USB\VID_04E2&PID_1410&REV_0001 USB\VID_04E2&PID_1410 В принципе, "PID_1410" похож на XR21V1410, а "VID_04E2" соответствует компании Exar (которая разработала этот мост, а затем продалась MaxLinear). Далее, на этой вкладке я меняю свойство на "Имя INF". Для COM28 это "usbser.inf", для USB-устройства это "usb.inf". Я открываю соответствующие файлы *.inf по пути "C:\Windows\INF" и... не нахожу там ничего похожего на *1410*. Соответственно, константу для guidDeviceInterface всё также не понятно где брать. Возвращаясь к началу поста, я бы предложил говорить без намёков. Если вы знаете, где и как найти константу - к чему это напускание тумана загадочности и величия? Если не знаете - тем более, к чему?
На сайте производителя можно скачать Serial_Test_USB_V1.2.0.0.exe, который содержит в себе вот такие две конструкции: Код (Text): .00406CDA push 0 .00406CDC lea ecx,dword ptr ss:[ebp-4] .00406CDF push ecx .00406CE0 push 0 .00406CE2 push 0 .00406CE4 push 0 .00406CE6 push 0 .00406CE8 push 22205C .00406CED push eax .00406CEE call dword ptr ds:[<&DeviceIoControl>] .00406CF4 mov ecx,esi .00406CF6 test eax,eax .00406CF8 jne serial_test_usb_v1.2.0.0.406D10 .00406CFA push 10 .00406CFC push serial_test_usb_v1.2.0.0.661F18 ;"Error" .00406D01 push serial_test_usb_v1.2.0.0.6621BC ;"Error calling IOCTL_XRUSBPORT_ENABLE_WIDE_MODE!" .00406C69 push 0 .00406C6B lea ecx,dword ptr ss:[ebp-4] .00406C6E push ecx .00406C6F push 0 .00406C71 push 0 .00406C73 push 0 .00406C75 push 0 .00406C77 push 222060 .00406C7C push eax .00406C7D call dword ptr ds:[<&DeviceIoControl>] .00406C83 mov ecx,esi .00406C85 test eax,eax .00406C87 jne serial_test_usb_v1.2.0.0.406C9F .00406C89 push 10 .00406C8B push serial_test_usb_v1.2.0.0.661F18 ;"Error" .00406C90 push serial_test_usb_v1.2.0.0.662188 ;"Error calling IOCTL_XRUSBPORT_DISABLE_WIDE_MODE!" Очевидно wide mode устанавливается DeviceIoControl(,0x22205C,,,,,,) и отключается DeviceIoControl(,0x222060,,,,,,). Вот как бы и всё. Наверняка там где-то можно нарыть сдк и там это тоже будет описано, но лень искать.
Когда то давным давно я работал напрямую с особым протоколом принтеров подключаемых в COM-порт. Особые принтеры со своим языком команд который надо засылать прямо установив соединение. У меня был ступор когда эти принтеры перешли на USB-протокол, т.к. никакого виртуального COM-порта драйверами в системе не проявлялось, а драйвера просто имитировали обычный принтер Windows со всеми вытекающими: любая печать превращалась в пересылку битмапов и безбожно тормозила и создавала кровавый геморрой с полями печати там где достаточно было закинуть несколько десятков байт нативных команд (по сути винда просто всё время слала нативную команду "отобразить битмап". Меня это не устраивало и я начал усиленно копать как вернуть COM-порт взад. И потом я обнаружил интересное - даже если не установлены драйвера, то при подключении к такого принтера к компу в системе USB проскакивали сообщения о появлении в системе точки подключения к serial-девайсу: https://gamedev.ru/flame/forum/?id=51653&page=2 При этом из гуида который возвращается можно сформировать истинное имя порта девайса которое имеет вид типа \\.\GUID - само перечисление возвращает вместо точки в этой сентенции знак вопроса или наоборот. Строку с этим делом можно использовать в обычном OpenFile чтобы открыть порт принтера напрямую как будто бы это COM-порт и спокойно работать дальше даже без установки драйверов. Просто воткнул девайс в новый комп, увидел в программе какой гуид при этом появляется в системе USB и используешь его после небольшой замены символов как имя порта. Так вот, подозреваю, что речь именно об этом гуиде идёт тут.
Здесь проблема скорее в этом: Есть шнурок с некоторым кастомным функционалом, но документации по нему кроме брошюрок с картинками для дебилов нету. Наверное так разрабы намекают, что покупкой шнурка ты не отделаешься.
Не знаю, могу только предположить. Вот пара примеров кода от азиатских товарищей: https://www.twblogs.net/a/5b898b2b2b71775d1ce25806 https://q.cnblogs.com/q/51027/ Загуглив значения (лет ми ду ит фор ю) видим, что эти гуиды соответствуют Bus Type Guid, который как раз можно найти в диспетчере задач, вкладка Details.
в нетах встречаютс разные упоминания, например: static const GUID OSR_DEVICE_INTERFACE[] = { 0xD696BFEB, 0x1734, 0x417d, { 0x8A, 0x04, 0x86,0xD0,0x10,0x71,0xC5,0x12 } }; может это поможет https://github.com/MicrosoftDocs/wi...pr/usbcon/automatic-installation-of-winusb.md --- Сообщение объединено, 21 апр 2023 --- https://github.com/MicrosoftDocs/wi...#writing-a-custom-inf-for-winusb-installation --- Сообщение объединено, 21 апр 2023 --- "в студию"