討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 網路投保旅行平安險 討論區最近新進100則主題
[ 回上頁 ] [ 討論區發言規則 ]
Usb 讀取資料的問題
更改我的閱讀文章字型大小
作者 : clain(Clain)
[ 貼文 5 | 人氣 2593 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/29 下午 02:13:58
大家好:

我在開發usb composite driver時遇到了一些問題,裝置的interface支援modem跟serial port,
當我利用HyperTerminal下達AT command,如果回傳的資料長度大於256byte,我所讀到的資訊便會出錯,

舉例來說,我在usb裝置裡存放了兩封簡訊,這兩封簡訊各自的大小都小於256bytes,index分別為0及1
然後我分別使用AT+cmgr=0及AT+cmgr=1去將這兩封簡訊讀出來,結果是正常的。

接著我使用AT+cmgl=4 這個指令去將裝置儲存的所有簡訊資料讀出來,
前256bytes一樣可以正常顯示,但256bytes之後的資料便會從第一封簡訊的資料內容開始重複,
然後重複的部份也沒有讀完,就直接斷在中間,造成我的AT command無法正常完成。

我想請問一下,這樣的問題是如何產生的呢?


還有個問題是,
我在程式碼中是使用UsbBuildInterruptOrBulkTransferRequest()這個routine去跟usb endpoint要資料
設定好urb以及Complete routine之後,再利用IoCallDriver把irp往底層送,
底下是我填入pass 給UsbBuildInterruptOrBulkTransferRequest()的參數資料。

UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER),
pipeHandle,
pDevExt->ReadData,
NULL,
4096,
USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK,
NULL);

這裡是一次讀取64bytes的資料,然後存入ReadData這個buffer中,
我有疑問的地方在於,如果資料長度大於4096bytes,那我該怎麼接著讀後續的資料呢?
我試過再call一次UsbBuildInterruptOrBulkTransferRequest(),但是所得到的資料卻是從頭開始,
若我想接續讀後面的資料,那標準的作法應該是怎麼樣的呢?


以上兩個問題,謝謝大家的解答。
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/29 下午 08:56:53
我自己並不明瞭modem的運作原理,猜測大抵就是從UART接收AT command然後從
bulk endpoint回傳資料給你的PC讀取吧? 提供一些bulk transfer方面的經驗供你參考

>回傳的資料長度大於256byte,我所讀到的資訊便會出錯
可能跟你的裝置端endpoint descriptor所設定的max. packet size有關
如果他設定最大packet size只有256那你一次bulk-transfer就不能超過256
如果descriptor設定沒錯的話,可能是firmware的bug, 建議可以用軟體工具:
Bus Hound去攔USB封包進行解析就知道發生什事

>如果資料長度大於4096bytes,那我該怎麼接著讀後續的資料呢?
Driver的API我不是很熟悉,但是每呼叫一次UsbBuildInterruptOrBulkTransferRequest()
就執行一次bulk transfer大概也是確定的,意思是說你呼叫API時所帶入的buffer長度
一樣受限於max. packet size (full speed最大64,high speed最大512)

因此接收時必須將大資料切割成多筆小資料(max. packet size)分次接收
一直到所收到的資料長度為0或小於max. packet size就知道所有資料都已經傳完.

參數堶惆滬 USBD_SHORT_TRANSFER_OK 就是這個用意
=> 允許傳送的資料小於max. packet size



作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/29 下午 09:03:29
覺得該修正一下:
>呼叫API時所帶入的buffer長度一樣受限於max. packet size

並不是不能用大於max. packet size的buffer去接收
而是每次bulk-in的實際讀回資料量不會超過max. packet size
作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/29 下午 10:45:08

>覺得該修正一下:
>>;呼叫API時所帶入的buffer長度一樣受限於max. packet size
>
>並不是不能用大於max. packet size的buffer去接收
>而是每次bulk-in的實際讀回資料量不會超過max. packet size
這個好像有一點問題喔 Max Packet Size 是一個Bulk-In Transfer 的一個單位 不代表Driver 裡的 一個Irp Bulk Transfer 的最大值 在Drver 裡的一個Irp Bulk Transfer 的最大值是去設定Max Transfer Size.
基本上我個人認為這是Firmware 有問題造成的 應該是Firmware 在搬Data 時Index 是用一個Byte or Offset 是用Byte 造成 超過256Byte 時Loop 造成
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/30 下午 05:54:48
Irp Bulk Transfer的部份實際如何去處理大過endpoint的Max Packet Size所設定的資料量
這點自己並不是很了解.. 因為USB硬體上的spec.對傳輸的資料有明確的規定而且DDK對UsbBuildInterruptOrBulkTransferRequest()的說明:

USBD_SHORT_TRANSFER_OK
Can be used if USBD_TRANSFER_DIRECTION_IN is set. If set, directs the HCD not to return an error if a packet is received from the device that is shorter than the maximum packet size for the endpoint. Otherwise, a short request returns an error condition.

照字面上的意思似乎暗示接收到的資料會小於或等於max packet size
因此小弟才會如次認定.
Driver方面自己並不是很有把握,還請清楚這方面的前輩幫忙指導一下^^
作者 : clain(Clain)
[ 貼文 5 | 人氣 2593 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/31 上午 02:01:52
剛剛打了一堆字全部被系統吃掉。

這邊說一下我這幾天發現的問題。

關於bulk in/out的問題,我一開始也以為是MaxPacketSize的問題,
但透過一些輔助軟體去得到硬體bulk in/out的size是64 bytes,所以才以為是別的地方,
但從這個網頁:http://msdn.microsoft.com/en-us/library/ms793357.aspx

這是msdn上關於USBD_PIPE_INFORMATION的詳細結構
裡面有定義兩個variable
USHORT MaximumPacketSize ;
ULONG MaximumTransferSize ;

底下列出網頁上詳細的說明。
MaximumPacketSize
Specifies the maximum packet size, in bytes, that this pipe handles. This value must be less than or equal to the value of wMaxPacketSize in the endpoint descriptor. The USB stack ignores this value if the USBD_PF_CHANGE_MAX_PACKET flag is not set in the PipeFlags member.

MaximumTransferSize
Specifies the maximum size, in bytes, for a transfer request on this pipe. In Windows Server 2003, Windows XP and later operating systems, this member is not used and does not contain valid data.
The following table lists the maximum transfer sizes for each type of pipe for the major versions of Windows:

所以看起來UsbBuildInterruptOrBulkTransferRequest()所指定的size是transfer
size沒錯,而網頁裡還有個表列出不同作業系統MaximumTransferSize的定義,
XP是256 kilobytes,而vista則沒有限制,
而我開發的OS正好是XP,所以看起來好像跟這有關?

但我還有一點困惑,網頁上寫的是256 kilobytes,
但我實際上應該是只有讀到256 bytes,所以感覺好像還是不太對的樣子。

另外我發現一個挺有意思的問題,
我將UsbBuildInterruptOrBulkTransferRequest()的transfer size指定為64,
讓它一次最多只讀64 bytes的資料,接著用IoSetCompletionRoutine設定一個
completion routine,等下層處理完irp之後再呼叫completion routine。

這時候如果我開啟windbg來抓出DbgPrint所印出的訊息,
在讀取endpoint資料的流程這部份是這樣的:
我用UsbBuildInterruptOrBulkTransferRequest()設定好urb,
然後幫irp設定好completion routine,接著利用IoCallDriver()把irp往下層丟,
下層處理完之後叫起completion routine,我在completion routine讀取完第一筆
64 bytes的資料,接著重複上述設定urb與completion routine,並把同樣的irp往下層丟,
接著completion routine第二次被叫起,然後讀完第二筆資料,再重複上述動作,
奇怪的是這次completion routine就不再被呼叫了,所以我的讀取到這邊就停止。
(或者不該說停止,這是因為completion routine一直沒有被呼叫的原因。)

有趣的是,我拿同樣的driver再試一次,
但這次我沒有開windbg,就讓它直接run在系統裡。
神奇的事情發生了,這樣子做結果可以正常讀完所有的資料,
也不會有之前斷在256 bytes的問題。
作者 : clain(Clain)
[ 貼文 5 | 人氣 2593 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/5/31 上午 02:03:11
字太多所以分兩段寫,以下是內文。

我還蠻好奇DbgPrint印出的訊息到底會不會影響IO呢?
照這兩個case看來,似乎是DbgPrint印出太多訊息,導致IO處理時發生不知名的狀況,
比方說可能還有資料要讀,但irp被結束,
或者像上面說得底層遲遲不處理完我丟給它的irp,而上層一直在等待。
這方面我不是很清楚,可能要請有經驗的人幫忙指導一下這個問題是怎樣的狀況?

另外,在上面這整個過程裡所用到的irp與urb都是同一個,
我在前面就已經利用IoAllocateIrp去配置一個irp,而urb也是一樣。

我還好奇一個問題,complete routine到底是怎麼被呼叫的?
我的理解是上層替irp設定好complete routine之後,利用IoCallDriver()把irp往下層丟,
等下層處理完之後就會叫起complete routine,
如果是這樣的話,那為什麼windbg的開啟與否會造成兩個完全不同的結果?
IoCallDriver()之後,底層到底做了哪些事情呢?
這點不知道可不可以請有想法的人給一些意見呢?

我另外說明一下,我這個driver在read/write的部份基本上是用DDK裡serial port的sample修改,
不過再跟usb溝通的部份,我則另外寫了其他的routine。
我看了一下ddk裡bulkusb跟isousb這兩份sample,
在跟usb要資料時,我寫的比較偏向bulkusb的方式,
但這兩個sample對於IO都是採取direct io的存取方式,
他們在取得資料長度是使用mdl去得到endpoint有多少資料等待被讀取。
但因為我的driver裡所使用的是buffer io(遷就serial port sample的寫法),
所以沒辦法像他們那樣明確的知道到底有多少資料等待被讀取,
我只能從urb的transfer size去知道說我這次讀取總共讀了多少資料回來,

我試著在complete routine裡去印出
IoGetCurrentIrpStackLocation(irp)->Parameter.Read.Length 以及
IoGetCurrentIrpStackLocation(irp)->Parameter.DeviceIoControl.OutputBufferLength,
所得到的值都是0,看了一下irp的stack location結構,似乎其他也沒地方可以塞這個值,

我想問的是,buffer io有辦法知道endpoint總共有多少資料等著被讀取嗎?

以上是最近的一些心得跟疑問,跟大家分享。
作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/1 下午 01:25:19
1. 你的問題是因為你有打開WinDbg 造成的如果你改用SoftICE就不會了 但是這還是無法解決你真正的問題個人認為你的問題是在Firmware上 可以用CATC 來確認
2. Buffer I/O 當然無法知道 endpoint 總共有多少資料等著被讀 因為Buffer I/O 不只被用來讀取USB Data 這個可以利用Serial Port 的Driver 來解決 給你可以參考一下
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/2 下午 04:08:25
>另外我發現一個挺有意思的問題,
>我將UsbBuildInterruptOrBulkTransferRequest()的transfer size指定為64,

DDK 的 bulkusb範例用的就是之前提到的將大量資料切成小塊的方式來傳輸
(每次傳送BULKUSB_MAX_TRANSFER_SIZE)
你的實驗結果跟我之前使用的經驗相同, UsbBuildInterruptOrBulkTransferRequest()
所代入的 TransferBufferLength 必須跟endpoint descriptor的 Max. Packet Size相同才能正常工作.

這個在官網有找到相關的說明: http://support.microsoft.com/kb/222600/en-us/

SUMMARY
The Universal Serial Bus 1.00 specification defines bulk transfers to be 4, 8, 16, 32 or 64 bytes in length. However, the TransferBufferLength field of _URB_BULK_OR_INTERRUPT_TRANSFER can specify a much larger byte size.
MORE INFORMATION
A developer using the USBD UsbBuildInterruptOrBulkTransferRequest service can specify a TransferBufferLength larger than 64 bytes. When a larger than 64 byte buffer is used, the USB port driver (UHCD.SYS or OPENHCI.SYS) breaks up the transfer into the correct size based on the USB controller type and the state of the controller.

The USB specification limits the bulk transfer size to a maximum of 64 bytes at the port driver level.

覺得這種說法很合理,因為不管軟體如何設定,最終硬體那邊還是必須遵照USB的規範
亦即每次傳送的資料量限制在Max. Packet Size之內.

致於那個 MaximumTransferSize 依照官網的說法:
http://msdn.microsoft.com/en-us/library/ms790486.aspx

In Windows XP, Windows Server 2003 and later operating system, the MaximumTransferSize member of the USBD_PIPE_INFORMATION structure is obsolete.

XP以後的OS不會再使用到











作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/3 上午 12:50:08
很有意思 我們之前發展 USB Storage Device Driver 時TransferBufferLength 用的是4K耶 ... 和您的實驗如果不同喔
bulkUSB 是將大量資料切成小塊的方式來傳輸沒錯但是在我的印象中不是切成64byte 為一個單位 明天再來查查DDK Sample ...
BULKUSB_MAX_TRANSFER_SIZE 在不同OS下定義不同 MaxTransferSize 但基本上可以在SelectInterface 的時候設定 ...
你可以參考
http://groups.google.com.tw/group/microsoft.public.development.device.drivers/browse_thread/thread/f35b341529b415d4/3cbee0ba812956b4?lnk=raot
這個討論串

>>;另外我發現一個挺有意思的問題,
>>;我將UsbBuildInterruptOrBulkTransferRequest()的transfer size指定為64,
>
>DDK 的 bulkusb範例用的就是之前提到的將大量資料切成小塊的方式來傳輸
>(每次傳送BULKUSB_MAX_TRANSFER_SIZE)
>你的實驗結果跟我之前使用的經驗相同, UsbBuildInterruptOrBulkTransferRequest()
>所代入的 TransferBufferLength 必須跟endpoint descriptor的 Max. Packet Size相同才能正常工作.
>
>這個在官網有找到相關的說明: http://support.microsoft.com/kb/222600/en-us/
>
>SUMMARY
>The Universal Serial Bus 1.00 specification defines bulk transfers to be 4, 8, 16, 32 or 64 bytes in length. However, the TransferBufferLength field of _URB_BULK_OR_INTERRUPT_TRANSFER can specify a much larger byte size.
>MORE INFORMATION
>A developer using the USBD UsbBuildInterruptOrBulkTransferRequest service can specify a TransferBufferLength larger than 64 bytes. When a larger than 64 byte buffer is used, the USB port driver (UHCD.SYS or OPENHCI.SYS) breaks up the transfer into the correct size based on the USB controller type and the state of the controller.
>
>The USB specification limits the bulk transfer size to a maximum of 64 bytes at the port driver level.
>
>覺得這種說法很合理,因為不管軟體如何設定,最終硬體那邊還是必須遵照USB的規範
>亦即每次傳送的資料量限制在Max. Packet Size之內.
>
>致於那個 MaximumTransferSize 依照官網的說法:
>http://msdn.microsoft.com/en-us/library/ms790486.aspx
>
>In Windows XP, Windows Server 2003 and later operating system, the MaximumTransferSize member of the USBD_PIPE_INFORMATION structure is obsolete.
>
>XP以後的OS不會再使用到
>
>
>
>
>
>
>
>
>
>
>
>
作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/3 上午 10:02:35
嗯 查了一下在BulkUsb 的sample code 裡 BULKUSB_MAX_TRANSFER_SIZE 是 256

>很有意思 我們之前發展 USB Storage Device Driver 時TransferBufferLength 用的是4K耶 ... 和您的實驗如果不同喔
>bulkUSB 是將大量資料切成小塊的方式來傳輸沒錯但是在我的印象中不是切成64byte 為一個單位 明天再來查查DDK Sample ...
>BULKUSB_MAX_TRANSFER_SIZE 在不同OS下定義不同 MaxTransferSize 但基本上可以在SelectInterface 的時候設定 ...
>你可以參考
>http://groups.google.com.tw/group/microsoft.public.development.device.drivers/browse_thread/thread/f35b341529b415d4/3cbee0ba812956b4?lnk=raot
>這個討論串
>
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人clain註記此篇回應為很有道理 2008/6/4 下午 06:49:40
>很有意思 我們之前發展 USB Storage Device Driver 時TransferBufferLength 用的是4K耶

看了大大的回覆還有網上的討論,覺得應該是IoCallDriver()幫忙做了切塊處理,
回顧之前看到的討論:
>A developer using the USBD UsbBuildInterruptOrBulkTransferRequest service can specify a TransferBufferLength larger than 64 bytes. When a larger than 64 byte buffer is used, the USB port driver (UHCD.SYS or OPENHCI.SYS) breaks up the transfer into the correct size based on the USB controller type and the state of the controller.

那個"break up the transfer into the correct size.."指的就是自動切塊吧?
之前也許是因為firmware沒有配合好..加上剛好bulkusb的寫法又切了一次
誤以為每call IoCallDriver()一次就只產生一次硬體Bulk-In

為了確認IoCallDriver()是否有自動切塊..特別去弄了個環境來測
藉由firmware那邊攔截訊息發現IoCallDriver()確實會自動切塊,
將資料拆解成多筆大小為Max. Packet Size的小資料然後分次傳送

利用bulkusb將 BULKUSB_MAX_TRANSFER_SIZE 設到最大 16384 也都可以正常工作
(受限於Device的SRAM無法再大)

經過上述討論與實驗大抵上可以得到結論:
XP之後的作業系統 TransferBufferLength 並沒有設限
基於效率的考量可以加大其值, 但設定的buffer大小必須要在USB Device可以處理的範圍內

感覺上一次傳太大的buffer似乎也不太好控制
因為一般IoSetCompletionRoutine()都會用個event然後以KeWaitForSingleObject()
去控制傳輸的time out, 傳一大筆資料的time out勢必要夠大
一但firmware那邊掛了..PC這邊就會被咬死

所以像bulkusb那樣切小塊去傳然後分段去控制time out應該會比較有彈性吧.



















作者 : clain(Clain)
[ 貼文 5 | 人氣 2593 | 評價 0 | 評價/貼文 0 | 送出評價 1 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/5 下午 02:47:59
>看了大大的回覆還有網上的討論,覺得應該是IoCallDriver()幫忙做了切塊處理,
>回顧之前看到的討論:
>>;A developer using the USBD UsbBuildInterruptOrBulkTransferRequest service can specify a TransferBufferLength larger than 64 bytes. When a larger than 64 byte buffer is used, the USB port driver (UHCD.SYS or OPENHCI.SYS) breaks up the transfer into the correct size based on the USB controller type and the state of the controller.
>
>那個break up the transfer into the correct size..指的就是自動切塊吧?
>之前也許是因為firmware沒有配合好..加上剛好bulkusb的寫法又切了一次
>誤以為每call IoCallDriver()一次就只產生一次硬體Bulk-In
>
>為了確認IoCallDriver()是否有自動切塊..特別去弄了個環境來測
>藉由firmware那邊攔截訊息發現IoCallDriver()確實會自動切塊,
>將資料拆解成多筆大小為Max. Packet Size的小資料然後分次傳送
>
>利用bulkusb將 BULKUSB_MAX_TRANSFER_SIZE 設到最大 16384 也都可以正常工作
>(受限於Device的SRAM無法再大)
>
>經過上述討論與實驗大抵上可以得到結論:
>XP之後的作業系統 TransferBufferLength 並沒有設限
>基於效率的考量可以加大其值, 但設定的buffer大小必須要在USB Device可以處理的範圍內
>
>感覺上一次傳太大的buffer似乎也不太好控制
>因為一般IoSetCompletionRoutine()都會用個event然後以KeWaitForSingleObject()
>去控制傳輸的time out, 傳一大筆資料的time out勢必要夠大
>一但firmware那邊掛了..PC這邊就會被咬死
>
>所以像bulkusb那樣切小塊去傳然後分段去控制time out應該會比較有彈性吧.

您的結論跟我目前得到的結果相同,所以我目前是設定一次讀取64 bytes。

另外剛好您有提到,我想問一個有關KeWaitForSingleObject的問題,

這是msdn上的定義:

NTSTATUS
KeWaitForSingleObject(
    IN PVOID Object,
    IN KWAIT_REASON WaitReason,
    IN KPROCESSOR_MODE WaitMode,
    IN BOOLEAN Alertable,
    IN PLARGE_INTEGER Timeout OPTIONAL
    );

其中WaitReason這個欄位,msdn上只提到driver應該將其設定成Executive,
但是在一些sample code中也可以看到有將其設定成Suspended的例子,
我想請問一下,這兩者的差異在哪裡?
作者 : quickwolf(疾風之狼) 貼文超過200則
[ 貼文 258 | 人氣 1837 | 評價 1420 | 評價/貼文 5.5 | 送出評價 11 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/5 下午 07:13:58
除了Suspended 外 wdm.h還定義了:
typedef enum _KWAIT_REASON {
    Executive,
    FreePage,
    PageIn,
    PoolAllocation,
    DelayExecution,
    Suspended,
    UserRequest,
    // 略...
} KWAIT_REASON;

但DDK的文件卻只提及UserRequest 跟 Executive
覺得沒有說明的東西要去臆測他的用意實在蠻困難(小弟目前的火侯尚且不足)
不像Linux沒有文件還可以去trace source code.

找了網上的說法:
http://www.themssforum.com/Drivers/meaning-enum/

據說好像沒有什實質用途.

 

作者 : tdtsai(新兵衛) 驅動程式優秀好手貼文超過200則
[ 貼文 362 | 人氣 779 | 評價 1290 | 評價/貼文 3.56 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/6/6 上午 10:13:41
IoCallDriver() 是一個General 的Function call 又不是都在傳 USB 的IRP ... 所以絕對不是IoCallDriver()幫忙做切塊處理 是UHCD.SYS(UHCI Host Driver) or OPENHCI.sys(OHCI Host Driver) 處理的哩 ccc...

>>;很有意思 我們之前發展 USB Storage Device Driver 時TransferBufferLength 用的是4K耶
>
>看了大大的回覆還有網上的討論,覺得應該是IoCallDriver()幫忙做了切塊處理,
>回顧之前看到的討論:
>>;A developer using the USBD UsbBuildInterruptOrBulkTransferRequest service can specify a TransferBufferLength larger than 64 bytes. When a larger than 64 byte buffer is used, the USB port driver (UHCD.SYS or OPENHCI.SYS) breaks up the transfer into the correct size based on the USB controller type and the state of the controller.
>
>那個break up the transfer into the correct size..指的就是自動切塊吧?
>之前也許是因為firmware沒有配合好..加上剛好bulkusb的寫法又切了一次
>誤以為每call IoCallDriver()一次就只產生一次硬體Bulk-In
>
>為了確認IoCallDriver()是否有自動切塊..特別去弄了個環境來測
>藉由firmware那邊攔截訊息發現IoCallDriver()確實會自動切塊,
>將資料拆解成多筆大小為Max. Packet Size的小資料然後分次傳送
>
>利用bulkusb將 BULKUSB_MAX_TRANSFER_SIZE 設到最大 16384 也都可以正常工作
>(受限於Device的SRAM無法再大)
>
>經過上述討論與實驗大抵上可以得到結論:
>XP之後的作業系統 TransferBufferLength 並沒有設限
>基於效率的考量可以加大其值, 但設定的buffer大小必須要在USB Device可以處理的範圍內
>
>感覺上一次傳太大的buffer似乎也不太好控制
>因為一般IoSetCompletionRoutine()都會用個event然後以KeWaitForSingleObject()
>去控制傳輸的time out, 傳一大筆資料的time out勢必要夠大
>一但firmware那邊掛了..PC這邊就會被咬死
>
>所以像bulkusb那樣切小塊去傳然後分段去控制time out應該會比較有彈性吧.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
作者 : snake(Snake)
[ 貼文 18 | 人氣 741 | 評價 30 | 評價/貼文 1.67 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/8/8 下午 04:47:04
雖然我不熟USB driver 但遇到這種問題, 我可能會先去看 從HOST 丟出去給USB Device的 Data 到底長得怎麼樣, 一次 256byte 或是全部都傳出去?

這個用bushund 軟體就可以看得到資料.
作者 : snake(Snake)
[ 貼文 18 | 人氣 741 | 評價 30 | 評價/貼文 1.67 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2008/8/8 下午 04:47:12
雖然我不熟USB driver 但遇到這種問題, 我可能會先去看 從HOST 丟出去給USB Device的 Data 到底長得怎麼樣, 一次 256byte 或是全部都傳出去?

這個用bushund 軟體就可以看得到資料.
 板主 : 徵求中
 > 驅動程式 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 驅動程式 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
驅動程式
1 新兵衛 1240 
2 eBoy 980 
3 牧童哥 780 
4 北極熊 580 
5 天行者 580 
6 燒酒仙 440 
7 weber 380 
8 KEN 350 
9 jonay 180 
10 掌握文武半邊天 180 
驅動程式
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.09375