下面是SP1 更新的內容
http://support.microsoft.com/kb/983509
2011年3月8日 星期二
2011年3月4日 星期五
USB Deep Trace Down
在做有關 burning 的問題的時候,發現速度並不夠快。
於是深入追蹤 在usbdrv.cpp 中發現在 GetInterface() 的上面有一段詳細說明
* The USB (OHCI) hardware assumes a host page size of 4K bytes. Under Windows CE, many
* supported processors do not necessarily follow this assumption (1K page size is common).
* The issue here is that the underlying hardware can use scatter/gather DMA, but
* can handle at most 1 page transition per transfer. However, client buffers on systems
* with smaller page sizes may be scattered across several physically disjoint pages.
*
* In order to make this restriction transparent to client drivers, OHCD.DLL allocates
* a buffer from the system which is known to be contiguous within 4K sections.
* Then, DMA is done to the private buffers, and copied to the client buffer
* once the transfer is complete. For some client drivers, this extra copy may
* impose an unacceptable performance hit, however. So, the Windows CE transfer functions
* allow the client to pass in an optional physical memory address which is used directly
* for the DMA to/from the HC hardware. Because the HC accesses this buffer directly,
* the following two restrictions must be rigidly adhered to:
*
* 1) Physical buffer must be contiguous within 4K segments. How the client allocates
* this memory is beyond the scope of this document (e.g. may be through a platform
* specific call). The LockPages() call can be used to get physical page information.
*
* 2) Client must not access or free the buffer before the transfer has completed.
意思就是說 USB Transfer 的時候,OHCD (or EHCD) 會 allocate 一個private的 4K buffer.
給 DMA 用,然後DMA完成時,再用memcpy 到 client buffer。
但是這會帶來 performance 的衝擊。
也就是 LPISSUE_BULK_TRANSFER (7個參數) 的最後一個參數 Physical Address 假如不為
NULL, Host Controller 會直接 DMA到這個 Physical Address.
以bot transfer 為例
BOT_DataTransfer (usbmsc.c) ....BulkTransfer::SendAnotherTransfer --> lpIssueBulkTransfer
http://support.microsoft.com/kb/937755/en-us
上面文章有用
三種加速的方法,Disable Cache, PacketsPerTransfer 0x80, IntThresCtrl = 1
在[HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\Mass_Storage_Class]
"DisableBuffering"=0 時會用 DMA =1 時 不用DMA(也就是不指定Physical address)
但是 = 0 時用DMA 也是另外 AllocPhysMem (in BulkTransfer::BulkTransfer() ) 然後再 memcpy ( 2個 in BulkTrans.cpp )
所以要真正加速而減少 memcpy 的話,必須要rewrite usbmsc bot部份
FILE_FLAG_WRITE_THROUGH & FILE_FLAG_NO_BUFFERING 沒用
http://support.microsoft.com/kb/99794/en-us
最後結果
能提昇USB速度有用的是 IntThresCtrl = 1
在Au1200 BSP中 修改registry 並沒有用
it is hard wired in Platform\DB1200\Drivers\USB20\EHCI\CHW.CPP
in CHW::EnterOperationalState()
set usbcmd.bit.IntThreshCtrl = 1 // original 8 microframe
EnableCache=0 + PacketsPerTransfer=80 in common.reg also improve
於是深入追蹤 在usbdrv.cpp 中發現在 GetInterface() 的上面有一段詳細說明
* The USB (OHCI) hardware assumes a host page size of 4K bytes. Under Windows CE, many
* supported processors do not necessarily follow this assumption (1K page size is common).
* The issue here is that the underlying hardware can use scatter/gather DMA, but
* can handle at most 1 page transition per transfer. However, client buffers on systems
* with smaller page sizes may be scattered across several physically disjoint pages.
*
* In order to make this restriction transparent to client drivers, OHCD.DLL allocates
* a buffer from the system which is known to be contiguous within 4K sections.
* Then, DMA is done to the private buffers, and copied to the client buffer
* once the transfer is complete. For some client drivers, this extra copy may
* impose an unacceptable performance hit, however. So, the Windows CE transfer functions
* allow the client to pass in an optional physical memory address which is used directly
* for the DMA to/from the HC hardware. Because the HC accesses this buffer directly,
* the following two restrictions must be rigidly adhered to:
*
* 1) Physical buffer must be contiguous within 4K segments. How the client allocates
* this memory is beyond the scope of this document (e.g. may be through a platform
* specific call). The LockPages() call can be used to get physical page information.
*
* 2) Client must not access or free the buffer before the transfer has completed.
意思就是說 USB Transfer 的時候,OHCD (or EHCD) 會 allocate 一個private的 4K buffer.
給 DMA 用,然後DMA完成時,再用memcpy 到 client buffer。
但是這會帶來 performance 的衝擊。
也就是 LPISSUE_BULK_TRANSFER (7個參數) 的最後一個參數 Physical Address 假如不為
NULL, Host Controller 會直接 DMA到這個 Physical Address.
以bot transfer 為例
BOT_DataTransfer (usbmsc.c) ....BulkTransfer::SendAnotherTransfer --> lpIssueBulkTransfer
http://support.microsoft.com/kb/937755/en-us
上面文章有用
三種加速的方法,Disable Cache, PacketsPerTransfer 0x80, IntThresCtrl = 1
在[HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\Mass_Storage_Class]
"DisableBuffering"=0 時會用 DMA =1 時 不用DMA(也就是不指定Physical address)
但是 = 0 時用DMA 也是另外 AllocPhysMem (in BulkTransfer::BulkTransfer() ) 然後再 memcpy ( 2個 in BulkTrans.cpp )
所以要真正加速而減少 memcpy 的話,必須要rewrite usbmsc bot部份
FILE_FLAG_WRITE_THROUGH & FILE_FLAG_NO_BUFFERING 沒用
http://support.microsoft.com/kb/99794/en-us
最後結果
能提昇USB速度有用的是 IntThresCtrl = 1
在Au1200 BSP中 修改registry 並沒有用
it is hard wired in Platform\DB1200\Drivers\USB20\EHCI\CHW.CPP
in CHW::EnterOperationalState()
set usbcmd.bit.IntThreshCtrl = 1 // original 8 microframe
EnableCache=0 + PacketsPerTransfer=80 in common.reg also improve
2011年2月9日 星期三
fscanf usage ( Parse Command Line )
在寫有關於Printer 的AP的時候,要parse command line from file.
使用 fwscanf 遇到問題,在google並在WIN32下debug和實驗後,找到解法。
http://support.microsoft.com/kb/60336/en-us
第一個fwscanf 之後的 fwscanf都parse 不出來 ( return 0 )
因為 file pointer 停在 delimiter 前面,後續呼叫會失敗
所以要加 %*c
使用 fwscanf 遇到問題,在google並在WIN32下debug和實驗後,找到解法。
http://support.microsoft.com/kb/60336/en-us
第一個fwscanf 之後的 fwscanf都parse 不出來 ( return 0 )
因為 file pointer 停在 delimiter 前面,後續呼叫會失敗
所以要加 %*c
2010年12月24日 星期五
inline function
在想要optimize AAC encoder 的速度的時候
想要inline fabs()
卻無法成功
1. inline is for C++, __inline is for C & C++
2.要change compiler option /Ob0 to /Ob1 or /Ob2 ( In C++ --> Optimization --> Inline function expansion )
http://msdn.microsoft.com/en-us/library/47238hez.aspx
3. /Ob1 和 /ZI (Edit and Continue) 選項衝突,改用 /Zi
4. __forceinline 強迫inline 但compiler 不一定會照做,參考
http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
想要inline fabs()
卻無法成功
1. inline is for C++, __inline is for C & C++
2.要change compiler option /Ob0 to /Ob1 or /Ob2 ( In C++ --> Optimization --> Inline function expansion )
http://msdn.microsoft.com/en-us/library/47238hez.aspx
3. /Ob1 和 /ZI (Edit and Continue) 選項衝突,改用 /Zi
4. __forceinline 強迫inline 但compiler 不一定會照做,參考
http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
2010年12月5日 星期日
JSAMPARRAY & jpeg_read_scanlines
JSAMPROW data[1];
data[0] = new JSAMPLE[1920*1080];
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, data, maxlines );
}
jpeg_read_scanlines 的第二個參數 JSAMPARRAY 是一個儲存 pointer to row 的陣列。
如果有一行 就得有一個元素,兩行就要有兩個元素。
也就是 & JSAMPROW 或 & data[n]
libjpeg.txt 的範例
JSAMPROW row_pointer[1]; /* pointer to a single row */
int row_stride; /* physical row width in buffer */
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
ycc_rgb_convert() in jdcolor.c
data[0] = new JSAMPLE[1920*1080];
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&cinfo, data, maxlines );
}
jpeg_read_scanlines 的第二個參數 JSAMPARRAY 是一個儲存 pointer to row 的陣列。
如果有一行 就得有一個元素,兩行就要有兩個元素。
也就是 & JSAMPROW 或 & data[n]
libjpeg.txt 的範例
JSAMPROW row_pointer[1]; /* pointer to a single row */
int row_stride; /* physical row width in buffer */
row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
ycc_rgb_convert() in jdcolor.c
2010年12月1日 星期三
Long Lasted Problem Solved. After OEMInit hang
在db1200 的板子上,之前一開始做新的Image
NK.bin 都會Hang 在 -OEMInit 之後。
因為在 startup.s 中,呼叫完 OEMInit 之後 會reenable interrupt
而因為在公版中 有用到GPIO7 也就是 IC1 interrupt 7
如果這個GPIO7 pin 的狀態為 High 沒問題, 如果為 Low 的話 則會trigger interrupt 導致系統Hang住。 (使用MMPG module 就可以pass, 因為它把GPIO7 pull high
之前粗魯的解決方法就是 Disable 整個 IC1 (在startup.s 中 disable interrupt mask )或者在 intr.c (OEMInterruptInit() )中 disable 整個 IC1 handler。
但是正確解法應該是,修改 db1200.h 或 pb1200.h
修改 PLATFORM_INTR_IC1_07
// Platform-specific interrupt defintions for kernel/hal/intr.c
#define PLATFORM_INTR_IC1_07 irqLL | INTR_MODE_UNMASK // 39 GPIO7 Board Interrupt Controller
不要定義 PLATFORM_INTR_IC1_07 的話 在intr.c
的 InterruptConfiguration[HWINTR_MAXIMUM ] array 就會定義 PLATFORM_INTR_IC1_07 為 irqNA
#ifndef PLATFORM_INTR_IC1_07
#define PLATFORM_INTR_IC1_07 irqNA
#endif
PLATFORM_INTR_IC1_07,
NK.bin 都會Hang 在 -OEMInit 之後。
因為在 startup.s 中,呼叫完 OEMInit 之後 會reenable interrupt
而因為在公版中 有用到GPIO7 也就是 IC1 interrupt 7
如果這個GPIO7 pin 的狀態為 High 沒問題, 如果為 Low 的話 則會trigger interrupt 導致系統Hang住。 (使用MMPG module 就可以pass, 因為它把GPIO7 pull high
之前粗魯的解決方法就是 Disable 整個 IC1 (在startup.s 中 disable interrupt mask )或者在 intr.c (OEMInterruptInit() )中 disable 整個 IC1 handler。
但是正確解法應該是,修改 db1200.h 或 pb1200.h
修改 PLATFORM_INTR_IC1_07
// Platform-specific interrupt defintions for kernel/hal/intr.c
#define PLATFORM_INTR_IC1_07 irqLL | INTR_MODE_UNMASK // 39 GPIO7 Board Interrupt Controller
不要定義 PLATFORM_INTR_IC1_07 的話 在intr.c
的 InterruptConfiguration[HWINTR_MAXIMUM ] array 就會定義 PLATFORM_INTR_IC1_07 為 irqNA
#ifndef PLATFORM_INTR_IC1_07
#define PLATFORM_INTR_IC1_07 irqNA
#endif
PLATFORM_INTR_IC1_07,
2010年11月17日 星期三
CreateDIBSection
在做印表機驅動程式的時候,要在圖片旁邊加字。
使用到CreateDIBSection
因為 Resolution 太大( 2392x3400) 所以 CreateDIBSection 只能一次
第二次會失敗。
所以每次都要釋放乾淨。
要用
SelectObject 把 DIBSection select 出來
然後 DeleteObject
使用到CreateDIBSection
因為 Resolution 太大( 2392x3400) 所以 CreateDIBSection 只能一次
第二次會失敗。
所以每次都要釋放乾淨。
要用
SelectObject 把 DIBSection select 出來
然後 DeleteObject
訂閱:
文章 (Atom)