Alpha
Интересующийся
Offline
|
|
« : 18-04-2010 20:35 » |
|
Здравствуйте, уважаемые профессионалы! Я пишу функциональный драйвер для USB-модема DLink-DU562M с использованием WDF. Пишу под Windows XP. Родной драйвер работает с ним через COM порт. Для передачи данных я создаю 3 pipe для устройства: для чтения, записи и прерывания. Возникла проблема передачи модему данных от пользователя. Т.е. я получаю от пользователя какие-то данные и записываю дальше на передачу с помощью функций WdfUsbTargetPipeFormatRequestForWrite(...), WdfRequestSetComplectionRoutine(...) и WdfRequestSend(...) вроде как бы они записываются в устройство. Но как получить от него ответ? Если я посылаю AT-команду модему через гипертерминал, например, ATI1 или ATI4, то я должен получить ответ, определенный буфер. Для ATI1 ответ должен быть "255", а для ATI4 - "D-Link DU-562M External Modem". Но на этом драйвер у меня виснет, а прерывания вообще не работают. Пробовал через SnoopyPro определить как идет передача данных в родном драйвере, в итоге пакеты посылки и получения данных от команд ATI1 и ATI4 совпадают, за исключением двух байт. Хотя как я понимаю в пакете должна быть последовательность байт, которыми представляются эти команды. Ничего подобного там нет, какие-то непонятные символы передаются. Уже целый месяц над этой проблемой парюсь. Никак не пойму, в чем загвоздка (
Помогите,пожалуйста, разобраться, как разрешить эту проблему. Может как-то надо посылать прямо в COM порт, связанный с этим модемом, а дальше там он просто ждать от него прерывания? Если это так, то какие команды надо писать? Или надо как-то очередь запросов настроить? Заранее спасибо!
|
|
« Последнее редактирование: 19-04-2010 06:52 от Ochkarik »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #1 : 19-04-2010 06:55 » |
|
один момент: а с чего вы взяли, что по USB надо именно AT команды в текстовом формате писать?) там вполне может быть свой собственный бинарный формат команд. а родной драйвер для совместимости уже виртуальный ком-порт создает, и транслирует в понятную AT-совместимую форму. исключительно для удобства совместимости. (это я к примеру сказал ) фраза "пакеты посылки и получения данных от команд ATI1 и ATI4 совпадают, за исключением двух байт" - мне понравилась) а что - в два байта разницы команда не влезет? или я не понял, - что это за пакеты? что вообще значит "пакеты посылки и получения данных"? в USB есть пайпы. в один вы только пишете пакеты(и ничего более) - другой только читаете. я не понял, что вы имели в виду, говоря, что пакеты передачи и и приема совпадают) насчет зависает... тут надо более подробно участки кода смотреть)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #2 : 24-04-2010 21:26 » |
|
Вот, к примеру функция для чтения В комментариях /* ... */ указан синронный способ чтения. VOID EvtDeviceIoRead( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_CONTEXT devCtx = NULL; WDFMEMORY requestMem;
size_t l; UCHAR *inChar = NULL;
//////// WDF_USB_CONTROL_SETUP_PACKET controlPacket; WDF_MEMORY_DESCRIPTOR memDescriptor; size_t bytesTransferred = -1; /////////
devCtx = GetDeviceContext(WdfIoQueueGetDevice(Queue));
UNREFERENCED_PARAMETER(Length);
DbgPrint(" === EvtDeviceIoRead\n"); KdPrint((__DRIVER_NAME "Received a read request of %d bytes\n", Length));
status = WdfRequestRetrieveOutputMemory(Request, &requestMem); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfRequestRetrieveOutputMemory failed with status 0x%08x\n", status)); WdfRequestComplete(Request, status); return; }
DbgPrint(" === EvtDeviceIoRead\n"); inChar = WdfMemoryGetBuffer(requestMem, &l); KdPrint(( " === [%s]\n", UCharToLPCStr(inChar, Length) ));
/////////////////////////////// status = WdfUsbTargetPipeFormatRequestForRead( devCtx->UsbBulkInPipe, Request, requestMem, NULL); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfUsbTargetPipeFormatRequestForRead failed with status 0x%08x\n", status)); WdfRequestComplete(Request, status); return; } DbgPrint(" === WdfUsbTargetPipeFormatRequestForRead OK \n");
WdfRequestSetCompletionRoutine(Request, EvtIoReadComplete, devCtx->UsbBulkInPipe); DbgPrint(" === WdfRequestSetCompletionRoutine OK \n");
if(FALSE == WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(devCtx->UsbBulkInPipe), NULL)) { KdPrint((__DRIVER_NAME "WdfRequestSend failed with status 0x%08x\n", status)); status = WdfRequestGetStatus(Request); } else { WdfRequestComplete(Request, status); DbgPrint(" === WdfRequestSend OK \n"); return; }
DbgPrint(" === WdfRequestSend before WdfRequestComplete OK \n"); WdfRequestComplete(Request, status); DbgPrint(" === EvtDeviceIoRead end \n");
/* WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptor, requestMem, NULL);
WDF_USB_CONTROL_SETUP_PACKET_INIT( &controlPacket, BmRequestDeviceToHost,//BmRequestHostToDevice, BmRequestToEndpoint,//BmRequestToDevice, 0x02, 0, 0); //method to send a USB control transfer request synchronously status = WdfUsbTargetDeviceSendControlTransferSynchronously( devCtx->UsbDevice, NULL, NULL, &controlPacket, &memDescriptor, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfUsbTargetDeviceSendControlTransferSynchronouslyfailed with status 0x%08x\n", status)); } KdPrint((__DRIVER_NAME "\n bytesTransferred = %d \n", bytesTransferred)); KdPrint((__DRIVER_NAME " memDescriptor.type = %d \n", memDescriptor.Type)); if (memDescriptor.Type == WdfMemoryDescriptorTypeHandle) { KdPrint((__DRIVER_NAME " memDescriptor.u.HandleType.Offsets = %08x ", memDescriptor.u.HandleType.Offsets)); inChar = WdfMemoryGetBuffer(memDescriptor.u.HandleType.Memory, &Length); KdPrint((__DRIVER_NAME " Length = %d ", Length));
for (l = 0; l < Length; l++) KdPrint((__DRIVER_NAME "inChar = (%d) [%c] ", inChar[l], inChar[l])); } WdfRequestComplete(Request, STATUS_NOT_SUPPORTED); */ }
Эта функция регистрируется в функции NTSTATUS EvtDeviceAdd(...), которая вызывается при добавлении устройства. Вот участок кода, отвечающий за создание очереди для чтения: /*create the IO queue for read requests*/ WDF_IO_QUEUE_CONFIG_INIT(&ioQConfig, WdfIoQueueDispatchSequential); ioQConfig.EvtIoRead = EvtDeviceIoRead; status = WdfIoQueueCreate(Device, &ioQConfig, WDF_NO_OBJECT_ATTRIBUTES, &Context->IoReadQueue); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfIoQueueCreate failed with status 0x%08x\n", status)); return status; }
status = WdfDeviceConfigureRequestDispatching(Device, Context->IoReadQueue, WdfRequestTypeRead); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfDeviceConfigureRequestDispatching failed with status 0x%08x\n", status)); return status; }
Вот функция, которая вызывается при завершении асинхронного чтения: /*............................................................................*/ /* callback function for signalling the completion of a read request. */ /*............................................................................*/ VOID EvtIoReadComplete( IN WDFREQUEST Request, IN WDFIOTARGET Target, IN PWDF_REQUEST_COMPLETION_PARAMS Params, IN WDFCONTEXT Context) { PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Target); KdPrint(( " === EvtIoReadComplete Begin\n"));
usbCompletionParams = Params->Parameters.Usb.Completion;
if(NT_SUCCESS(Params->IoStatus.Status)) { KdPrint((__DRIVER_NAME "Completed the read request with %d bytes\n", usbCompletionParams->Parameters.PipeRead.Length)); } else { KdPrint((__DRIVER_NAME "Failed the read request with status 0x%08x\n", Params->IoStatus.Status)); } WdfRequestCompleteWithInformation(Request, Params->IoStatus.Status, usbCompletionParams->Parameters.PipeRead.Length);
KdPrint(( " === EvtIoReadComplete end\n")); }
Но ни асинхронный, ни синхронный способы чтении не работают. При синхронном чтении у меня появляется синий экран. А при асинхронном чтении вызов функции WdfUsbTargetPipeFormatRequestForRead завершается с ошибкой 0xc0000138. Как я понял, это связано с тем, что я неправильно формирую пакет для запроса чтения. Та же самая ситуация возникает и при асинхронной посылке управляющего кода устройству. Тот же номер ошибки. Если это так, то получается, что я только реверс инжинирингом смогу понять, какой формат передаваемой структуры. Вот будет засада, если на самом деле как Вы сказали, модем принимает бинарный формат команд. Или у меня не совсем правильно написана функция для запроса на чтение данных из модема? Пишу драйвер первый раз) поэтому прошу прощения, если я что-то не правильно объяснил.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #3 : 25-04-2010 12:03 » |
|
STATUS_ORDINAL_NOT_FOUND ? очень странно. проверьте версии установленного WDF. а BSOD - совершенно однозначно указывает на некорректный код.. на самом деле я бы вам посоветовал для начала установить какой-нибудь монитор шины USB, наподобие HHD USB Monitor. и для начала просто посмотреть на пакеты, чтобы убедится что в них находится? увидите ли вы AT команды или нет при работе родного драйвера? и проверяйте на всякий случай WdfUsbTargetPipeFormatRequestForRead(): ReadMemory [in, optional] A handle to a framework memory object. This object represents a buffer that will receive data from the pipe. The buffer size must be a multiple of the pipe's maximum packet size unless the driver has called WdfUsbTargetPipeSetNoMaximumPacketSizeCheck. For more information about this buffer, see the following Remarks section. проверяйте после WdfUsbInterfaceGetConfiguredPipe структуру PWDF_USB_PIPE_INFORMATION. кстати... UsbBulkInPipe - у него адрес какой? у вас он точно на чтение? и... кстати а исходя из чего вы адреса выбирали? я не помню.. они автоматически детектятся?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #4 : 25-04-2010 17:02 » |
|
Спасибо за совет про HHD USB Monitor. Насчет pipe'ов. Через usbview (находится в src\usb\usbview, где установлен WDK) я посмотрел, у меня их 3 штуки: один на прерывание, другой на ввод и последний на вывод Вот функция конфигурирования pipe'ов NTSTATUS ConfigureUsbPipes(PDEVICE_CONTEXT DeviceContext) { NTSTATUS status = STATUS_SUCCESS; BYTE index = 0; WDF_USB_PIPE_INFORMATION pipeConfig; WDFUSBPIPE pipe = NULL;
WDFUSBINTERFACE usbInterface; UCHAR numInterfaces; BYTE numEndpoints; UCHAR i;
DeviceContext->UsbInterruptPipe = NULL; DeviceContext->UsbBulkInPipe = NULL; DeviceContext->UsbBulkOutPipe = NULL;
numInterfaces = WdfUsbTargetDeviceGetNumInterfaces(DeviceContext->UsbDevice); for (i = 0; i < numInterfaces; i++) { usbInterface = WdfUsbTargetDeviceGetInterface(DeviceContext->UsbDevice, i); numEndpoints = WdfUsbInterfaceGetNumEndpoints( usbInterface, 0 ); DbgPrint(" === numEndpoints i = %d\n", numEndpoints); } for (i = 0; i < numInterfaces; i++) { usbInterface = WdfUsbTargetDeviceGetInterface(DeviceContext->UsbDevice, i); WDF_USB_PIPE_INFORMATION_INIT(&pipeConfig); index = 0; do { pipe = WdfUsbInterfaceGetConfiguredPipe(usbInterface, index, &pipeConfig); if(NULL == pipe) break; DbgPrint(" === ConfigureUsbPipes, %i\n", index);
// none of our data transfers will have a guarantee that the requested // data size is a multiple of the packet size. WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);
if(WdfUsbPipeTypeInterrupt == pipeConfig.PipeType) { DeviceContext->UsbInterruptPipe = pipe; DbgPrint(" === WdfUsbPipeType Interrupt, packetsize = %d address = %d\n", pipeConfig.MaximumPacketSize, pipeConfig.EndpointAddress); } else if(WdfUsbPipeTypeBulk == pipeConfig.PipeType) { if(TRUE == WdfUsbTargetPipeIsInEndpoint(pipe)) { DeviceContext->UsbBulkInPipe = pipe; DbgPrint(" === WdfUsbTargetPipeIs InEndpoint, packetsize = %d address = %d\n", pipeConfig.MaximumPacketSize, pipeConfig.EndpointAddress); } else if(TRUE == WdfUsbTargetPipeIsOutEndpoint(pipe)) { DeviceContext->UsbBulkOutPipe = pipe; DbgPrint(" === WdfUsbTargetPipeIs OutEndpoint, packetsize = %d address = %d\n", pipeConfig.MaximumPacketSize, pipeConfig.EndpointAddress); } } index++; } while(NULL != pipe); }
if((NULL == DeviceContext->UsbInterruptPipe) || (NULL == DeviceContext->UsbBulkInPipe) || (NULL == DeviceContext->UsbBulkOutPipe)) { KdPrint((__DRIVER_NAME "Not all expected USB pipes were found.\n")); return STATUS_INVALID_PARAMETER; } return status; }
Функция вызывается в EvtDevicePrepareHardware. NTSTATUS EvtDevicePrepareHardware( IN WDFDEVICE Device, IN WDFCMRESLIST ResourceList, IN WDFCMRESLIST ResourceListTranslated ) { NTSTATUS status; PDEVICE_CONTEXT devCtx = NULL; WDF_USB_CONTINUOUS_READER_CONFIG interruptConfig;
UNREFERENCED_PARAMETER(ResourceList); UNREFERENCED_PARAMETER(ResourceListTranslated);
DbgPrint(" === EvtDevicePrepareHardware\n");
devCtx = GetDeviceContext(Device);
status = ConfigureUsbInterface(Device, devCtx, ResourceList, ResourceListTranslated); DbgPrint(" === ConfigureUsbInterface RESULT, 0x%08x\n", status);
if(!NT_SUCCESS(status)) return status;
DbgPrint(" === \n", status); status = ConfigureUsbPipes(devCtx); DbgPrint(" === ConfigureUsbPipes RESULT, 0x%08x\n", status); if(!NT_SUCCESS(status)) return status;
DbgPrint(" === \n", status); status = InitPowerManagement(Device, devCtx); DbgPrint(" === InitPowerManagement RESULT, 0x%08x\n", status); if(!NT_SUCCESS(status)) return status;
/*set up the interrupt endpoint with a continuous read operation. that way we are guaranteed that no interrupt data is lost.*/ WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&interruptConfig, EvtUsbDeviceInterrupt, devCtx, sizeof(BYTE)); status = WdfUsbTargetPipeConfigContinuousReader( devCtx->UsbInterruptPipe, &interruptConfig); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfUsbTargetPipeConfigContinuousReader failed with status 0x%08x\n", status)); return status; }
KdPrint((__DRIVER_NAME " === EvtDevicePrepareHardware SUCCESS, 0x%08x\n", status));
return status; }
В свою очередь, EvtDevicePrepareHardware(...) регистрируется в EvtDeviceAdd(...) NTSTATUS EvtDeviceAdd( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit ) { ............... /*set the callback functions that will be executed on PNP and Power events*/ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware; pnpPowerCallbacks.EvtDeviceD0Entry = EvtDeviceD0Entry; pnpPowerCallbacks.EvtDeviceD0Exit = EvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); ............... }
Вот, что показал usbview на устройстве с родными драйверами: Device Descriptor: bcdUSB: 0x0110 bDeviceClass: 0x02 bDeviceSubClass: 0x00 bDeviceProtocol: 0xFF bMaxPacketSize0: 0x40 (64) idVendor: 0x0572 (Conexant Systems, Inc.) idProduct: 0x1300 bcdDevice: 0x0100 iManufacturer: 0x01 iProduct: 0x02 iSerialNumber: 0x00 bNumConfigurations: 0x01
ConnectionStatus: DeviceConnected Current Config Value: 0x01 Device Bus Speed: Full Device Address: 0x01 Open Pipes: 3
Endpoint Descriptor: bEndpointAddress: 0x01 OUT Transfer Type: Bulk wMaxPacketSize: 0x0040 (64) bInterval: 0x00
Endpoint Descriptor: bEndpointAddress: 0x81 IN Transfer Type: Bulk wMaxPacketSize: 0x0040 (64) bInterval: 0x00
Endpoint Descriptor: bEndpointAddress: 0x82 IN Transfer Type: Interrupt wMaxPacketSize: 0x0040 (64) bInterval: 0x01
Configuration Descriptor: wTotalLength: 0x0049 bNumInterfaces: 0x02 bConfigurationValue: 0x01 iConfiguration: 0x03 bmAttributes: 0xA0 (Bus Powered Remote Wakeup) MaxPower: 0x82 (260 mA)
Interface Descriptor: bInterfaceNumber: 0x00 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0x0A bInterfaceSubClass: 0x00 bInterfaceProtocol: 0x00 iInterface: 0x04
Endpoint Descriptor: bEndpointAddress: 0x01 OUT Transfer Type: Bulk wMaxPacketSize: 0x0040 (64) bInterval: 0x00
Endpoint Descriptor: bEndpointAddress: 0x81 IN Transfer Type: Bulk wMaxPacketSize: 0x0040 (64) bInterval: 0x00
Interface Descriptor: bInterfaceNumber: 0x01 bAlternateSetting: 0x00 bNumEndpoints: 0x01 bInterfaceClass: 0x02 bInterfaceSubClass: 0x01 bInterfaceProtocol: 0xFF iInterface: 0x04
Endpoint Descriptor: bEndpointAddress: 0x82 IN Transfer Type: Interrupt wMaxPacketSize: 0x0040 (64) bInterval: 0x01
Unknown Descriptor: bDescriptorType: 0x24 bLength: 0x05 05 24 00 10 01
Unknown Descriptor: bDescriptorType: 0x24 bLength: 0x05 05 24 06 00 01
Unknown Descriptor: bDescriptorType: 0x24 bLength: 0x05 05 24 01 00 01
Unknown Descriptor: bDescriptorType: 0x24 bLength: 0x04 04 24 03 00
Unknown Descriptor: bDescriptorType: 0x24 bLength: 0x06 06 24 07 05 48 03
Насчет адресов pipe'ов: DebugView отображает следующее: 00000046 0.66781086 === ConfigureUsbPipes, 0 00000047 0.66787177 === WdfUsbTargetPipeIs OutEndpoint, packetsize = 64 address = 1 00000048 0.66790640 === ConfigureUsbPipes, 1 00000049 0.66794133 === WdfUsbTargetPipeIs InEndpoint, packetsize = 64 address = 129 00000050 0.66797543 === ConfigureUsbPipes, 0 00000051 0.66801006 === WdfUsbPipeType Interrupt, packetsize = 64 address = 130 00000052 0.66804415 === ConfigureUsbPipes RESULT, 0x00000000 Т.е. все конфигурирование pipe'ов проходит нормально. Да, еще забыл сказать, т.к. устройство цепляется к COM порту, то я еще обрабатываю соответственно управляющие коды COM порта, но пока там заглушки стоят. Эту часть сделал по подобию примера FakeModem из WDK
|
|
|
Записан
|
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #5 : 25-04-2010 17:28 » |
|
Немного спутал) адреса pipe'ов следующие: OutEndpoint = 7cecf888 InEndpoint = 7cecc478 Interrupt = 7d0900f0
|
|
|
Записан
|
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #6 : 25-04-2010 18:06 » |
|
Вот, что показал HHD USB Monitor при посылке через гипертерминал команды ati4. Предварительно я подключил модуль Serial к HHD USB Monitor'у: Packet View: 00000001 25.04.2010 20:01:47.984 PnP Event: Connect DOWN 0x00000000 5c 00 3f 00 3f 00 5c 00 55 00 53 00 42 00 23 00 56 00 69 00 … \ 00000002 25.04.2010 20:01:49.265 +1.281 IRP_MJ_WRITE DOWN 0x00000000 61 a 00000003 25.04.2010 20:01:49.265 +0.0 IRP_MJ_WRITE UP 0x00000000 61 a 00000004 25.04.2010 20:01:49.671 +0.406 IRP_MJ_WRITE DOWN 0x00000000 74 t 00000005 25.04.2010 20:01:49.671 +0.0 IRP_MJ_WRITE UP 0x00000000 74 t 00000006 25.04.2010 20:01:50.265 +0.593 IRP_MJ_WRITE DOWN 0x00000000 69 i 00000007 25.04.2010 20:01:50.265 +0.0 IRP_MJ_WRITE UP 0x00000000 69 i 00000008 25.04.2010 20:01:50.687 +0.421 IRP_MJ_WRITE DOWN 0x00000000 34 4 00000009 25.04.2010 20:01:50.687 +0.0 IRP_MJ_WRITE UP 0x00000000 34 4 00000010 25.04.2010 20:01:51.953 +1.265 IRP_MJ_WRITE DOWN 0x00000000 0d
00000011 25.04.2010 20:01:51.953 +0.0 IRP_MJ_WRITE UP 0x00000000 0d
00000012 25.04.2010 20:01:51.984 +0.031 IRP_MJ_READ UP 0x00000102 0d 0a 44 2d 4c 69 6e 6b 20 44 55 2d 35 36 32 4d 20 45 78 74 … D-Link DU-562M Ext… 00000013 25.04.2010 20:01:51.984 +0.0 IRP_MJ_READ DOWN 0x00000000
Request View 000001: PnP Event (DOWN), 25.04.2010 20:01:47.984 The device has just been connected to the system. 000002: Write Request (DOWN), 25.04.2010 20:01:49.265 +1.281 Buffer size: 0x1 bytes 61 a 000003: Write Request (UP), 25.04.2010 20:01:49.265 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000004: Write Request (DOWN), 25.04.2010 20:01:49.671 +0.406 Buffer size: 0x1 bytes 74 t 000005: Write Request (UP), 25.04.2010 20:01:49.671 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000006: Write Request (DOWN), 25.04.2010 20:01:50.265 +0.593 Buffer size: 0x1 bytes 69 i 000007: Write Request (UP), 25.04.2010 20:01:50.265 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000008: Write Request (DOWN), 25.04.2010 20:01:50.687 +0.421 Buffer size: 0x1 bytes 34 4 000009: Write Request (UP), 25.04.2010 20:01:50.687 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000010: Write Request (DOWN), 25.04.2010 20:01:51.953 +1.265 Buffer size: 0x1 bytes 0D . 000011: Write Request (UP), 25.04.2010 20:01:51.953 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000012: Read Request (UP), 25.04.2010 20:01:51.984 +0.031 Buffer size: 0x25 bytes Status: 0x00000102 0D 0A 44 2D 4C 69 6E 6B 20 44 55 2D 35 36 32 4D ..D-Link DU-562M 20 45 78 74 65 72 6E 61 6C 20 4D 6F 64 65 6D 0D External Modem. 0A 4F 4B 0D 0A .OK.. 000013: Read Request (DOWN), 25.04.2010 20:01:51.984 +0.0 Buffer size: 0x0 bytes
Data View Reads
0D 0A 44 2D 4C 69 6E 6B 20 44 55 2D 35 36 32 4D ..D-Link DU-562M 20 45 78 74 65 72 6E 61 6C 20 4D 6F 64 65 6D 0D External Modem. 0A 4F 4B 0D 0A .OK..
Writes 000002: 25.04.2010 20:01:49.265 +1.281
61 a 000004: 25.04.2010 20:01:49.671 +0.406
74 t 000006: 25.04.2010 20:01:50.265 +0.593
69 i 000008: 25.04.2010 20:01:50.687 +0.421
34 4 000010: 25.04.2010 20:01:51.953 +1.265
0D .
ModBus View: Packet 12: MODBUS Response (packet size: 0, data size: 37)
Mode: RTU Address: 13 (Slave) Function: 10 (Poll 484) CRC:3338 (WRONG)
...Хм как-то странно. насколько я понял запросу на запись IRP_MJ_WRITE соответствует WdfRequestTypeWrite, аналогично запросу на чтение IRP_MJ_READ WdfRequestTypeRead. В таком случае почему не работает, не совсем понятно (
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #7 : 25-04-2010 20:24 » |
|
пади разбери этот wdf
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #8 : 25-04-2010 20:36 » |
|
насчет адресов вы как раз не спутали))) первый раз. я физические адреса на шине как раз имел в виду: 0x01 и 0x81, 0x82 - похоже на правду. они однобайтные, старший бит - направление.
WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&interruptConfig, EvtUsbDeviceInterrupt, devCtx, sizeof(BYTE)); не маловато ли максимальный размер пакета? packetsize один байт... я не помню сколько для Interrupt, должно быть... но по вашему логу DebugView - должно быть 64. и проверьте остальные maxpacketsize в ВАШИХ IOCTL/READ/WRITE запросах. он должен быть не меньше требуемого)
PS resource, я тоже его пугаюсь.... так все просто было! а тут хрен поймешь чего они тут намудрили))
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #9 : 25-04-2010 21:17 » |
|
Просто моя философия такая - системный программист (особенно если речь о драйверах) должен пользоваться всем в первозданном виде, чтобы не добавлять новые проблемы к уже имеющимся, и что самое важное, видеть весь код таким, каким он в итоге и будет выполняться (понимаю, спорный тезис). Я конечно не имею ввиду впадать в маразм и писать на асме. Но вот всяческие надстройки не приветствую. В тоже время, не пытаюсь выставить это как абсолютную истину.
Извиняюсь за оффтоп
|
|
|
Записан
|
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #10 : 28-04-2010 06:47 » |
|
Просто моя философия такая - системный программист (особенно если речь о драйверах) должен пользоваться всем в первозданном виде, чтобы не добавлять новые проблемы к уже имеющимся, и что самое важное, видеть весь код таким, каким он в итоге и будет выполняться (понимаю, спорный тезис). Я конечно не имею ввиду впадать в маразм и писать на асме. Но вот всяческие надстройки не приветствую. В тоже время, не пытаюсь выставить это как абсолютную истину.
Извиняюсь за оффтоп
Просто если бы я пользовался WDM, у меня дольше времени ушло на разработку драйвера. В функции WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&interruptConfig, EvtUsbDeviceInterrupt, devCtx, 64); поставил 64 вместо sizeof(BYTE). Теперь постоянно на этапе чтения вылетает синий экран. Т.е. драйвер что-то пишет, но не понятно, так ли это. А чтение не работает. Попробовал вот так записывать status = WdfRequestRetrieveInputBuffer(Request, Length, &systemBuffer, &length); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; }
KdPrint(( " === [%s]\n", UCharToLPCStr(systemBuffer, Length) )); WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
и считывать: status = WdfRequestRetrieveOutputBuffer(Request, Length, &systemBuffer, &bufLen); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; }
status = WdfRequestForwardToIoQueue(Request, fmDeviceData->FmReadQueue); if (!NT_SUCCESS(status)) { WdfRequestCompleteWithInformation(Request, status, 0); return; }
аналогичная ситуация. Вылетает синий экран. Явно чего-то не хватает. Может быть задержка перед чтением должна быть? Но хотя для этого есть функция асинхронного чтения, которая тоже не работает.
|
|
|
Записан
|
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #11 : 28-04-2010 06:56 » |
|
Ochkarik, а как проверить maxpacketsize в IOCTL/READ/WRITE запросах? Информация храниться в одном из параметров функции EvtDeviceIoRead( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length ) ? Я при создании pipe выводил лог 00000046 0.66781086 === ConfigureUsbPipes, 0 00000047 0.66787177 === WdfUsbTargetPipeIs OutEndpoint, packetsize = 64 address = 1 00000048 0.66790640 === ConfigureUsbPipes, 1 00000049 0.66794133 === WdfUsbTargetPipeIs InEndpoint, packetsize = 64 address = 129 00000050 0.66797543 === ConfigureUsbPipes, 0 00000051 0.66801006 === WdfUsbPipeType Interrupt, packetsize = 64 address = 130 00000052 0.66804415 === ConfigureUsbPipes RESULT, 0x00000000
Здесь все pipe'ы имеют размер packetsize 64
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #12 : 28-04-2010 08:09 » |
|
так. давайте ка сначала. 1. насчет HHD монитора. вы кажется привели результат мониторинга IRP_READ/IRP_WRITE. а нужен был мониторинг пакетов URB самой шины. не помню как оно выглядело, но то что вы привели - на него не похоже. 2. насчет чтения. вы просто так USB пайп не прочтете. насколько я помню... кстати... посмотрите Агурова, там должно быть немного про идеологию шины написано. насколько я помню, чтение пайпа - это ожидание, пока от USB устройства не придет пакет. а пакет от устройства придет только тогда когда устройство его отправит. а отправит оно его только когда узнает что надо это сделать. а это произойдет только когда вы ей команду пошлете, на которую она сможет ответить. короче пайп чтения - это не паралельный порт. его абы когда читать не получится... посмотрите агурова, короче. 3. maxpacketsize в IOCTL/READ/WRITE не существует)))) там длинна запроса существует. вы документацию на используемые функции смотрите? http://msdn.microsoft.com/en-us/library/ff550014(VS.85).aspx"Length [out, optional] - A pointer to a location that receives the buffer's size, in byte" PS Просто если бы я пользовался WDM, у меня дольше времени ушло на разработку драйвера. а так вы пытаетесь что то делать не понимая как оно работает) а это тоже не вариант. на самом деле KMFD тоже требует изучения не меньшего... майкрософт его позиционировал не как конструктор, который сам все делает... а как обертку, для того чтобы программисты делали меньше ошибок) ПРЕДПОСЛЕДНЕЕ СООБЩЕНИЕ С КОДОМ я вообще не понял... вы что сделать пытались? ? я вообще не понял.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #13 : 28-04-2010 20:40 » |
|
Через гипертерминал посылал команду ATI6, и вот что из этого получилось - программа USBlyzer выдала следующий лог Type | Seq | Time | Request | Request Details | Raw Data | I/O | C:I:E | Device Object | Device Name | Driver Name | IRP | Status | Кнопка "A" URB | 0002 | 22:43:11.203 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF02B6F0h | | URB | 0003-0002 | 22:43:11.203 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF02B6F0h | Success (Success) | URB | 0004 | 22:43:11.203 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | | Кнопка "T" URB | 0005 | 22:43:11.750 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF02A008h | | URB | 0006-0005 | 22:43:11.750 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF02A008h | Success (Success) | URB | 0007-0004 | 22:43:11.765 | Bulk or Interrupt Transfer | 10 bytes data | C1 02 01 00 8C 23 02 00... | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | Success (Success) | URB | 0008 | 22:43:11.765 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | | Кнопка "I" URB | 0009 | 22:43:12.281 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | | URB | 0010-0009 | 22:43:12.281 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | Success (Success) | URB | 0011-0008 | 22:43:12.281 | Bulk or Interrupt Transfer | 10 bytes data | C1 02 01 00 8F 25 02 00... | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | Success (Success) | URB | 0012 | 22:43:12.281 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | | Кнопка "6" URB | 0013 | 22:43:12.921 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | | URB | 0014-0013 | 22:43:12.921 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | Success (Success) | URB | 0015-0012 | 22:43:12.937 | Bulk or Interrupt Transfer | 10 bytes data | C1 02 01 00 10 28 02 00... | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | Success (Success) | URB | 0016 | 22:43:12.937 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | | Кнопка Enter URB | 0017 | 22:43:13.609 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | | URB | 0018-0017 | 22:43:13.609 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF07A988h | Success (Success) | URB | 0019-0016 | 22:43:13.625 | Bulk or Interrupt Transfer | 10 bytes data | C1 02 01 00 C6 2A 02 00... | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | Success (Success) | URB | 0020 | 22:43:13.625 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | |
Более подробная информация про вот эту строчку URB 0002 22:43:11.203 Vendor Interface 32 01 2F 01 3D F1 0A 31... out 82155DE8h USBPDO-3 usbhub FF02B6F0h Raw Data 00000000 32 01 2F 01 3D F1 0A 31 01 27 0D 27 01 36 2./.=ñ.1.'.'.6 Setup Packet Offset Field Size Value Description 0 bmRequestType 1 41h 4..0: Recipient ...00001 Interface 6..5: Type .10..... Vendor 7: Direction 0....... Host-to-Device 1 bRequest 1 02h 2 wValue 2 FF01h 4 wIndex 2 0001h 6 wLength 2 000Eh
Более подробная информация про вот эту строчку URB 0007-0004 22:43:11.765 Bulk or Interrupt Transfer 10 bytes data C1 02 01 00 8C 23 02 00... in 01:01:82 82155DE8h USBPDO-3 usbhub 8210C008h Success (Success) Raw Data 00000000 C1 02 01 00 8C 23 02 00 0D 01 Á...Œ#.... Про Setup Packet информации нет Заметил, везде, где есть информация про Setup Packet направление посылки данных Host-to-Device После добавления serial-дополнения на HHD монитор, модем стал определяться как Serial устройство. Параллельно с UBLyzer'ом я получил лог HHD монитора: Вкладка Request View 000001: PnP Event (DOWN), 28.04.2010 22:42:51.671 The device has just been connected to the system. 000002: Write Request (DOWN), 28.04.2010 22:43:11.187 +19.515 Buffer size: 0x1 bytes A 000003: Write Request (UP), 28.04.2010 22:43:11.203 +0.015 Buffer size: 0x1 bytes Status: 0x00000000 000004: Write Request (DOWN), 28.04.2010 22:43:11.750 +0.546 Buffer size: 0x1 bytes T 000005: Write Request (UP), 28.04.2010 22:43:11.750 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000006: Write Request (DOWN), 28.04.2010 22:43:12.265 +0.515 Buffer size: 0x1 bytes I 000007: Write Request (UP), 28.04.2010 22:43:12.281 +0.015 Buffer size: 0x1 bytes Status: 0x00000000 000008: Write Request (DOWN), 28.04.2010 22:43:12.921 +0.640 Buffer size: 0x1 bytes 6 000009: Write Request (UP), 28.04.2010 22:43:12.921 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000010: Write Request (DOWN), 28.04.2010 22:43:13.609 +0.687 Buffer size: 0x1 bytes Enter (0D) 000011: Write Request (UP), 28.04.2010 22:43:13.609 +0.0 Buffer size: 0x1 bytes Status: 0x00000000 000012: Read Request (UP), 28.04.2010 22:43:13.625 +0.015 Buffer size: 0x39 bytes Status: 0x00000102
0D 0A 53 6F 66 74 4B 35 36 20 0D 0A 43 4D 6F 64 ..SoftK56 ..CMod 65 6D 20 56 65 72 73 69 6F 6E 20 31 32 0D 0A 52 em Version 12..R 6B 73 61 6D 70 6C 65 20 56 65 72 73 69 6F 6E 20 ksample Version 33 34 32 0D 0A 4F 4B 0D 0A 342..OK..
000013: Read Request (DOWN), 28.04.2010 22:43:13.625 +0.0 Buffer size: 0x0 bytes
PacketView Ordinal Time Function Direction Status Data 00000001 28.04.2010 22:42:51.671 PnP Event: Connect DOWN 0x00000000 5c 00 3f 00 3f 00 5c 00 55 00 53 00 42 00 23 00 56 00 69 00 … \ 00000002 28.04.2010 22:43:11.187 +19.515 IRP_MJ_WRITE DOWN 0x00000000 61 a 00000003 28.04.2010 22:43:11.203 +0.015 IRP_MJ_WRITE UP 0x00000000 61 a 00000004 28.04.2010 22:43:11.750 +0.546 IRP_MJ_WRITE DOWN 0x00000000 74 t 00000005 28.04.2010 22:43:11.750 +0.0 IRP_MJ_WRITE UP 0x00000000 74 t 00000006 28.04.2010 22:43:12.265 +0.515 IRP_MJ_WRITE DOWN 0x00000000 69 i 00000007 28.04.2010 22:43:12.281 +0.015 IRP_MJ_WRITE UP 0x00000000 69 i 00000008 28.04.2010 22:43:12.921 +0.640 IRP_MJ_WRITE DOWN 0x00000000 36 6 00000009 28.04.2010 22:43:12.921 +0.0 IRP_MJ_WRITE UP 0x00000000 36 6 00000010 28.04.2010 22:43:13.609 +0.687 IRP_MJ_WRITE DOWN 0x00000000 0d
00000011 28.04.2010 22:43:13.609 +0.0 IRP_MJ_WRITE UP 0x00000000 0d
00000012 28.04.2010 22:43:13.625 +0.015 IRP_MJ_READ UP 0x00000102 0d 0a 53 6f 66 74 4b 35 36 20 0d 0a 43 4d 6f 64 65 6d 20 56 … SoftK56 CModem V… 00000013 28.04.2010 22:43:13.625 +0.0 IRP_MJ_READ DOWN 0x00000000
И какой-то интересный лог на вкладке ModBus View Packet 12: MODBUS Response (packet size: 0, data size: 57) Mode: RTU Address: 13 (Slave) Function: 10 (Poll 484) CRC:3338 (WRONG) Это случайно ли не та функция, которую надо послать модему, чтоб он выполнил запись и отправил мне ответ? Если это так, то как она вызывается? И пока писал сообщение, возникла одна мысль. Если обратить внимание на время, то можно увидеть, что сначала идет запись в COM порт символа, например, T 00000004 28.04.2010 22:43:11.750 +0.546 IRP_MJ_WRITE DOWN 0x00000000 74 t 00000005 28.04.2010 22:43:11.750 +0.0 IRP_MJ_WRITE UP 0x00000000 74 t В этот же момент в логу USBLyzer запрос по USB Кнопка "T" URB | 0005 | 22:43:11.750 | Vendor Interface | | 32 01 2F 01 3D F1 0A 31... | out | | 82155DE8h | USBPDO-3 | usbhub | FF02A008h | | URB | 0006-0005 | 22:43:11.750 | Control Transfer | | | out | --:--:00 | 82155DE8h | USBPDO-3 | usbhub | FF02A008h | Success (Success) | URB | 0007-0004 | 22:43:11.765 | Bulk or Interrupt Transfer | 10 bytes data | C1 02 01 00 8C 23 02 00... | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | Success (Success) | URB | 0008 | 22:43:11.765 | Bulk or Interrupt Transfer | 64 bytes buffer | | in | 01:01:82 | 82155DE8h | USBPDO-3 | usbhub | 8210C008h | |
Значит из этого следует, что мне сначала надо записать в буфер, связанный с COM-портом status = WdfRequestRetrieveInputBuffer(Request, Length, &systemBuffer, &length); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; }
а потом послать синхронно что-то типа этого? WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDescriptor, requestMem, NULL);
WDF_USB_CONTROL_SETUP_PACKET_INIT( &controlPacket, BmRequestHostToDevice, BmRequestToDevice, 0x02, 0, 0); //method to send a USB control transfer request synchronously status = WdfUsbTargetDeviceSendControlTransferSynchronously( devCtx->UsbDevice, NULL, NULL, &controlPacket, &memDescriptor, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint((__DRIVER_NAME "WdfUsbTargetDeviceSendControlTransferSynchronouslyfailed with status 0x%08x\n", status)); }
Фу... вроде вот такие у меня идеи. Как вы думаете, я прав? или не так запросы надо отсылать?
|
|
|
Записан
|
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #14 : 28-04-2010 20:59 » |
|
ПРЕДПОСЛЕДНЕЕ СООБЩЕНИЕ С КОДОМ я вообще не понял... вы что сделать пытались? ? я вообще не понял. Как я понял WdfRequestRetrieveInputBuffer() это запись в буфер, привязанный к COM-порту, т.е. запрос на запись A request's input buffer contains information, such as data to be written to a disk, that was supplied by the originator of the request. Your driver can call WdfRequestRetrieveInputBuffer to obtain the input buffer for a write request or a device I/O control request, but not for a read request (because read requests do not provide input data).
Тем более в примерах WDK для последовательных устройств эта функция WdfRequestRetrieveInputBuffer используется.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #15 : 29-04-2010 19:57 » |
|
опробовал вот так записывать Код: status = WdfRequestRetrieveInputBuffer(Request, Length, &systemBuffer, &length); if (!NT_SUCCESS(status)) { WdfRequestComplete(Request, status); return; }
KdPrint(( " === [%s]\n", UCharToLPCStr(systemBuffer, Length) )); WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length); - что вы тут делали? где тут запись то? вы получили указатель на входной буфер и ввели его в виде дебагового сообщения... о какой записи шла речь? ?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #16 : 29-04-2010 19:59 » |
|
А как тогда записать?
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #17 : 30-04-2010 05:21 » |
|
вы получили указатель на входной буфер и ввели его в виде дебагового сообщения Да еще и извратно как-то. А как тогда записать?
Перефразирую: а как копировать данные в по этому адресу?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #18 : 30-04-2010 13:42 » |
|
resource, Перефразирую: а как копировать данные в по этому адресу?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Alpha
Интересующийся
Offline
|
|
« Ответ #19 : 12-05-2010 20:51 » |
|
огромное спасибо за советы!) но в итоге после долгого разговора с преподавателем я решил отложить написание этого драйвера и взял другую тему, написать драйвер для геймпада, который отлавливает нажатые кнопки, возник небольшой вопрос, как от одного драйвера послать другому драйверу - драйверу клавиатуры - запрос на нажатие кнопки - но это уже другая тема Может быть летом допишу драйвер для модема) в общем подумаю)
|
|
|
Записан
|
|
|
|
|