2009年7月22日 星期三

Push Mode簡介



說明:
"push mode" 是指device 上觸發了某些事件,這些事件有必要讓PC 端知道。
如在Scanner 上按下了掃描鍵。PC 端應立刻讀取scanner 上的掃描資訊,進行掃描。

基本上分為兩種:
1. polling: 每隔一段時間便向device 詢問相關資訊。
2.1 function 呼叫時機:
自行參考xp ddk下的demo

2. asynchronous: device 透過 interrupt 發送相關資訊上來。
2.1 function 呼叫時機:
//initialization
IStiUSD::Initialize()
IStiUSD::GetCapabilities()
IStiUSD::GetStatus()
IStiUSD::SetNotificationHandle()

//when device send a interrupt
IStiUSD::GetNotificationData()

//Set again
IStiUSD::SetNotificationHandle()

.
.
.

Function 簡介(asynchronous):

IStiUSD::Initialize()
a. 用Createfile()取得另一個Handle,有別於read/write 用的那一個。

IStiUSD::GetCapabilities()
a. 提供支援STI 的版本(xp: STI_VERSION, vista/7: STI_VERSION_3)
b. 告知是否支援wia, 支援何種 push mode(polling/ asynchronous)

IStiUSD::GetStatus()
a. 由mask 中的
STI_DEVSTATUS_ONLINE_STATE 決定是否告知device online,
STI_DEVSTATUS_EVENTS_STATE 決定是否告知有無event pending-----只有 polling mode此flag 才會被設立
b. 告知是否Device online

IStiUSD::SetNotificationHandle()
a. 用來DeviceIoControl(,IOCTL_WAIT_ON_DEVICE_EVENT,..)來幫助WIA Service 等待device 的interrupt.
b. 支援 asynchronous才會進來此function,支援 polling 則不會。

IStiUSD::GetNotificationData()
a. WIA Service 一旦等待到Device interrupt 便會呼叫此function
b. 在此從device 取得相關資訊,並由此資訊判斷屬於哪個Event ,再回傳此Event給 WIA Service

IWiaMiniDrv::drvGetCapabilities()
a. 告知支援的Event 及command

IWiaMiniDrv::drvNotifyPnpEvent
a. 當asynchronous 模式且pnp Event 為WIA_EVENT_POWER_RESUME ,得再次呼叫IStiUSD::SetNotificationHandle() 來設立WIA Service的等待模式。




INF File

"Capabilities" in INF DDInstall section:

bit 0(STI_GENCAP_NOTIFICATIONS): 支援push mode 預設模式 為 asynchronous
bit 1(STI_GENCAP_POLLING_NEEDED): 改變模式為 polling
bit 2(STI_GENCAP_GENERATE_ARRIVALEVENT):
bit 3(STI_GENCAP_AUTO_PORTSELECT):
bit 4(STI_GENCAP_WIA): 支援WIA
bit 5(STI_GENCAP_SUBSET):


ex:
.
.
.
[Manufacturer]
%Mfg%=Models

[Models]
%WIASample.DeviceDesc% = WIASample.Scanner, MICROSOFT_WIASCANR_TESTDEVICE_PNP_ID

[WIASample.Scanner]
Capabilities=0x31(支援wia(ddk 中demo code 中把STI_GENCAP_SUBSET 設起來), 且push mode 的模式為 asynchronous)
.
.
.


2009年7月18日 星期六

WIA 流程簡介




流程說明:
Tip:refer to win DDK(xp) "Calling Order for Minidriver Functions"


1. 初始化:

STI---

IStiUSD::Initialize()
a. 用Createfile()取得Handle
b. 打開 驅動程式鍵(driver key)下的"DeviceData" key,可在此存放一些自訂的資訊。

IStiUSD::GetCapabilities()
a. 提供支援STI 的版本(xp: STI_VERSION, vista/7: STI_VERSION_3)
b. 告知是否支援wia, 支援何種 push mode(polling/ asynchronous)

IStiUSD::GetStatus()
a. 告知是否Device online
b. 有沒有Event pending 中


WIA---

IWiaMiniDrv::drvInitializeWia()
a. 保存 指向IStiDevice 的 pointer(間接呼叫IStiUSD)
b. 建立 Item Tree 中的 所有 Item ( xp: 0000\Root 和 0000\Root\Flatbed or 0000\Root\Feeder 這2個Item, vista/7: 0000\Root 和 0000\Root\Flatbed, 0000\Root\Flatbed, ..等至少2個以上的Item)


IWiaMiniDrv::drvGetCapabilities()
a. 告知支援的Event 及command

IWiaMiniDrv::drvInitItemProperties()
a. 建立Item Tree 中每一個Item 中所需的property
b. 如果Item Tree 中有2 個Item , 此function 會被呼叫 2次(呼叫次數為Item Tree 中 Item的個數) IWiaMiniDrv::drvValidateItemProperties()




2. (property validation) UI 改變掃描參數或硬體資訊

WIA---

IWiaMiniDrv::drvValidateItemProperties()

a. WIA AP 改變了 Item Tree 中 Item 裡的property所含的數值便會觸發此fucntion (如圖中 相片類型由 彩色相片->灰階圖片。)



3. 建立傳輸

STI---

IStiUSD::LockDevice()
IStiUSD::RawReadCommand()
IStiUSD::RawWriteCommand()
IStiUSD::RawReadData()
IStiUSD::RawWriteData()
IStiUSD::UnLockDevice()


WIA---

IWiaMiniDrv::drvLockWiaDevice()
IWiaMiniDrv::drvWriteItemProperties()
IWiaMiniDrv::drvAcquireItemData()
IWiaMiniDrv::drvUnLockWiaDevice()


3.1. Lock/UnLock:
依接口,效能考量而有不同。(因為STI 支援多個instance 同時呼叫一個Device所以在每次read/write時要做lock的動作)

STI---
read command-> parse command -> read/write data
write command-> read/write data

其實只要有read/ write function 就行了。
反正command 也只是一塊buffer 而已 所以只要
read: read: IStiUSD::LockDevice() ->IStiUSD::RawReadData()->IStiUSD::UnLockDevice()
write: write: IStiUSD::LockDevice() ->IStiUSD::RawWriteData()->IStiUSD::UnLockDevice()

//以下的function可以不用implement
IStiUSD::RawReadCommand()--no use
IStiUSD::RawWriteCommand()--no use

WIA---
Lock/UnLock: 和STI 的考量點一樣。


3.2 Transfer:

xp/nt:
3.2.1 WIA 對device 的read/write 由呼叫 以上的STI read/write function 完成。
3.2.2 IWiaMiniDrv::drvWriteItemProperties(): 寫入欲掃描的影像資訊到device 上
IWiaMiniDrv::drvAcquireItemData() : 透過callback function 回傳影像資料到WIA Service

3.2.3 [IWiaMiniDrv::drvWriteItemProperties() + IWiaMiniDrv::drvAcquireItemData()] :
為回傳從Device 取得的一頁影像到WIA Service. 如有4 頁影像,便連續進入4次(flatbed, simplex 一張紙只能掃出1頁,duplex 能掃出2頁)


Vista/7:
3.2.1 WIA 對device 的read/write 由呼叫 以上的STI read/write function 完成。
3.2.2 IWiaMiniDrv::drvWriteItemProperties(): 沒有作用
IWiaMiniDrv::drvAcquireItemData() : 透過IStream 回傳影像資料到WIA Service

3.2.3 [IWiaMiniDrv::drvAcquireItemData()] :
在此function 內完成一個scan job, 一次掃描只進來一次,一次完成所有頁數的掃描。

2009年7月15日 星期三

WIA 架構簡介

















Component 介紹:

1. WIA AP: 使用 wia 的 application
2. WIA Service: windows 內的一個Service
3. WIA mini driver: 要implement 的對象(提供 IWiaMiniDrv, IStiUSD 兩個inteface)
4. sti.dll: STI (提供 IStiDevice 這個 interface)
5. WIA Driver service library: 提供一些輔助用的function (ex: wiasXXX,...), 用來存取 Item Tree
6. Driver(USB, SCSI,...): 依scanner 提供的接口而變,大多是USB.
7. Item Tree:
7.1. 將 Device 的硬體資訊存入 個別Item(ex: 0000\Root, 0000\Root\Flatbed,..) 的property 中.
7.2. 三份Item Tree 是一樣的。(一個 WIA AP 會有自己的一份)
7.3. 由WIA Service 來主導 WIA AP 和 WIA mini driver 的協調
8. CONTEXT: WIA Service 呼叫 WIA mini driver 的 IWiaMiniDrv 介面function 時所帶之參數


2009年7月13日 星期一

Big/Little Endian

-------------------------------------
定義:
-------------------------------------
MSB(Most Significant Bit/Byte)
LSB(Least Significant Bit/Byte)

以32 bits cpu 來看:

暫存器每個BYTE 的index 如下。








-------------------------------------
解釋:
-------------------------------------
Big/Little endian 的差別在於。是由MSB 開始copy 每一 BYTE 的值到記憶體中,或是由LSB開始。



-------------------------------------
例子:
-------------------------------------

//Big endian

















//Little endian