線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5353
推到 Plurk!
推到 Facebook!

onDeviceChange 及 usb 的問題

答題得分者是:daldal
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-08-24 10:27:41 IP:59.120.xxx.xxx 訂閱

由於需要做即時偵測 usb 的插拔動作,所以最近用了onDeviceChange這個功能...
當然是可以順利的動作....
不過問題來了....

如果今天我要對 a usb device 做燒錄的動作 ( 逶過a 燒錄 bin檔到chip裡面)
單純這樣的動作也是可行的...

不過如果在燒錄的中間,我再另外的插入了一個 b usb device.....
結果,這個 b 就會觸發 onDeviceChange 導致 我的程式就死當在那邊了....

我想問的是,有沒有辦法避掉這種干擾的行為....
因為查了一堆usb的資料,不過好像都是在提怎麼「連結 usb port 然後讀寫」 或是 「偵測插拔」 的..

編輯記錄
brian_chen 重新編輯於 2007-08-28 10:26:19, 註解 無‧
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-08-27 13:46:34 IP:59.120.xxx.xxx 訂閱
這幾天有想了一下...
有想過透過guid的方式來避開....

不過好像還是不行...
透過guid的方式是能避開 DBT_DEVICEARRIVAL 及 DBT_DEVICEREMOVECOMPLETE...
不過還是會產生 DBT_DEVNODES_CHANGED 訊息

也就是說只要有裝置插入,都會先呼叫 OnDeviceChange 函式....
實在想不出有什麼辦法,可以在想要的時候呼叫,不想要的時候就不呼叫....囧
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-08-27 19:32:05 IP:61.219.xxx.xxx 訂閱
一個蠻笨的方法@@
宣告一個變數bool pBusy=false;
然後在OnDeviceChange的時候多一個判斷 if (pBusy == true) return;
當進入format, copy等狀態時,把pBusy=true; 結束再還原 false;
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-08-28 09:33:19 IP:59.120.xxx.xxx 訂閱

不過我想請問一下

BOOL bBusy = FALSE;
OnDeviceChange(...)
{
if (bBusy)
{
return;
}
}


那個所謂的 return 是 return 回原來的程序嗎
比如說:
原本的程序 1->2->3->4->5
有跳 ondevicechang 的程序 1->2----(bBusy=true)--->ondevicechang->return->3->4->5 ???

因為其實我的想法是,在燒錄時期想把 ondevicechang 這個 function disable
就是會繞過這個動作 繼續執行下去

或是說 有其它的方法,可以偵測usb插拔的動作....
而且只對單一 a 產品 ,其它的 b mp3 player, c 隨身硬碟, d 隨身碟,插下去都沒反應....

===================引 用 daldal 文 章===================
一個蠻笨的方法@@
宣告一個變數bool pBusy=false;
然後在OnDeviceChange的時候多一個判斷 if (pBusy == true) return;
當進入format, copy等狀態時,把pBusy=true; 結束再還原 false;
harrypp
中階會員


發表:7
回覆:124
積分:61
註冊:2006-08-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-08-28 15:04:17 IP:210.202.xxx.xxx 訂閱
Disable也是個辦法。
不嫌麻煩就另外寫Thread偵測Device,不要使用OnDeviceChange。
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-08-28 16:09:54 IP:61.219.xxx.xxx 訂閱

===================引 用 brian_chen 文 章===================
...略
那個所謂的 return 是 return 回原來的程序嗎
比如說:
原本的程序 1->2->3->4->5
有跳 ondevicechang 的程序 1->2----(bBusy=true)--->ondevicechang->return->3->4->5 ???

因為其實我的想法是,在燒錄時期想把 ondevicechang 這個 function disable
就是會繞過這個動作 繼續執行下去
...略

舉例來說,
把會影響的動作放到OnDeviceChange的Function中 (例如當偵測到插入的時候觸發某某動作)
若是在觸發某某動作前就return的話,就會跳出該Function,所以後面會影響的部分便不會執行了
但是就Function外的程序還是會繼續跑下去,不會影響你的主流程

主程序
{
function1();
function2();
function3();
function4();
}

void function2()
{
// 檢查是否燒錄中
if (pBusy==true) rerturn;
else {
// 若沒有在燒錄中的動作放在這
}
}
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-08-29 00:03:32 IP:220.133.xxx.xxx 訂閱

===================引 用 daldal 文 章===================
舉例來說,
把會影響的動作放到OnDeviceChange的Function中 (例如當偵測到插入的時候觸發某某動作)
若是在觸發某某動作前就return的話,就會跳出該Function,所以後面會影響的部分便不會執行了
但是就Function外的程序還是會繼續跑下去,不會影響你的主流程

主程序
{
function1();
function2();
function3();
function4();
}

void function2()
{
// 檢查是否燒錄中
if (pBusy==true) rerturn;
else {
// 若沒有在燒錄中的動作放在這
}
}
=============================================

可是一般來說....
ondevicechange並不算是主程序中的一員不是@@

主程序
{
function1();
function2();
function3()
{
...
有裝置插入...
....
};
function4();
}

void ondevicechange()
{
// 檢查是否燒錄中
if (pBusy==true) rerturn;
else {
// 若沒有在燒錄中的動作放在這
}
}

在function3執行中,發生其它usb裝置插入的事件
就會跳到ondevicechange...

不過如果 pbusy=true 就會 return
但是應該是不會從跳出的地方開始跑了吧(就算有跑,也可能燒進去的東西是錯的??)

所以現在是卡在這個地方...
不知道其它開發usb裝置IDE的人是怎麼避掉這個問題的
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-08-29 09:27:42 IP:122.124.xxx.xxx 未訂閱
check GUID, VID, PID, product string...
編輯記錄
taishyang 重新編輯於 2007-08-29 09:28:14, 註解 無‧
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-08-29 16:21:55 IP:59.120.xxx.xxx 訂閱

===================引 用 taishyang 文 章===================
check GUID, VID, PID, product string...
======================================================

這個方法我也有想過
本來是想說利用vid及pid就可以判別特定的usb device(是沒錯)

void __fastcall TFWMain::OnDeviceChange(TMessage & tMsg)
{
USBDetect->DetectUSB(); //抓vid 及 pid

//假如 svid = ea48 才去做 WParam 的判斷
if(USBDetect->sVid == "EA48")
{
if ((tMsg.WParam == DBT_DEVICEARRIVAL ||
tMsg.WParam == DBT_DEVICEREMOVECOMPLETE))
{
changeStatus(USBDetect->iDetectClass);
}
}
}

以上的程式碼在單純
1. 如果只插特定usb device
2. 如果插其它的usb device
這兩者是成立的...
但如果特定的usb device一開始就插著,之後不管插什麼都是會做changeStatus的動作...

還有如果只用guid來判別,也是會跟上面一樣的結果....
本來的想法是 如果用RegisterDeviceNotification定死裝置的guid
其它的裝置插入,就不會觸發OnDeviceChange (不過事情好像沒那麼簡單)
結果還是會觸發...只是沒了DBT_DEVICEARRIVAL 跟 DBT_DEVICEREMOVECOMPLETE 的訊息...
不過還是會產生 DBT_DEVNODES_CHANGED 的訊息

所以,以上兩種方式在有裝置插入時,還是會跳出原有的程序....去執行OnDeviceChange裡面的事...

另外,樓上有位大大提出用thread的方式來做usb detect的動作,不過沒有頭緒.....

自己有另外想過,不過一直試不成功...(也不知可不可行)
就是開兩個thread
thread1 專門做 usb 插拔的偵測 (他偵測他的)
thread2 就做main裡面該做的事 (我繼續燒我的檔案)

只是不知道該怎麼把 usb 插拔的偵測 套到 thread1裡面....
daldal
高階會員


發表:6
回覆:102
積分:226
註冊:2007-06-18

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-08-29 20:57:31 IP:61.219.xxx.xxx 訂閱

===================引 用 brian_chen 文 章===================

可是一般來說....
ondevicechange並不算是主程序中的一員不是@@

===================引 用 brian_chen 文 章===================


可能是小弟沒表達清楚
試試看把會影響燒錄的程式碼放到 OnDeviceChange裡面
並在前面加上判斷是否Busy中
如下所示

if (pBusy == true) return;
else
{
// 放會影響到燒錄的程式碼
....
....
}

我寫CAMERA連線/斷線偵測也是這樣子寫的
應該不會有問題
如果還是不行的話,看看方不方便直接上傳程式碼
或許問題出在其他地方。
brian_chen
一般會員


發表:14
回覆:20
積分:6
註冊:2007-06-26

發送簡訊給我
#11 引用回覆 回覆 發表時間:2007-08-30 11:44:09 IP:59.120.xxx.xxx 訂閱

===================引 用 daldal 文 章===================
可能是小弟沒表達清楚
試試看把會影響燒錄的程式碼放到 OnDeviceChange裡面
並在前面加上判斷是否Busy中
如下所示

if (pBusy == true) return;
else
{
// 放會影響到燒錄的程式碼
....
....
}

我寫CAMERA連線/斷線偵測也是這樣子寫的
應該不會有問題
如果還是不行的話,看看方不方便直接上傳程式碼
或許問題出在其他地方。

===================引 用 daldal 文 章===================

原來是這樣,我先試試看....有問題再上來問....
謝謝啊...
系統時間:2024-07-05 7:59:28
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!