📄 usbbulk.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/USB-Bulk
*
* (c) Copyright 2003 - 2004, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : USBBULK.c
Purpose : USB functions
---------------------------END-OF-HEADER------------------------------
*/
#include <windows.h>
#include <WINIOCTL.H>
#include "USBBULK.h"
/*********************************************************************
*
* Defines
*/
#define USBBULK_DEVICE_PATH "\\\\.\\usbbulk"
#define USBBULK_PIPE_READ_PATH (USBBULK_DEVICE_PATH"\\pipe00")
#define USBBULK_PIPE_WRITE_PATH (USBBULK_DEVICE_PATH"\\pipe01")
#define USB_BULK_IOCTL_INDEX 0x0111
#define DEFAULT_TIMEOUT 10*1000 // 10 seconds
#define IOCTL_USB_BULK_GET_CONFIG_DESCRIPTOR CTL_CODE(FILE_DEVICE_UNKNOWN, USB_BULK_IOCTL_INDEX+0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_BULK_RESET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, USB_BULK_IOCTL_INDEX+1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_USB_BULK_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, USB_BULK_IOCTL_INDEX+2, METHOD_BUFFERED, FILE_ANY_ACCESS)
/*********************************************************************
*
* Typedefs
*/
typedef struct {
HANDLE hDevice; // handle to device
HANDLE hPipeRead; // handle to pipe in
HANDLE hPipeWrite; // handle to pipe out
OVERLAPPED OverlapRead;
int Timeout;
} CONN_INFO;
typedef CONN_INFO *USBBULK_HANDLE;
/*********************************************************************
*
* Static data
*/
static CONN_INFO * _pConnInfo;
/*********************************************************************
*
* _Read
*
* Function description
*/
static int _Read(void * pBuffer, int NumBytesReq) {
static int nBytesRead = 0;
ReadFile(_pConnInfo->hPipeRead, pBuffer, NumBytesReq, &nBytesRead, &_pConnInfo->OverlapRead);
if (WaitForSingleObject(_pConnInfo->OverlapRead.hEvent, _pConnInfo->Timeout) == WAIT_TIMEOUT) {
CancelIo(_pConnInfo->hPipeRead);
return nBytesRead; // Timed out, let's cancel pending I/O operation on the pipe
}
// check on the results of the asynchronous read
GetOverlappedResult(_pConnInfo->hPipeRead, &_pConnInfo->OverlapRead, &nBytesRead, FALSE);
return nBytesRead;
}
/*********************************************************************
*
* USBBULK_SetTimeout
*
* Function description
*/
void USBBULK_SetTimeout(int Timeout) {
if (_pConnInfo) {
_pConnInfo->Timeout = (DWORD) Timeout;
}
}
/*********************************************************************
*
* USBBULK_Open
*
* Function description
*/
void *USBBULK_Open(void) {
CONN_INFO *pConnInfo;
HANDLE hTmp;
pConnInfo = (CONN_INFO *) calloc(sizeof(CONN_INFO), 1);
USBBULK_ResetPipe();
if (pConnInfo) {
pConnInfo->Timeout = 1000;
hTmp = CreateFile(USBBULK_DEVICE_PATH,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0, NULL);
if (hTmp != INVALID_HANDLE_VALUE) {
pConnInfo->hDevice = hTmp;
//
// Create read pipe
//
hTmp = CreateFile(USBBULK_PIPE_READ_PATH, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hTmp != INVALID_HANDLE_VALUE) {
pConnInfo->hPipeRead = hTmp;
//
// Init overlay structure
//
pConnInfo->OverlapRead;
memset (&pConnInfo->OverlapRead, 0, sizeof(pConnInfo->OverlapRead));
pConnInfo->OverlapRead.hEvent = CreateEvent(NULL, 1, 0, NULL);
//
// Create write pipe
//
hTmp = CreateFile(USBBULK_PIPE_WRITE_PATH, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hTmp != INVALID_HANDLE_VALUE) {
pConnInfo->hPipeWrite = hTmp;
} else {
CloseHandle(pConnInfo->hPipeRead);
CloseHandle(pConnInfo->hDevice);
}
} else {
CloseHandle(pConnInfo->hDevice);
}
}
}
if (hTmp == INVALID_HANDLE_VALUE) {
free(pConnInfo);
pConnInfo = NULL;
}
_pConnInfo = pConnInfo;
return pConnInfo;
}
/*********************************************************************
*
* USBBULK_Close
*
* Function description
*/
void USBBULK_Close(void) {
if (_pConnInfo) {
CloseHandle(_pConnInfo->hPipeRead);
CloseHandle(_pConnInfo->hPipeWrite);
CloseHandle(_pConnInfo->hDevice);
CloseHandle(_pConnInfo->OverlapRead.hEvent);
free(_pConnInfo);
_pConnInfo = NULL;
}
}
/*********************************************************************
*
* USBBULK_Read
*
* Function description
*/
int USBBULK_Read(void * pBuffer, int Size) {
return _Read(pBuffer, Size);
}
/*********************************************************************
*
* USBBULK_Write
*/
int USBBULK_Write(void * pBuffer, int Size) {
int NumBytesWritten = 0;
if (_pConnInfo) {
if (!WriteFile(_pConnInfo->hPipeWrite, pBuffer, (DWORD)Size, &NumBytesWritten, NULL)) {
NumBytesWritten = 0;
}
}
return NumBytesWritten;
}
/*********************************************************************
*
* USBBULK_WriteRead
*
* Function description
* Write to the device & read.
* Reason to have this function is that it reduces latencies.
*/
int USBBULK_WriteRead(const void* pWrite, int WrSize, void* pRead, int RdSize) {
int NumBytesWritten = 0;
int NumBytesRead = 0;
if (_pConnInfo) {
ReadFile(_pConnInfo->hPipeRead, pRead, RdSize, &NumBytesRead, &_pConnInfo->OverlapRead);
if (!WriteFile(_pConnInfo->hPipeWrite, pWrite, WrSize, &NumBytesWritten, NULL)) {
NumBytesWritten = 0;
}
if (WaitForSingleObject(_pConnInfo->OverlapRead.hEvent, _pConnInfo->Timeout) == WAIT_TIMEOUT) {
CancelIo(_pConnInfo->hPipeRead);
return NumBytesRead; // Timed out, let's cancel pending I/O operation on the pipe
}
// check on the results of the asynchronous read
GetOverlappedResult(_pConnInfo->hPipeRead, &_pConnInfo->OverlapRead, &NumBytesRead, FALSE);
}
return NumBytesRead;
}
/*********************************************************************
*
* USBBULK_Control
*
* Function description
*/
int USBBULK_Control(USBBULK_CONTROL Action, PVOID pBuffer, int Size) {
DWORD len = 0;
BOOL Res;
if (Action == UsbResetPipe) {
Res = DeviceIoControl(_pConnInfo->hPipeRead, IOCTL_USB_BULK_RESET_PIPE, NULL, 0, NULL, 0, &len, NULL);
if (Res) {
Res = DeviceIoControl(_pConnInfo->hPipeWrite, IOCTL_USB_BULK_RESET_PIPE, NULL, 0, NULL, 0, &len, NULL);
}
} else if (Action == UsbResetDevice) {
Res = DeviceIoControl(_pConnInfo->hDevice, IOCTL_USB_BULK_RESET_DEVICE, NULL, 0, NULL, 0, &len, NULL);
} else if (Action == UsbGetConfigDescriptor) {
Res = DeviceIoControl(_pConnInfo->hDevice, IOCTL_USB_BULK_GET_CONFIG_DESCRIPTOR,
pBuffer, Size, pBuffer, Size, &len, NULL);
}
return(Res);
}
/*********************************************************************
*
* USBBULK_GetConfigDescriptor
*
* Function description
*/
int USBBULK_GetConfigDescriptor (void* pBuffer, int Size) {
int len;
return DeviceIoControl(_pConnInfo->hDevice, IOCTL_USB_BULK_GET_CONFIG_DESCRIPTOR,
pBuffer, Size, pBuffer, Size, &len, NULL);
}
/*********************************************************************
*
* USBBULK_ResetPipe
*
* Function description
*/
int USBBULK_ResetPipe(void) {
return 0; // TBD
}
/*********************************************************************
*
* USBBULK_ResetDevice
*
* Function description
*/
int USBBULK_ResetDevice(void) {
return 0; // TBD
}
/*************************** End of file ****************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -