Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Микроконтроллеры и их применение»

В двух словах - ReadFile, WriteFile

Отправлено Глупый_пИнгвин 02 ноября 2008 г. 13:36
В ответ на: Как со стороны РС общаться с USB-HID ? отправлено koyodza 02 ноября 2008 г. 12:50

Нюансы. Чтобы открыть девайс как файл, нужно знать DevicePath, а мы знаем VID и PID. Чудовищно, но, похоже, в винде нет функции, которая по вид-пид возвращает путь или сразу хэндл. Поэтому приходится тупо просматривать список хид-девайсов, пока на найдётся с нужным видом-пидом. Другой странный момент - хид нельзя открыть в read-write режиме, а нужно заводить два хэндла - один для чтения, другой для записи. И последнее - винда добавляет к репортам один байт. Если девайс поддерживает несколько вариантов репортов, что нетипично, байт содержит номер варианта. Если, как это обычно бывает, репорт только одного типа, байт всё равно присутствует и всегда равен 0.
Ну и пример на сях:

#include <Windows.h>
#include <conio.h>
#include <stdio.h>

extern "C" {
#include "hidsdi.h"
#include <setupapi.h>
}

//HID libraries
#pragma comment(lib, "hid.lib")
#pragma comment(lib, "setupapi.lib")


#define MY_VID 0x1234
#define MY_PID 0x5678


#pragma pack(1)
struct in_report
{
BYTE report_id;
// actual in report here
// for example
BYTE my_buttons;
};

struct out_report
{
BYTE report_id;
// actual out report here
// for example
BYTE my_leds;
};
#pragma pack()


HANDLE WriteHandle = INVALID_HANDLE_VALUE;
HANDLE ReadHandle = INVALID_HANDLE_VALUE;

BOOL HidOpenDevice( const unsigned int VendorID, const unsigned int ProductID )
{
PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
SP_DEVICE_INTERFACE_DATA devInfoData;

GUID HidGuid;
HidD_GetHidGuid(&HidGuid);

HANDLE hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
devInfoData.cbSize = sizeof(devInfoData);

for( int j = 0; WriteHandle == INVALID_HANDLE_VALUE; j++ )
{
if( 0 == SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, j, &devInfoData) )
break; //no more devices
DWORD Length;
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); //get size for detail
detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)new BYTE[Length];
detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail( hDevInfo, &devInfoData, detailData, Length, &Length, NULL ); //get detail

//Open a handle to the device.
WriteHandle = CreateFile( detailData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

HIDD_ATTRIBUTES Attributes;
Attributes.Size = sizeof(Attributes);
HidD_GetAttributes( WriteHandle, &Attributes );

if( Attributes.VendorID == VendorID && Attributes.ProductID == ProductID )
{
//Both the Product and Vendor IDs match.
printf( "Device detected\n" );
ReadHandle = CreateFile( detailData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0 , NULL );
}
else
{
CloseHandle( WriteHandle );
WriteHandle = INVALID_HANDLE_VALUE;
}
delete detailData;
}

SetupDiDestroyDeviceInfoList(hDevInfo);

return ( ReadHandle != INVALID_HANDLE_VALUE );
}

void HidCloseDevice()
{
if( ReadHandle != INVALID_HANDLE_VALUE )
{
CloseHandle( ReadHandle );
ReadHandle = INVALID_HANDLE_VALUE;
}
if( WriteHandle != INVALID_HANDLE_VALUE )
{
CloseHandle( WriteHandle );
WriteHandle = INVALID_HANDLE_VALUE;
}
}


int main(int argc, char* argv[])
{
if( ! HidOpenDevice( MY_VID, MY_PID ) )
{
printf( "Device not found\n" );
return 1;
}
printf( "press a key to stop\n" );

while( ! _kbhit() )
{
in_report ir;
out_report or;
DWORD nBytes = 0;

if( ! ReadFile( ReadHandle, &ir, sizeof(ir), &nBytes, NULL ) )
{
printf( "Read failed. Error %x\n", GetLastError() );
break;
}

or.report_id = 0;
or.my_leds = ir.my_buttons;
if( ! WriteFile( WriteHandle, &or, sizeof(or), &nBytes, NULL ) )
{
printf( "Write failed. Error %x\n", GetLastError() );
break;
}
}
HidCloseDevice();
return 0;
}


Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
введите число 34:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru