• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    WinUSB驅動實現(xiàn)及其通信傳輸應用

    2018-09-14 07:51:18石保敬王長荀怯肇乾
    軟件 2018年8期
    關鍵詞:句柄描述符線程

    石保敬,王長荀,怯肇乾

    ?

    WinUSB驅動實現(xiàn)及其通信傳輸應用

    石保敬,王長荀,怯肇乾

    (河南馳誠電氣,河南 鄭州 450001)

    微軟近年來推出的規(guī)范簡便的WinUSB設備通信模型,編程對接的關鍵是“底層USB設備如何添加描述使Windows OS識別其為WinUSB設備”和“可視化測試/應用程序怎樣通過WinUSB.dll調用與之進行管道數(shù)據(jù)傳輸?shù)膶崿F(xiàn)”,恰到好處的運用定時器或線程是異步快速實時數(shù)據(jù)接收軟件設計的核心,USB測試/應用程序發(fā)布針對低級操作系統(tǒng)版本需要編寫引導安裝程序,USB設備插拔處置和多USB設備通信的操控也需要特定處置,如此編程設計,Windows下USB設備傳輸通信就如同傳統(tǒng)的RS-232C通信一樣方便自如而且還直截了當和迅速高效了。

    USB描述符;WinUSB設備;異步數(shù)據(jù)傳輸;定時數(shù)據(jù)接收;線程數(shù)據(jù)接收

    0 引言[9]

    Windows操作系統(tǒng)OS(Operation System)下,通過USB(Universal Serial Bus)接口,讀寫訪問USB設備,是嵌入式應用系統(tǒng)和可視化測試/應用軟件開發(fā)必不可少的常用環(huán)節(jié)。微軟從Winxp-SP2版本開始,在Windows中集成了通用的WinUSB Device驅動及其連接OS底層和應用層的WinUSB.dll,極大簡化了USB數(shù)據(jù)的通信傳輸。恰到好處的運用WinUSB進行開發(fā),同樣可以到達類似使用傻瓜托管式的WinDriver軟件的效果。編程設計的關鍵是如何讓Windows快速的把USB設備識別為通用WinUSB設備和應用軟件怎樣合理調用WinUSB.dll對應的WinUSB.lib庫。本文就此展開詳細闡述。

    開發(fā)WinUSB驅動實現(xiàn)及其通信傳輸應用,可以采用C++、C#或JavaScript等語言,最好的集成開發(fā)環(huán)境IDE(Integrated Development Environment)是Visial Studio,也可以是Rad Studio XE等,無論哪個IDE都需要首先安裝Windows驅動程序開發(fā)工具包WDK(Windows Driver Kit)。這里以Rad Studio XE和STM32F103系列微控制器的可視化USB設備通信開發(fā)為例加以說明。

    1 底層USB設備通信支持[1-4]

    嵌入式應用系統(tǒng)實現(xiàn)USB設備通信,主要是在高優(yōu)先級的中斷服務程序中實現(xiàn)的,包括常規(guī)的USB標準請求應答和管道讀寫收發(fā)實現(xiàn),管道操作主要是中斷和批量傳輸,USB標準請求包括設備、配置、接口及其端點描述與速度限定變換。必須設法讓Windows識別為通用WinUSB設備,可視化測試/應用程序才可以使用通用的WinUSB設備驅動進行溝通交互,如圖1所示。

    圖1 通用WinUSB設備的操作系統(tǒng)識別

    為此,需要特別構造1個標準USB類描述符--OS描述符和2個供應商類描述符--OS特征ID(Identifier)描述符和注冊設備接口GUID描述符。全球唯一標識符GUID(Globally Unique Identifier)。

    1.1 標準USB類OS描述符

    OS描述符,定義存儲在字符串索引0xEE 處,對應的USB標準請求為:

    80 06 ee 03 00 00 12 00

    典型的OS描述符定義如下:

    #define bMS_VendorCode 0x01

    //Vendor 請求的請求代碼

    const unsigned char OsDscrptStr[] =

    // "MSFT100" : index : 0xEE : langId : 0

    { 0x12, 0x03, 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, bMS_VendorCode, 0 };

    1.2 供應商類OS特征ID描述符

    供應商類OS特征ID描述符,用作設置擴展兼容,對應的供應商類請求為:

    初步請求--c0 01 00 00 04 00 10 00,再次請求--c0 01 00 00 04 00 28 00

    典型的OS特征ID描述符包定義如下:

    const unsigned char cptbIdDscrpt [] =

    { 0x28, 0x00, 0x00, 0x00, //包長

    0x00, 0x01, //BCD版本

    0x04, 0x00, //索引

    0x01, //數(shù)量

    0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, //保留[7]

    0x00, //第一接口編號

    0x01, //保留(0x01)

    'W', 'I', 'N', 'U', 'S', 'B',

    0x00, 0x00, //兼容ID[8]

    0x00, 0x00, 0x00, 0x00,

    0x00, 0x00, 0x00, 0x00, //子兼容ID[8]

    0x00, 0x00, 0x00,

    0x00, 0x00, 0x00 //保留[6]

    };

    1.3 供應商類注冊設備接口GUID

    供應商類注冊設備接口GUID,將體現(xiàn)在注冊表中,如圖2所示,GUID可用相應工具軟件產(chǎn)生。

    圖2 Windows注冊表中的特定通用USB設備接口GUID示意圖

    該描述符,供應用程序調用該GUID做讀寫訪問的USB設備識別,對應的供應商類請求為:

    初次請求--c1 01 00 00 05 00 0a 00,再次請求--c1 01 00 00 05 00 8e 00

    典型的注冊設備接口 GUID描述符定義如下:

    const unsigned char itfcGuidDscrpt[] =

    { 0x8E, 0x00, 0x00, 0x00, //包長(頭+各部分)

    0x00, 0x01, //頭: BCD版本

    0x05, 0x00, //索引

    0x01, 0x00, //數(shù)量

    0x84, 0x00, 0x00, 0x00 //部分: 大小

    0x01, 0x00, 0x00, 0x00, //屬性數(shù)據(jù)類型

    0x28, 0x00, //屬性名字長度

    { 'D', 0, 'e', 0, 'v', 0, 'i', //屬性名稱[40]:

    0, 'c', 0, 'e', 0, 'I', 0, "DeviceInterfaceGUID"

    'n',0, 't', 0, 'e', 0, 'r',

    0, 'f',0, 'a', 0, 'c', 0,

    'e', 0, 'G',0, 'U', 0,

    'I', 0, 'D', 0, 0, 0

    },

    0x4E, 0x00, //屬性數(shù)據(jù)長度:

    0x00, 0x00, 78[0x4E]

    { '{', 0, '1', 0, '2', 0, '3', 0, //屬性數(shù)據(jù): {12345678-

    '4', 0, '5', 0, '6', 0, '7', 1234-1234-1234-

    0, 8', 0, '-', 0, '1', 0, '2', 123456789ABC}

    0, '3', 0, '4', 0, '-', 0, '1',

    0, '2', 0, '3', 0, 4', 0, ' '-',

    0, '1', 0, '2', 0, '3', 0, '4',

    0, '-', 0, '1', 0,'2', 0, '3', 0,

    '4', 0, '5', 0, '6', 0, '7', 0,

    8', 0, '9', 0, 'A', 0, 'B', 0,

    'C', 0, '}', 0, 0, 0

    }

    };

    可用作者的“ARM系列微處理控制器的軟件體系架構工具”得到完整的STM32103系列USB驅動程序,包括上述3個特殊描述符在內的標準USB請求類和供應商請求及其應答配置與控制、中斷、批量或同步管道傳輸代碼,限于篇幅,不再贅述。

    2 WinUSB設備驅動運用[3-4,10]

    可視化測試/應用程序中使用Windows OS通用的WinUSB設備驅動,必須引入對WDK頭文件的引用,需要在可視化窗口.cpp文件頭部加入的典型.h文件引用如下:

    #include "Windows Kits10Include10.0.15063. 0sharedusb.h"

    #include "Windows Kits10Include10.0.15063. 0sharedstrsafe.h"

    #include "Windows Kits10Include10.0.15063. 0umSetupAPI.h"

    #include "Windows Kits10Include10.0.15063. 0umwinusb.h"

    可視化測試/應用程序,通過連接OS底層和應用層的WinUSB.dll操作特定的通用WinUSB Device,必須在項目工程中引用WinUSB.dll對應的WinUSB.lib庫文件。WDK提供有相應的WinUSB. lib,在Visival Studio中引用沒有問題,但不能直接在Rad Studio XE中引用,編譯連接時會報錯:

    BCB contains invalid OMF record, type 0x21 (possibly COFF)

    這是IDE要求的原始設備制造商OEM(Original Equipment Manufacturer)的通用對象文件格式COFF(Common Object File Format)不同引起的lib文件兼容不足導致的??梢允褂肦ad Studio XE的coff2omf. exe工具進行轉換再加以引用,命令行操作如下,其中前者是微軟DDK提供的,后者就是得到的Rad Studio XE開發(fā)所需的庫:

    coff2omf -lib:ms WinUSB.lib bcb WinUSB.lib

    3 WinUSB通信傳輸實現(xiàn)[3-8]

    3.1 WinUSB設備文件操作

    與其它OS一樣,Winsows把設備當做文件操作,但USB設備又有特定的集成端點在內的管道傳輸?shù)慕涌?,所以打開USB設備文件后還要打開相應的USB接口,得到特定的USB接口操作句柄,之后就可以運用該句柄,調用管道讀寫進行數(shù)據(jù)傳輸了。可視化測試/應用程序退出時必須依次關閉USB接口操作句柄和設備文件操作句柄。

    獲取USB設備及其接口操作句柄的典型函數(shù)代碼如下:

    HANDLE hDeviceHandle = INVALID_HANDLE_VALUE; // 設備文件句柄

    WINUSB_INTERFACE_HANDLE hWinUSBHandle // WinUSB操作句柄

    = INVALID_HANDLE_VALUE;

    // USB設備文件句柄創(chuàng)建[接口GUID,設備句柄]-------------------------------------------------------------------

    BOOL GetDeviceHandle(GUID guidDeviceInterface, PHANDLE hDeviceHandle )

    { if ( guidDeviceInterface == GUID_NULL ) return FALSE;

    BOOL bResult = TRUE; HDEVINFO hDeviceInfo;

    SP_DEVINFO_DATA DeviceInfoData; DWORD index = 0;

    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;

    PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;

    ULONG requiredLength = 0; LPTSTR lpDevicePath = NULL;

    // 為特定設備的接口類而獲取安裝設備的所有信息

    hDeviceInfo = SetupDiGetClassDevs(&guidDeviceInterface, NULL, NULL,

    DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );

    if ( hDeviceInfo == INVALID_HANDLE_VALUE ) goto done; // 無效退出

    // 在設備信息集中枚舉所有設備接口

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

    for(index=0; SetupDiEnumDeviceInfo(hDeviceInfo, index, & DeviceInfoData); index++)

    { if(lpDevicePath) LocalFree(lpDevicePath); // 復位相應項

    if(pInterfaceDetailData) LocalFree(pInterfaceDetailData);

    deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

    bResult = SetupDiEnumDeviceInterfaces( hDeviceInfo, // 獲取設備接口信息

    &DeviceInfoData, &guidDeviceInterface, 0, &deviceInterfaceData );

    if(GetLastError()== ERROR_NO_MORE_ITEMS) break; // 最后項?

    if(!bResult) goto done; // 錯誤退出

    // 動態(tài)調用2次,首次分配空間,再次得到接口數(shù)據(jù)

    bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo,

    &deviceInterfaceData, NULL, 0, &requiredLength, NULL );

    if(!bResult) // 錯誤檢查

    { if((ERROR_INSUFFICIENT_BUFFER == GetLastError())

    && ( requiredLength > 0 ) )

    { pInterfaceDetailData = // 動態(tài)分配緩沖區(qū)大小

    (PSP_DEVICE_INTERFACE_DETAIL_DATA)

    LocalAlloc(LPTR, requiredLength );

    if (!pInterfaceDetailData ) goto done; // 錯誤退出

    }

    else goto done; // 錯誤退出

    }

    pInterfaceDetailData->cbSize // 獲取接口詳細數(shù)據(jù)

    = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo,

    &deviceInterfaceData, pInterfaceDetailData,

    requiredLength, NULL, &DeviceInfoData );

    if (!bResult) goto done; // 錯誤退出

    size_t nLength = wcslen(pInterfaceDetailData->DevicePath ) + 1; // 設備文件路徑

    lpDevicePath = (TCHAR *) LocalAlloc( LPTR, nLength * sizeof(TCHAR));

    StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);

    lpDevicePath[(nLength - 1)] = 0;

    }

    if (!lpDevicePath) goto done; // 錯誤退出

    }

    *hDeviceHandle = CreateFile( lpDevicePath, // 打開設備文件, 得到設備文件句柄

    GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ

    | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,

    FILE_FLAG_OVERLAPPED, NULL);

    if (*hDeviceHandle != INVALID_HANDLE_VALUE ) return true;

    done: LocalFree( lpDevicePath );

    LocalFree( pInterfaceDetailData );

    bResult = SetupDiDestroyDeviceInfoList( hDeviceInfo );

    return bResult;

    }

    // 獲取設備的 WinUSB 接口句柄------------------------------------------------------------------------------------

    BOOL GetWinUSBHandle(HANDLE hDeviceHandle,

    PWINUSB_INTERFACE_HANDLE phWinUSBHandle)

    { if(hDeviceHandle == INVALID_HANDLE_VALUE) return FALSE;

    BOOL bResult = WinUsb_Initialize(hDeviceHandle, phWinUSBHandle);

    if (!bResult) return FALSE;

    return bResult;

    }

    可視化窗口,創(chuàng)建時運用特定USB接口GUID,調用這兩個函數(shù)創(chuàng)建設備文件句柄和USB接口操作句柄;窗口關閉時依次關閉這兩個句柄;若USB設備沒有掛接,應用禁止窗口上所有USB數(shù)據(jù)收發(fā)按鈕操作,相關核心代碼如下:

    void__fastcall TfrmShow::FormCreate(TObject *Sender)

    {static const GUID stm32F1xxDvcItfc = { 0x-12345678, 0x1234, 0x1344,

    {0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC } };

    GUID guidDeviceInterface = stm32F1xxDvcItfc;

    BOOL bResult = TRUE; ULONG cbSize = 0;

    bResult = GetDeviceHandle(guidDeviceInterface, &hDeviceHandle);

    if (!bResult) return;

    bResult = GetWinUSBHandle(hDeviceHandle, & hWinUSBHandle);

    if(!bResult) return;

    flgWinUSB = true;

    }

    //---------------------------------------------------------

    void __fastcall TfrmShow::FormClose(TObject *Sender, TCloseAction &Action)

    { if(!flgWinUSB) return;

    CloseHandle(hDeviceHandle);

    WinUsb_Free(hWinUSBHandle);

    }

    3.2 收發(fā)傳輸?shù)牟呗钥紤]

    運用WinUSB應用程序編程接口API (Appli-cation Programming Interface)函數(shù)WinUsb_ReadPipe和WinUsb_WritePipe進行數(shù)據(jù)管道收發(fā)傳輸時,若沒有收到或發(fā)出數(shù)據(jù),程序會一直等待,造成可視化窗口失控,可以通過調用WinUsb_SetPipePolicy函數(shù),使用WinUSB的超時管道傳輸策略來避免這種阻塞式的尷尬局面,取消請求之前等待超時時間,超過超時時間退出等待。通常在USB設備文件句柄和WinUSB接口句柄創(chuàng)建成功后進行超時傳輸設置,時間據(jù)實際傳輸量而定,典型代碼如下,這里超時時間取100ms,0x81對應輸入IN管道1,0x02對應輸出OUT管道2:

    UINT timeout = 100;

    bResult = WinUsb_SetPipePolicy(hWinUSBHandle, 0x81, // 輸入IN管道1

    PIPE_TRANSFER_TIMEOUT, sizeof (timeout), & timeout);

    if(!bResult) return;

    bResult = WinUsb_SetPipePolicy(hWinUSBHandle, 0x02, // 輸出OUT管道2

    PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout);

    if(!bResult) return;

    3.3 數(shù)據(jù)發(fā)送操作實現(xiàn)

    數(shù)據(jù)發(fā)送,同異步操作差別不大,只要準備好數(shù)據(jù),很容易知道其數(shù)據(jù)大小,主動同步發(fā)出,以最簡方式實現(xiàn),典型代碼如下:

    if(hWinUSBHandle==INVALID_HANDLE_VALUE) return;

    UCHAR szBffr[50]; ULONG cbSent = 0;

    AnsiString str = edtSdDt->Text; // 窗口文本輸入控件

    strcpy(szBffr, str.c_str());

    ULONG cbSize = str.Length();

    WinUsb_WritePipe(hWinUSBHandle, 0x02, szBffr, cbSize, &cbSent, 0 );

    3.4 異步數(shù)據(jù)傳輸?shù)膶崿F(xiàn)

    異步數(shù)據(jù)收發(fā)傳輸,對于不知數(shù)據(jù)量大小的操作非常有效,特別是USB管道的讀操作。

    首先需要定義全局的OVERLAPPED結構變量,并在USB設備文件及其WinUSB接口句柄創(chuàng)建成功后初始化這個結構變量,主要是其相關“事件Event”的初始化,典型代碼如下:

    OVERLAPPED overlapped;

    ZeroMemory(&overlapped, sizeof(overlapped));

    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    典型的異步USB管道讀事件代碼如下,首先以小固定數(shù)量15進行盲讀,在限定的超時時間內,只要收到數(shù)據(jù),都可以接收,并成行顯示在窗口的文本指示框內:

    void WinUSB_Read(void)

    { if(hWinUSBHandle==INVALID_HANDLE_VALUE) return;

    ULONG cbRead = 0; UCHAR szBffr[20] = {'0'}; AnsiString str;

    BOOL bResult = WinUsb_ReadPipe(hWinUSB-Handle, 0x81,

    szBffr, 15, &cbRead, &overlapped);

    if(bResult)

    { const char* t = szBffr; str = t;

    mRcvDt->Lines->Add(str); // 可視窗口文本顯示控件

    }

    else if(ERROR_IO_PENDING == GetLastError ())

    {bResult = WinUsb_GetOverlappedResult(hW-inUSBHandle, & overlapped, &cbRead, true);

    if(NULL != cbRead)

    { int m = cbRead; cbRead = 0;

    if(bResult)

    { const char* d = szBffr; str = d;

    mmRcvDt->Lines->Add(str);

    }

    }

    }

    }

    3.5 定時數(shù)據(jù)接收的實現(xiàn)

    隨時監(jiān)聽USB輸入管道并接收可能傳入的數(shù)據(jù),在可視化測試/應用程序設計中,簡潔高效的方法就是采用定時器控制,以一定的時間間隔,在定時器的OnTimer事件處理中,去異步的讀取USB輸入管道,典型代碼如下,其中設置的時間間隔是100 ms:

    void __fastcall TfrmShow::rcvTmrTimer(TObject *Sender)

    { rcvTmr->Enabled = false; // 關閉定時器

    WinUSB_Read(); // 異步數(shù)據(jù)謀取并進行可視化窗口顯示

    rcvTmr->Enabled = true; // 重開定時器

    }

    3.6 后臺線程數(shù)據(jù)接收實現(xiàn)

    以線程方式在后臺進行USB輸入管道的監(jiān)聽并接收可能傳入的數(shù)據(jù),是另外一種及時高效的USB數(shù)據(jù)接收形式。在項目工程中新建線程對象rcvThrd,進而在生成的rcvThrd.h文件中聲明引用的窗口顯示控件和數(shù)據(jù)接收函數(shù)RcvDt(),典型代碼如下:

    class thrdRcvDt : public TThread

    { private: TMemo *memo;

    protected: void __fastcall Execute();

    public: void __fastcall thrdRcvDt::RcvDt();

    __fastcall thrdRcvDt(bool CreateSuspended, TMemo *Amemo);

    };

    在rcvThrd.cpp文件中,聲明所需的包含文件、外部變量,并定義操作函數(shù),典型代碼如下:

    #include "frmStm32Tst.h" // 可視化窗口文件

    #include "Windows Kits10Include10.0.15063. 0sharedusb.h" // DDK文件

    #include "Windows Kits10Include10.0.15063. 0sharedstrsafe.h"

    #include "Windows Kits10Include10.0.15063. 0umSetupAPI.h"

    #include "Windows Kits10Include10.0.15063. 0umwinusb.h"

    extern WINUSB_INTERFACE_HANDLE hWin-USBHandle;

    extern OVERLAPPED overlapped;

    extern void WinUSB_Read(void);

    __fastcall thrdRcvDt::thrdRcvDt(bool Create-Suspended, TMemo *Amemo) : TThread(CreateSu-spended)

    { memo = Amemo; }

    void __fastcall thrdRcvDt::Execute() // 線程執(zhí)行[休眠100ms]

    { while(!Terminated)

    { Synchronize(RcvDt); Sleep(100); }

    }

    void __fastcall thrdRcvDt::RcvDt() // 數(shù)據(jù)異步接收窗口指示

    { WinUSB_Read(); }

    在可視化窗口的frmStm32Tst.h中加入線程對象包含和線程實例化聲明,典型代碼如下:

    #include "rcvThrd.h"

    class TfrmShow : public TForm

    { …

    private: thrdRcvDt *rcvThrd;

    }

    在可視化窗口的frmStm32Tst.cpp中,打開設備文件和WinUSB接口句柄后,啟動線程,定義線程終止時自動銷毀,然后運行線程,典型代碼如下:

    rcvThrd = new thrdRcvDt(true, mmRcvDt);

    rcvThrd->FreeOnTerminate = true;

    rcvThrd->Resume();

    對比定時數(shù)據(jù)接收,異曲同工。定時器控件,本質就是休眠時間可調整的線程操作封裝。

    3.7 設備插撥及相應處置

    以上闡述基于先插上USB設備,再打開可視化測試/應用程序,進行通信傳輸,用后關閉應用程序,撥下設備。而USB設備即插即用,在USB設備突然被拔下后,還進行讀寫傳輸,程序就阻塞了。為避免這種現(xiàn)象發(fā)生,可創(chuàng)建一個線程,定時(如每2s)枚舉檢查相關的USB設備,若被拔下,停止定時數(shù)據(jù)接收或休眠接收線程;若重新插入,則重新創(chuàng)建操作句柄,恢復定時數(shù)據(jù)接收或線程數(shù)據(jù)接收。

    4 WinUSB應用/測試程序的發(fā)布[3-4,8]

    4.1 Win8.1以上系統(tǒng)

    應用軟件發(fā)布,除Rad Studio產(chǎn)生的.exe文件外,還需要包含WinUSB.lib。若編譯時不能包含動態(tài)庫,還需要包含IDE相關的cc32240mt.dll和borlndmm.dll。上述各種方法綜合在一起,得到的針對STM32F103系列微控制USB設備的WinUSB數(shù)據(jù)收發(fā)測試的可視化應用程序窗口界面如圖3所示:

    圖3 WinUSB數(shù)據(jù)收發(fā)測試的可視化應用程序窗口界面

    4.2 WinXP-Win8系統(tǒng)

    編寫驅動安裝文件.inf,引導OS調用內置的winusb.sys驅動文件的安裝應用,主要指明USB設備的廠商號、產(chǎn)品號、USB接口GUID等,通知安裝程序類已設置為 "USBDevice"。需要使用WinUSB協(xié)助安裝庫文件WinUsbCoInstaller,區(qū)分32位和64位版本,常用版本是V1.9,Win7之后也可以是V1.11。Win7之后系統(tǒng),還需要準備cat文件,可運用WDK的Inf2Cat.exe工具得到,命令行操作如下:

    Inf2Cat.exe /driver:[inf文件目錄] /os: XP_X86, XP_X64,7_X86,7_X64,8_X32,8_X64

    典型inf驅動安裝文件如下:

    [Version]

    Signature="$Windows NT$"

    Class=USBDevice

    ClassGUID={88BAE032-5A81-49f0-BC3D-A4-FF138216D6}

    Provider=%ManufacturerName%

    CatalogFile=instlWinUSB.cat

    DriverVer=01/13/2018,12.4.23.896

    [Manufacturer]

    %ManufacturerName%=Standard,NTx86,NTx64

    [Standard.NTx86]

    %DeviceName%=USB_Install,USBVID_0483& PID_5720

    [Standard.NTx64]

    %DeviceName%=USB_Install,USBVID_0483& PID_5720

    [ClassInstall32]

    AddReg=ClassInstall_AddReg

    [ClassInstall_AddReg]

    HKR,,,,%ClassName%

    HKR,,NoInstallClass,,1

    HKR,,IconPath,%REG_MULTI_SZ%,"C:WindowsSystem32setupapi.dll,-20"

    HKR,,LowerLogoVersion,,5.2

    [USB_Install]

    Include=winusb.inf

    Needs=WINUSB.NT

    [USB_Install.Services]

    Include=winusb.inf

    AddService=WinUsb,0x00000002,WinUsb_Ser-viceInstall

    [WinUsb_ServiceInstall]

    DisplayName=%WinUsb_SvcDesc%

    ServiceType=1

    StartType=3

    ErrorControl=1

    ServiceBinary=C:WindowsSystem32driversWin--USB.sys

    [USB_Install.HW]

    AddReg=Dev_AddReg

    [Dev_AddReg]

    HKR,,DeviceInterfaceGUIDs,0x10000,"{12345678-1234-1344-1234-123456789ABC}"

    [USB_Install.Wdf]

    KmdfService=WINUSB, WinUsb_Install

    [WinUSB_Install]

    KmdfLibraryVersion=1.9

    [USB_Install.CoInstallers]

    AddReg=CoInstallers_AddReg

    CopyFiles=CoInstallers_CopyFiles

    [CoInstallers_AddReg]

    HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller"

    [CoInstallers_CopyFiles]

    WdfCoInstaller01009.dll

    [DestinationDirs]

    CoInstallers_CopyFiles=11

    [SourceDisksNames]

    1=%DiskName%

    [SourceDisksFiles]

    WdfCoInstaller01009.dll=1

    [Strings]

    ManufacturerName="STMicroelectronics"

    ClassName="USB通用串行總線設備"

    DiskName="kzq"

    WinUsb_SvcDesc="WinUSB Driver"

    DeviceName="STM3210"

    REG_MULTI_SZ = 0x00010000

    5 多WinUSB設備應用測試的實現(xiàn)

    多個同類WinUSB設備插入同一臺電腦,系統(tǒng)都可以識別,通信時連接傳輸快的USB設備占主動權后,其它USB設備就不通信了??梢孕薷腢SB設備的接口GUID,使連入USB設備差異化,以實現(xiàn)各個對應的傳輸通信,找到一個設備通信一個,從而實現(xiàn)類似設備參數(shù)配置的批量操作實現(xiàn)。

    6 驅動開發(fā)對比

    表1 幾種驅動及其開發(fā)對比表

    Tab.1 Some kind of device drivers and it’s design comparison

    7 結語

    底層嵌入式應用軟件中添加特定描述支持,Windows OS就可以自動識其為WinUSB設備,上層可視化測試/應用程序就可以通過WinUSB.dll與其進行USB數(shù)據(jù)傳輸通信了。這樣,Windows下USB設備的數(shù)據(jù)采集、監(jiān)視控制、配置參數(shù)、軟件刷新等軟件編程操控,就同傳統(tǒng)的“RS-232C通信”一樣了,無需USB轉串口硬軟件轉接,而且速度快、實時性強,直截了當。同樣,定時接收、線程接收、多設備通信等軟件手段也可以搬來使用,進一步提升效率和實用性。

    [1] CSDN博客. USB設備描述符舉例說明[EB/OL]. http://blog. csdn.net/u013256018/article/details/60805770?locationNum=10&fps=1, 2017.3.

    [2] CSDN博客﹒WinUSB--微軟為所有USB設備提供的常規(guī)驅動程序[EB/OL]. http://blog.csdn.net/whw8007/article/details/ 9569989, 2013.8.

    [3] 微軟開發(fā)網(wǎng). 如何通過WinUSB功能訪問USB設備[EB/OL]. https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff540174(v=vs.85).aspx, 2017.12.

    [4] 馬開東博客. 如何使用WinUSB與USB設備USBDevice通信[EB/OL]. http://www.makaidong.com/%E5%8D%9A%E5% AE%A2%E5%9B%AD7/20151013/306670_4.html, 2015.10.

    [5] 微軟開發(fā)網(wǎng). 適用于USB設備的Windows桌面應用[EB/OL]. https://msdn.microsoft.com/zh-cn/library/windows/ hardware/dn376885(v=vs.85).aspx, 2017.12.

    [6] 微軟開發(fā)網(wǎng). 編寫基于WinUSB模板的Windows桌面應用[EB/OL]. https://msdn.microsoft.com/zh-cn/library/windows/ hardware/dn376872(v=vs.85).aspx, 2017.12.

    [7] 微軟開發(fā)網(wǎng). 用于管道策略修改的WinUSB功能[EB/OL]. https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff728833(v=vs.85).aspx, 2017.12.

    [8] 怯肇乾等. Windows異步串行通信編程縱橫[J]. 電腦與開發(fā)應用, 2009, 6(445): 21-25.

    [9] CSDN博客. winusb--不再為你的usb設備編寫驅動[EB/OL]. https://blog.csdn.net/phenixyf/article/details/46744419, 2015.7.

    [10] 彭偉. 基于WinUSB與SHT75的溫濕度數(shù)據(jù)采集與控制系統(tǒng)設計仿真[J]. 制造業(yè)自動化, 2013, 7(15): 129-133.

    Implementation of WinUSB Driver and Its Application in Communication Transmission

    SHI Bao-jing, WANG Chang-xun, KAI Zhao-qian

    (HNCC Electronic Co., LTD, Zhengzhou 450001, China)

    Software design key about WinUSB-Device-Model-Application is how to add descriptor to WinUSB-Device in Windows OS and how to communicate in Windows Application. It’s kernel is how to use timer and thread with asynchronous-data-transmission. Note WinUSB-Application-Publishing in low operating system version, account USB-Plug-in-Plug-out handling and multi-USB-devices-communication. So, Windows USB device data transmission are easy to use such as RS-232C.

    USB descriptor; WinUSB device; Asynchronous data transmission; Data reception with timer; Data reception with thread.

    TP36

    B

    10.3969/j.issn.1003-6970.2018.08.013

    怯肇乾(1969-),男,電子與信息技術高級工程師,嵌入式系統(tǒng)設計師/培訓師,web網(wǎng)絡測控軟件系統(tǒng)架構師,研究方向為軟硬件體系及其網(wǎng)絡系統(tǒng)軟件設計;石保敬(1977-),男,經(jīng)濟師,風險評估師,環(huán)保健康探測警報專家,研究方向為危害和易燃易爆氣體探測產(chǎn)品系統(tǒng)及其開發(fā)設計;王長荀(1988-),男,嵌入式硬軟件開發(fā)工程師,研究方向為軟硬件體系及其網(wǎng)絡系統(tǒng)軟件設計。

    本文著錄格式:石保敬,王長荀,怯肇乾. WinUSB驅動實現(xiàn)及其通信傳輸應用[J]. 軟件,2018,39(8):57-64

    猜你喜歡
    句柄描述符線程
    基于結構信息的異源遙感圖像局部特征描述符研究
    測繪學報(2022年12期)2022-02-13 09:13:01
    Linux單線程并發(fā)服務器探索
    高校圖書館持久標識符應用研究
    利用CNN的無人機遙感影像特征描述符學習
    編譯程序語法分析句柄問題分析與探討
    淺談linux多線程協(xié)作
    MFC應用程序多線程混合顯示界面方法研究
    基于SPY++的軟件功能擴展的研究
    Linux線程實現(xiàn)技術研究
    基于PDIUSBD12的USB接口設計應用研究
    昌图县| 安仁县| 卓资县| 图片| 平湖市| 彰武县| 游戏| 衡水市| 仙居县| 九寨沟县| 宜宾县| 嵊泗县| 永兴县| 德兴市| 特克斯县| 成安县| 长海县| 澄城县| 林甸县| 巧家县| 安远县| 江阴市| 康保县| 钟祥市| 内江市| 长泰县| 灵武市| 开远市| 东海县| 阿瓦提县| 陆良县| 巴彦淖尔市| 凌云县| 大厂| 贺兰县| 云梦县| 兴城市| 襄樊市| 台北县| 房产| 正蓝旗|