2010年9月30日 星期四

USB Request Block & USB Protocol

5.1 Sync Field
Each USB packet starts with a SYNC field. This is basically used to synchronise the transmitter and the receiver so that the data can be transferred accurately.
In a USB slow / full speed system this SYNC field consists 3 KJ pairs followed by 2 K’s to make up 8 bits of data.
In a USB Hi-Speed system the synchronisation requires 15 KJ pairs followed by 2 K’s to make up 32 bits of data

Bus Hound 裏面有關 URB

USB Request Block 是定義在 Windows 或 Linux 中
跟實際的USB Protocol 沒有關係
URB 的定義在 usb.h 中
它是各種不同的定義的集合 ( union )
http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx

2010年9月27日 星期一

sal.h

在做 USB Printer 的專案(x86)時,會用到 GUID_DEVINTERFACE_USB_DEVICE
及 IOCTL_PAR_QUERY_DEVICE_ID
所以要
#include
#include

而這兩個檔案是在 Windows DDK (WDK)裏有,所以要 add additional include directory
在 wdk 中的 \inc\api

現在問題來了,原來的project 為 vs2005
轉換成vs2008後 會出現一堆沒有定義 _In_opt 等等的錯誤
(為什麼要轉成 vs2008 的原因 是因為在vs2005中 下斷點有問題
有些部份無法設 breakpoint 會出現 the breakpoint will not currently be hit. invalid file line xxx
改成vs2008 之後就好了)

那是因為 vs2008 的 sal.h 和 ddk sdk 中的 sal.h 定義不同
必需要用到原來 vs2008中的 sal.h ( Visual Studio 9.0\vc\include ) 才行
但是因為我們加了 additional include directory
所以 wdk 中的 sal.h 會被先用到....
而造成錯誤

解決方法就是修改 Visual Studio 9.0\vc\include\crtdefs.h
在crtdefs.h 中會
#include
把它改成
#include "sal.h"
就可解決。(目前完美的方式)

...簡單的東西搞出麻煩的過程

2010年9月20日 星期一

build gnash on Windows

http://wiki.gnashdev.org/Building_on_Windows



boost
boost 1.44

cd \tools\jam
build_dist.bat

然後 build 出3個 Library?
libboost_program_options-vc100-mt-gd-1_44.lib
libboost_filesystem-vc100-mt-gd-1_44.lib
libboost_system-vc100-mt-gd-1_44.lib

2010年9月14日 星期二

WINCE 6.0 image making

嘗試 WinCE 6.0 Image 的 build,
在build minimal configuration 時
出現don't know how to make xxx\....\ndis.lib 的錯誤
ndis.lib 是在 core os->CEBASE -> shell and interface -> user interface -> network user interfacer


porting 參考 
http://blog.csdn.net/xilidecai/archive/2009/09/18/4566731.aspx


LNK2001: unresolved external symbol __CxxFrameHandler3 in otg


要加選 C++ Runtime support for Exception Handling and RTTI




Config.bib 中還是設定 AUTOSIZE=ON 比較好,一來沒有空間不夠的問題,二來能釋放出更多的記憶體。

2010年9月9日 星期四

Thread, Thread Quantum 測試

為了解決一些常見的煩人問題
只好實地下去測試 WinCE Thread 的運作機制

結果非常有趣,跟想像理解中有所不同


1. WinCE default time slice ( quantum )是為 100ms,OEM可以自己設定。(在OEMInit中設定 dwDefaultThreadQuantum) 。CE 也提供了2個函式 CeGetThreadQuantum and CeSetThreadQuantum


extern DWORD dwDefaultThreadQuantum;
 
 
void OEMInit()
{
                dwDefaultThreadQuantum = 50;
}

2.  Sleep(0)  就是把目前thread 剩下的 quantum 時間 ( <=100ms) 讓給 同Priority 的 Thread。如果沒有同Priority 的Thread ,則馬上 return. 也就是說 Sleep(0) 有兩種可能(效果)  
 I. 睡100ms (或更少) 
 II.沒有效果(馬上return)

3. Sleep(1) (或Sleep(X))  就很有趣了,就實地測試,依環境不同,有不同的結果。
如果只有2個同 Priority 的Thread, Sleep(1) 後再度醒來已經是 100ms後了。
如果有3個 Thread,則 Sleep(1) 大概睡 3~9ms。
神奇吧?

2010年9月7日 星期二

null, nullptr

簡單來說
在 C# / Java, use null
在 C++, use NULL
在 C++ .NET ( compile with /clr ), use nullptr

2010年8月4日 星期三

USB Audio Class Driver 開發

在開發的過程中, USBDeviceAttach 被呼叫了四次(第三個參數usb interface 都不相同,因為總共有4個 interface,USBAudio算是 interface driver,所以第一個interface 載入成功的話會載入下個interface。詳情請看 LoadDeviceDrivers() in usbd.cpp。
雖然被載入4次,但不會重複載入DLL (也就是DLLMain PROCESS_ATTACH 只會CALL 一次,之後的應該是THREAD_ATTACH)。
如果你的USB Client Driver 不是 interface driver 的話,則USBDeviceAttach第三個參數為 NULL。
還有 LoadDeviceDrivers 的載入interface driver 部份有點問題,它總共會載入 bNumInterfaces 次, 這個bNumInterfaces 是 active configuration 的 descriptor (USB_CONFIGURATION_DESCRIPTOR) 但 interface++ 的部份有點不對,因為每個interface又有可能有alternate setting ,所以總共的interface (含alternate setting) 應該是 dwNumInterfaces 個 ( USB_CONFIGURATION ) 。這一點我發現在 WINCE 6 usbd.cpp中改了過來,有把alternate setting 的狀況考慮進去。



USB Audio Output procedure

1. Set Interface  ( Interface 1, Alternate Setting 1 )
2. GetEndpoint
3. OpenPipe
4. IssueIsochTransfer

而 USB Mic Recording 基本上跟 Audio Out 一樣,不過怎麼試
都得不到正確資料,而是抓到整個 Configuration Descriptor

想破腦袋後,並從Bus Hound,發現Set Interface 後有 SET_CUR
而這個SET_CUR 就是設定 Audio In Endpoint 的 frequency,果然再 issue 這個
SET_CUR 的 VendorTransfer 後就可以正常讀取 Audio Stream 了。(請參考 Audio Class spec
第五章 request ),當然 bits 數 ,frequency, channel 都要正確才行。


USB Audio Input procedure

1. Set Interface  ( Interface 2, Alternate Setting 2 )
2. GetEndpoint
3. Send Endpoint Frequency Request
4. OpenPipe
5. IssueIsochTransfer


Note: 在 IssueIsochTransfer 的 callback function 中呼叫 closepipe的話,
會再多出一次 callback

Note!! 在 IssueIsochTransfer 的 callback function 中呼叫 WriteFile,而這個檔案又位在
USB Disk上時,這個WriteFile 會block住。所以,要再Create專門WriteFile 的Thread
不能在 callback中 WriteFile

如果要做 Isoch Transfer 這篇文章很重要
http://support.microsoft.com/?scid=kb;en-us;317434&x=14&y=7

DRVM_MAPPER_PREFERRED_SET 
設定 default waveout device
http://msdn.microsoft.com/en-us/library/dd187525.aspx
http://msdn.microsoft.com/en-us/library/aa908376.aspx
http://relatedterms.com/thread/2314671/Multiple%20Audio%20Devices%20Win%20CE



MMRESULT Err = waveOutMessage((HWAVEOUT)WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_SET,
CurDeviceID,
0
);

    把指定的 audio driver id 設成 0 (也就是 default audio driver )



MMRESULT Err = waveOutMessage((HWAVEOUT)WAVE_MAPPER,
DRVM_MAPPER_PREFERRED_SET,
CurDeviceID,
(DWORD)-1
); 

 把指定的 audio driver id 設成-1 (變成最後一個,比如說總共有3個driver, 0 1 2 那就會變成 2 )




USB Audio Class Driver 除了 USB 的部份還有Audio Driver的部份
之後有2個 audio device,所以才會想到用 DRVM_MAPPER_PREFERRED_SET 來設定 default audio device。DRVM_MAPPER_PREFERRED_SET 在 WINCE 5 NavReady 2009 ( ARM Only )和在 WINCE 6 R3之後才有支援。不支援的話呼叫會傳回 8 (MMSYSERR_NOTSUPPORTED)




除了不支援設定哪個default 之外,要load 2 個 audio driver 也遇到了問題
http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-pb/10473/how-to-install-the-second-audio-driver
 search   "load audio driver wince"






但是看了WINCE 5 的help 之後,發現Audio Driver 有兩種,一種是 MDD+PDD 另一種是 UAM
(Unified Driver Model )。
可惜的是,MDD+PDD 只support only one device ( waveOutGetNumDevs always returns 1 )
新發現第三種 wavedev2 audio model ( Sample available in WINCE 6 ) (or WINCE 5 NMD Pack )
http://msdn.microsoft.com/en-us/library/ee485233.aspx
wavedev2 好像有support S/PDIF
http://www.ms-news.net/f3868/question-about-audio-driver-wince5-0-a-11725972.html

google wavedev2 waveapi.dll
http://news.rdeasy.cn/yingyong/20100208/7921.html


Writing a Network Audio Driver in WINCE
http://blogs.msdn.com/b/cenet/archive/2005/10/10/479282.aspx

Audio MDD PDD
在使用 MDD (wavemdd.lib) 的時候,PDD 部份要定義 gIntrAudio,並InterruptConnect 此 gIntrAudio。


Audio Stack 架構圖 ( described in wavedev.h )


//  @topic  Wave Audio API Manager Device Interface |
//          The COREDLL.DLL Dynamic Link Library gives user applications
//          access to the Waveform Audio functions.
//
//          The Waveform Audio API Manager exports the waveXXX functions via the
//          device manager's IOCTL calls. IOCTL_XXX constants are defined in
//          wavedev.h.
//
//  @ex     Software Layers |
//  
// *       ===============    ===============
// *       | Application |    | Application |  Module(s)
// *       ===============    ===============
// *    
// *         --------- MMSYSTEM.H ---------    Interface
// *    
// *       ==================================
// *       |          COREDLL.DLL           |  Module  (coredll.dll)
// *       ==================================
// *    
// *         ---------- WAVEDEV.H ---------    Interface
// *    
// *         ------ DeviceIoControl() -----    PSL API
// *    
// *       ==================================
// *       |     WAPI (Wave API Manager)    |  Module (waveapi.dll)
// *       ==================================
// *    
// *         ---------- WAVEDEV.H ---------    Interface
// *    
// *         ------ DeviceIoControl() -----    PSL API
// *    
// *       ==================================
// *       |            WAVEMDD             |  Module (wavedev.dll)
// *       ==================================
// *    
// *         --------- WAVEDDSI.H ---------    Interface
// *    
// *       ==================================
// *       |            WAVEPDD             |  Module (wavedev.dll)
// *       ==================================





DRVM_MAPPER_PREFERRED_SET and DRVM_MAPPER_PREFERRED_GET are not defined by Windows Embedded CE. To use these messages, you must first define them in your code, as follows:


#define DRVM_MAPPER 0x2000
#define DRVM_MAPPER_PREFERRED_GET (DRVM_MAPPER+21) 
#define DRVM_MAPPER_PREFERRED_SET (DRVM_MAPPER+22)