Windows USB 编程

GUIDhtml

#include <initguid.h> // For DEFINE_GUID算法

// Device Interface GUID.
DEFINE_GUID(GUID_DEVINTERFACE_FOR_D3XX,
            0xd1e8fe6a, 0xab75, 0x4d9e, 0x97, 0xd2, 0x6, 0xfa, 0x22, 0xc7, 0x73, 0x6c);
GUID DeviceGUID[2] = {0};
GUID是经过特定算法产生的一个二进制长度为128位的数字,在空间上和时间上具备惟一性,保证同一时间不一样地方产生的数字不一样。GUID的主要目的是产生彻底惟一的数字。在理想状况下,任何计算机和计算机集群都不会生成两个相同的GUID。随机生成两个相同GUID的可能性是很是小的,但并不为0。
  用了DEFINE_GUID,你可使用在全部源文件中包含同一个头文件,在头文件中这样定义GUID:DEFINE_GUID(CLSID_MyObject,0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  在没有包含Initguid.h的地方,DEFINE_GUID宏建立外部引用来使用GUID值,在包含Initguid.h的地方,DEFINE_GUID重定义DEFINE_GUID宏以产生GUID的定义。安全

typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
memcpy()服务器

#include<string.h>
// Open a device handle by GUID
memcpy(&DeviceGUID[0], &GUID_DEVINTERFACE_FOR_D3XX, sizeof(GUID));
函数原型:void memcpy( voiddest, const void *src, size_t n );
函数功能:由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
返回值: 函数返回一个指向dest的指针。数据结构

主要目的是,使用GUID惟一标识USB设备,并把打开USB设备的句柄存储到GUID的数据结构中。多线程

memcmp()app

#include<string.h>
//Compare bytes read with bytes written
memcmp(acWriteBuf, acReadBuf, sizeof(acReadBuf));
函数原型: int memcmp(const void *str1, const void *str2, size_t n)) ;
函数功能:把存储区 str1 和存储区 str2 的前 n 个字节进行比较。
返回值: 若是返回值 < 0,则表示 str1 小于 str2。若是返回值 > 0,则表示 str2 小于 str1。若是返回值 = 0,则表示 str1 等于 str2。异步

isprint()async

#include <ctype.h>
if (!isprint(pManufacturer[i]))
    return FALSE;
函数原型:int isprint( int c );
函数功能:检查所传的字符是不是可打印的,可打印字符是非控制字符的字符。
返回值: 若是 c 是一个可打印的字符,则该函数返回非零值(true),不然返回 0(false)。
主要目的是,检验输入的参数是否正确。函数

OVERLAPPED

功能做用:Overlapped I/O的设计的目的:取代多线程功能(多线程存在同步机制,线程上下文切换是十分消耗CPU资源的)。Overlapped I/O模型是OS为你传递数据,完成上下文切换,在处理完以后通知你。由程序自己的处理,变为OS的处理(内部也是用线程处理的)。也就是说程序运行的同时,系统再开辟一个I/O操做的新线程,I/O操做的时间和线程执行其它任务的时间是重叠(OVERLAPPED)的。


// Create the overlapped io event for asynchronous transfer
    OVERLAPPED vOverlappedWrite = {0};
    vOverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Write asynchronously
// When FT_WritePipe is called with overlapped io,
// the function will immediately return with FT_IO_PENDING
    ftStatus = FT_WritePipe(ftHandle, 0x02, acWriteBuf, ulBytesToWrite, &ulBytesWritten, &vOverlappedWrite);
                if (ftStatus == FT_IO_PENDING)
            {
                // Poll until all data requested ulBytesToWrite is sent
                do
                {
                    // FT_GetOverlappedResult will return FT_IO_INCOMPLETE if not yet finish
                    ftStatus = FT_GetOverlappedResult(ftHandle, &vOverlappedWrite, &ulBytesWritten, FALSE);
                    if (ftStatus == FT_IO_INCOMPLETE)
                    {
                        continue;
                    }
                    else if (FT_FAILED(ftStatus))
                    {
                        CloseHandle(vOverlappedWrite.hEvent);
                        FT_Close(ftHandle);
                        return FALSE;
                    }
                    else //if (ftStatus == FT_OK)
                    {
                        // exit now
                        break;
                    }
                }
                while (1);
            }
            // Delete the overlapped io event
            CloseHandle(vOverlappedWrite.hEvent);
程序解读:
  由于 FT_WritePipe()是同步阻塞操做,若是要作到异步写操做,就要用到 vOverlapped parameter。
  CreateEvent() 建立事件对象,指定该内核对象是自动重置的(FALSE)。而且指定该内核对象起始状态是未通知状态的(FALSE)。
  当 FT_WritePipe() 用 overlapped IO 调用时,会当即返回 FT_IO_PENDING 。
  进入循环的做用是判断写操做是否完成。经过 FT_GetOverlappedResult() 检测写操做是否完成,若未完成则返回 FT_IO_INCOMPLETE ;写操做线程继续,同时检测线程检测。
  最后关闭事件对象。
  你能够这样认为重叠IO,如今你已经进入一个服务器/客户机环境,请不要混淆概念,这里的服务器是指操做系统,而客户机是指你的程序(它进行IO操做),是当你进行IO操做(send,recv,writefile,readfile….)时你发送一个IO请求给服务器(操做系统),由服务器来完成你须要的操做,而后你什么事都没有了(有点像开辟新线程),当服务器完成IO请求时它会通知你,固然在这期间你能够作任何事,一个经常使用的技巧是在发送重叠IO请求后,程序在一个循环中一边调用PeekMessage,TranslateMessage和DispatchMessage更新界面,同时调用 GetOverlappedResult等待服务器完成IO操做,更高效一点的作法是使用IO完成例程来处理服务器(操做系统)返回的结果,但并非每一个支持重叠IO操做的函数都支持完成例程如TransmitFile函数.

OVERLAPPED 数据结构:

typedef struct _OVERLAPPED {
  DWORD Internal; //一般被保留,当GetOverlappedResult()传回False而且GatLastError()并不是传回ERROR_IO_PENDINO时,该状态置为系统定的状态。
  DWORD InternalHigh; //一般被保留,当GetOverlappedResult()传回False时,为被传输数据的长度。
  DWORD Offset; //指定文件的位置,从该位置传送数据,文件位置是相对文件开始处的字节偏移量。调用 ReadFile或WriteFile函数以前调用进程设置这个成员,读写命名管道及通讯设备时调用进程忽略这个成员;
  DWORD OffsetHigh; //指定开始传送数据的字节偏移量的高位字,读写命名管道及通讯设备时调用进程忽略这个成员;
  HANDLE hEvent; //标识事件,数据传送完成时把它设为信号状态,调用ReadFil,eWriteFile,ConnectNamedPipe TransactNamedPipe函数前,调用进程设置这个成员. 相关函数CreateEvent ResetEvent GetOverlappedResult WaitForSingleObject CWinThread GetLastError
} OVERLAPPED, *LPOVERLAPPED;
CreateEvent 数据结构:

HANDLE CreateEvent(
PSECURITY_ATTRIBUTES psa,
BOOL bManualReset,
BOOL bInitialState,
PCTSTR pszName);
第一个参数:是安全描述符,设为NULL表示使用默认的安全描述符,而且子进程没法继承返回的句柄。
  第二个参数:指定了该内核对象是人工重置(传递TRUE)的仍是自动重置(传递FALSE)的。
  第三个参数:指定了该内核对象起始状态是已通知(传递TRUE)仍是未通知状态(FALSE)。
  第四个参数:为要建立的事件内核对象起一个名字,若是传递NULL,则建立一个“匿名”的事件内核对象。若是不传递NULL,且系统中已经存在该名字的事件内核对象,则不建立新的事件内核对象而是打开这个已经存在的,返回它的句柄。
  该函数若是成功,返回事件内核对象的句柄,这样就能够操纵它了。若是失败,返回NULL。

事件内核对象(hEvent):
  事件内核对象最一般的用途是:让一个线程执行初始化工做,而后触发另外一个线程,让它执行剩余的工做,一开始的时候咱们将事件初始化为未触发状态,而后当线程完成初始化工做的时候触发事件。
  一个事件内核对象的触发表示一个操做已经完成。有两种类型的事件内核对象:手动重置事件和自动重置事件。
当一个手动重置对象被触发的时候,正在等待该事件的全部线程都将变成可调度状态。而当一个自动重置事件被触发时,只有一个正在等待该事件的线程会变成可调度状态。
  对同一个文件handle,系统有多个异步操做时(一边读文件头,一边写文件尾, 有一个完成,就会有信号,不能区分是那种操做。),为每一个进行中的overlapped调用GetOverlappedResult是很差的做法。

SetEvent设置事件为触发状态,ResetEvent设置事件为未触发状态。

句柄必定要关闭,经过CloseHandle。

C++ 中_In_ 和_out_

__ In__ 代表定义的变量或参数是做为输入,即须要给这个参数赋值,传递给某个函数去执行;

__ out__ 代表定义的变量或参数是做为输出,即须要给该参数一个地址,函数内部往这个地址写数据;

//////////////////////////////////////////////////////////////////
// Setting of chip configuration ( enables/disables streaming mode )
//////////////////////////////////////////////////////////////////
BOOL StartStreamPipe(
        FT_HANDLE ftHandle,
// _In_ : it's macro definition, need assign a value to parameter
           _In_  UCHAR a_ucPipeID,
           _In_  ULONG a_ulStreamSize
    )
{
    return FT_SetStreamPipe(ftHandle,
            FALSE,
            FALSE,
            a_ucPipeID,
            a_ulStreamSize
    ) == FT_OK ? TRUE : FALSE;
}

 

https://www.cnblogs.com/leon19870907/archive/2011/09/23/2186291.html

https://www.jianshu.com/p/3afc1eb5bd32

https://www.jianshu.com/p/cf8e7df5ff09

https://www.jianshu.com/p/2a6e22194cd3

相关文章
相关标签/搜索