0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

USB設(shè)備加載與卸除的通用方法介紹

英創(chuàng)信息技術(shù) ? 作者:英創(chuàng)信息技術(shù) ? 2019-09-25 17:09 ? 次閱讀

有時應(yīng)用需要檢查USB設(shè)備的加載與卸除消息,如U盤的插上與拔出。一種辦法是以輪詢的方式調(diào)用設(shè)備接口嘗試訪問設(shè)備,但這樣的做法效率很低,并且實時性不高。本文將介紹更為通用的方法,通過系統(tǒng)API函數(shù)RequestDeviceNotifications,讀取設(shè)備消息,獲得設(shè)備加載及移除的消息。

查找設(shè)備IClass值

每個USB設(shè)備都有一個IClass值,相當(dāng)于在系統(tǒng)里的編號,IClass值可以通過查詢板子注冊表獲得。以U盤為例:

USB設(shè)備加載與卸除的通用方法介紹

如圖,[HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers]下存有所有USB設(shè)備類型的信息。Mass_Storage_Class即U盤的IClass值為{A4E7EDDA-E575-4252-9D6B-4195D48BB865}

用代碼表示即

GUID guid = { 0xA4E7EDDA, 0xE575, 0x4252, { 0x9D, 0x6B, 0x41, 0x95, 0xD4, 0x8B, 0xB8, 0x65 } };

調(diào)用API監(jiān)聽設(shè)備消息

監(jiān)聽流程如下:

創(chuàng)建消息隊列->綁定設(shè)備和消息隊列->讀取消息隊列

以U盤為例,代碼如下

MSGQUEUEOPTIONS msgopts;

//{A4E7EDDA-E575-4252-9D6B-4195D48BB865} 這個是USB storage的

GUID guid = { 0xA4E7EDDA, 0xE575, 0x4252, { 0x9D, 0x6B, 0x41, 0x95, 0xD4, 0x8B, 0xB8, 0x65 } };

msgopts.dwSize = sizeof(MSGQUEUEOPTIONS);

msgopts.dwFlags = 0;

msgopts.dwMaxMessages = 10; //?

msgopts.cbMaxMessage = sizeof(MYDEV);

msgopts.bReadAccess = TRUE;

HANDLE m_hReadMsgQ = CreateMsgQueue(NULL, &msgopts);

HANDLE hNotify;

DWORD ret;

hNotify = RequestDeviceNotifications(&guid, m_hReadMsgQ, TRUE);

flags = 0;

size = 0;

//while(true){

ret = WaitForSingleObject(m_hReadMsgQ, INFINITE);

if(ret == WAIT_OBJECT_0)

{

while (ReadMsgQueue(m_hReadMsgQ, &detail, sizeof(detail), &size, 1, &flags) == TRUE) //參數(shù)“1”表示1ms超時

{

if (detail.d.fAttached)

{

wprintf(L"%s %s,f=0x%x\r\n", detail.d.szName, detail.d.fAttached ? L"appeared" : L"was removed", flags);

}

Else

{

wprintf(L"%s %s,f=0x%x\r\n", detail.d.szName, detail.d.fAttached ? L"appeared" : L"was removed", flags);

}// if (detail.d.fAttached)

}//while

}//if(ret == WAIT_OBJECT_0)

//}while(true)

CloseMsgQueue(m_hReadMsgQ);

注意:如果是U盤,這里讀到的detail.d.szName是U盤在驅(qū)動中的名稱,如“DSK1”,并非U盤盤符。

消息隊列里讀到的消息包括已加載設(shè)備的加載消息。

根據(jù)設(shè)備加載消息獲得準(zhǔn)確的設(shè)備信息

以U盤為例,它的設(shè)備類型為“DSK”,而SD卡,NANDFLASH的設(shè)備類型也是DSK,所以從設(shè)備消息里讀出設(shè)備名如“DSK1”、“DSK2”后并不能直觀確定哪個是U盤的設(shè)備名。

這時可以調(diào)用存儲器相關(guān)API函數(shù)OpenStore根據(jù)設(shè)備名,查詢U盤盤符等信息。

必要的頭文件及l(fā)ib庫

#include "Storemgr.h"

#pragma comment(lib,"Storeapi.lib")

封裝OpenStore函數(shù)

增加超時是有必要的,因為設(shè)備加載消息來得更快,可能存儲設(shè)備還沒完全加載好。最長可能慢1ms,所以稍加延時即可。

HANDLE WINAPI OpenStoreEx(LPCTSTR szDeviceName, DWORD timeout = 3)

{

HANDLE hStore;

int i;

for(i=0;i

{

hStore = OpenStore(szDeviceName);

if (hStore != INVALID_HANDLE_VALUE)

{

break;;

}

Sleep(1);

}

return hStore;

}

獲得詳細(xì)信息

GetStoreInfo(hStore, &StoreInfo);

//if(wcscmp(StoreInfo.szStoreName, L"SD Memory Card") == 0) //判斷是SD卡

//else if(wcscmp(StoreInfo.szStoreName, L"NANDFS") == 0) //判斷是NandFlash

//else if (wcscmp(StoreInfo.szStoreName, L"USB Hard Disk Drive") == 0) //判斷是U盤

wprintf(L"%s %s %s,f=0x%x\r\n", detail.d.szName, StoreInfo.szStoreName, detail.d.fAttached ? L"appeared" : L"was removed", flags);

用鏈表存儲設(shè)備信息

在U盤加載時,可以通過訪問存儲驅(qū)動API來查詢設(shè)備信息。但是當(dāng)設(shè)備移除后,設(shè)備信息就不存在于驅(qū)動中了,所以用OpenStore和GetStoreInfo就無法查到已移除的設(shè)備信息了。

想要知道移除的設(shè)備詳細(xì)信息,就只有在加載的時候?qū)⑿畔⒋嬖跀?shù)據(jù)結(jié)構(gòu)中。這樣在移除時,通過查詢數(shù)據(jù)結(jié)構(gòu)中的數(shù)據(jù),就可以獲得設(shè)備詳細(xì)信息了。

數(shù)據(jù)結(jié)構(gòu)根據(jù)實際需求,使用數(shù)組,鏈表,MAP,都可以。英創(chuàng)對客戶提供一份使用單向鏈表實現(xiàn)的例程。

其它設(shè)備

USB擴(kuò)展串口模塊

英創(chuàng)主板擴(kuò)展串口號均在10以上,所以通過設(shè)備名中的設(shè)備號,能很容易確定是否為USB擴(kuò)展的串口設(shè)備。

USB打印機(jī)、攝像頭等

這些USB設(shè)備通過設(shè)備名即能確定是什么USB設(shè)備。

相關(guān)例程可以聯(lián)系英創(chuàng)工程師獲得。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7979

    瀏覽量

    265719
  • 嵌入式主板
    +關(guān)注

    關(guān)注

    7

    文章

    6086

    瀏覽量

    35545
收藏 人收藏

    評論

    相關(guān)推薦

    檢查u***設(shè)備加載卸除方法

      有時應(yīng)用需要檢查USB設(shè)備加載卸除消息,如U盤的插上與拔出。一種辦法是以輪詢的方式調(diào)用設(shè)備接口嘗試訪問
    發(fā)表于 01-04 14:34

    USB主機(jī)和設(shè)備介紹

    USB主機(jī)和設(shè)備USB總裁中最重要的就是USB主機(jī)和USB設(shè)備。
    發(fā)表于 05-23 09:23

    Freescale USB大容量存儲設(shè)備引導(dǎo)加載器資料分享

    USB大容量存儲設(shè)備(MSD)引導(dǎo)加載程序
    發(fā)表于 12-09 07:28

    USB大容量存儲設(shè)備主機(jī)引導(dǎo)加載程序資料分享

    USB大容量存儲設(shè)備(MSD)主機(jī)引導(dǎo)加載程序
    發(fā)表于 12-09 06:07

    微軟 USB存儲設(shè)備通用驅(qū)動 for Win9X

    微軟 USB存儲設(shè)備通用驅(qū)動 for Win9X.zip
    發(fā)表于 01-26 14:39 ?5次下載

    創(chuàng)意USB設(shè)備介紹

    創(chuàng)意USB設(shè)備介紹 奇百怪的創(chuàng)意設(shè)備盤點又和大家見面了。繼前幾期推出了千奇百怪USB玩意兒盤點后,大家可謂大開了眼界。有網(wǎng)友來電詢問
    發(fā)表于 04-28 10:20 ?1239次閱讀

    通用串行總線USB設(shè)備的驅(qū)動

    從問題的由來、類驅(qū)動程序、通信協(xié)議、描述符、驅(qū)動開發(fā)等對 USB 的驅(qū)動進(jìn)行分析和討論,提出USB 設(shè)備使用操作系統(tǒng)嵌入的通用類驅(qū)動程序成為趨勢。
    發(fā)表于 06-03 17:10 ?126次下載
    <b class='flag-5'>通用</b>串行總線<b class='flag-5'>USB</b><b class='flag-5'>設(shè)備</b>的驅(qū)動

    將DSP物理連接到USB主機(jī)上的USB引導(dǎo)加載程序

    TMS32 VC5506/C5507/C5509/C5509A數(shù)字信號處理器(DSP)的加載通過處理器通用串行總線(USB)外圍設(shè)備是標(biāo)準(zhǔn)的一部分。在
    發(fā)表于 04-25 10:49 ?8次下載
    將DSP物理連接到<b class='flag-5'>USB</b>主機(jī)上的<b class='flag-5'>USB</b>引導(dǎo)<b class='flag-5'>加載</b>程序

    如何通過系統(tǒng)API函數(shù)讀取USB設(shè)備消息,獲得設(shè)備加載及移除的消息

    有時應(yīng)用需要檢查USB設(shè)備加載卸除消息,如U盤的插上與拔出。一種辦法是以輪詢的方式調(diào)用設(shè)備接口嘗試訪問
    發(fā)表于 08-31 17:52 ?5476次閱讀
    如何通過系統(tǒng)API函數(shù)讀取<b class='flag-5'>USB</b><b class='flag-5'>設(shè)備</b>消息,獲得<b class='flag-5'>設(shè)備</b><b class='flag-5'>加載</b>及移除的消息

    如何加載USB-Blaster驅(qū)動的詳細(xì)視頻資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何加載USB-Blaster驅(qū)動的詳細(xì)視頻資料說明。
    發(fā)表于 05-06 16:40 ?3次下載
    如何<b class='flag-5'>加載</b><b class='flag-5'>USB</b>-Blaster驅(qū)動的詳細(xì)視頻資料說明

    HMI畫面加載到HMI設(shè)備方法

    可將自己新建的項目加載到 HMI設(shè)備并在運(yùn)行系統(tǒng)中執(zhí)行。 為此,組態(tài)設(shè)備和 HMI設(shè)備之間必須建立連接。 如果您沒有使用 HMI設(shè)備,則
    的頭像 發(fā)表于 09-21 09:29 ?5869次閱讀
    HMI畫面<b class='flag-5'>加載</b>到HMI<b class='flag-5'>設(shè)備</b>的<b class='flag-5'>方法</b>

    通用圖像加載器教程及案例

    ) ImageLoader配置(線程執(zhí)行器、下載器、解碼器、內(nèi)存和磁盤緩存、顯示圖像選項等)的廣泛定制 每個顯示圖像調(diào)用都有很多定制選項(存根圖像、緩存開關(guān)、解碼選項、位圖處理和顯示等) 圖像緩存在內(nèi)存和/或磁盤(設(shè)備的文件系統(tǒng)或SD卡) 監(jiān)聽加載
    發(fā)表于 03-30 13:41 ?3次下載

    USB設(shè)備在Linux系統(tǒng)中的識別和加載過程

    不知道大家在學(xué)習(xí)Linux的時候有沒有過這樣的疑問,為什么我們通過同一個接口接入的不同USB設(shè)備,我們的電腦都可以識別到呢?為什么Linux電腦不會把鼠標(biāo)識別成鍵盤呢?帶著這些疑問我們一起來看一下USB的識別和
    的頭像 發(fā)表于 05-10 11:53 ?4714次閱讀

    USB復(fù)合設(shè)備介紹

    電子發(fā)燒友網(wǎng)站提供《USB復(fù)合設(shè)備介紹.pdf》資料免費(fèi)下載
    發(fā)表于 08-01 10:37 ?0次下載
    <b class='flag-5'>USB</b>復(fù)合<b class='flag-5'>設(shè)備</b><b class='flag-5'>介紹</b>

    用于MCU的USB?DFU引導(dǎo)加載程序

    電子發(fā)燒友網(wǎng)站提供《用于MCU的USB?DFU引導(dǎo)加載程序.pdf》資料免費(fèi)下載
    發(fā)表于 10-27 14:23 ?1次下載
    用于MCU的<b class='flag-5'>USB</b>?DFU引導(dǎo)<b class='flag-5'>加載</b>程序