6.29.2010

The master makefile of Windows CE

真是太感謝 Kun-Yi 啦!

從我進來這裡,RBT 就展示他sysgen XXX 的能力,讓我門少build 一些 code,少浪費一些時間。
但是我問他,怎麼知道 改 OOO 時要用 XXX ?
他也說不出個所以然來
不然就是他不願意說...
所以我就不斷的在找這個謎.....(找了好幾年..)

後來,上一篇,偉大而又無私的 資深 Windows CE 專家 Kun-Ki 直接給出答案:
就是 PUBLIC\COMMON\CESYSGEN\makefile

打開來看,果然有所有 target 的 name 和 dependency..

真是令人感動!!

終於看到 CE 的 master makefile ....

6.28.2010

output message on device on/off - sysgen and private

在查 system poweron/off 時,有時要列印出所以 driver 的 on/off message。
一個一個加很麻煩,可以直接在 device manger 加:
C:\WinCE600\PRIVATE\WINCEOS\COREOS\DEVICE\DEVCORE\Devapi.c
裡面的 DevMgrPowerOffHandler:
原來的
                DEBUGMSG(ZONE_PNP,(TEXT("Calling \'%s\' PowerDown at 0x%x\r\n"),
改為強制輸出的 RETAILMSG 就可以。


在該 folder build 完後,下 sysgen -p common devmgr 後,就可以makeimg 了。



-p common 的意思是 "在 wince600\public\common 下"
-p option 好像是指 public 下的 folder。
所以 sysgen -p common devmgr 的意思是要 sysgen public\common\ 下的 devmgr
-- 雖然不知道怎麼看出common folder 里有 devmgr 這個 target @_@..

可以測試一下:
sysgen -p directx 會 build 出 public\direct 下所有的 directx example
如果只要 build mosquito:
sysgen -p directx mosquito



sysgen 也是一個 batch 檔...

只是我一直找不到那些 sysgen 的 "target" 到底在哪裡...

關於 sysgen 的target ..大概可以到 retail folder 去找,, dll 或是 exe。
用 cesysgen_capture,會產生 該 project 的 sources file,然後去找該 target 是由哪些
library build 出來的。
cesysgen_capture -p common devmgr 
會產生一個 sources.devmgr

sysgen_capture device

會產生一堆 (相依?) 的 source 檔:
  • sources.ceddk -- ceddk.lib
  • sources.devmgr -- devmgr.lib
  • sources.pm -- pm.lib
  • sources.udevice -- udevice.exe
  • sources.device -- device.exe

6.24.2010

operator overwrite : conversion function

在WTL 的source code 看到:
operator HBITMAP() const { return m_hBitmap; }
所以不知道是哪一個 operator 被 overwrite。

有 HBITMAP 這個 operator 嗎?

的確,就是 conversion function

自動型別轉換.
CBitmap theBitmap;
HBITMAP hBitmap;

hBitmap = theBitmap; // 等於是 hBitmap = (HBITMAP)theBitmap;

這個就是 conversion
上面的 example 會讓 hBitmap = theBitmap.m_hBitmap;

... 好像也是為了好看...好吧,還有方便..

smart_ptr in WTL CBitmap

看到 WTL 的 AtlCopyBitmap ( ) 中,有:
CBitmap bmNew = NULL;
..
bmNew.CreateCompatibleBitmap( ..
覺得很奇怪。
所以看一下 CBitmap 的 implement (在 atlgdi.h),, 有這一段:
CBitmapT<t_bManaged>& operator =(HBITMAP hBitmap)
{
Attach(hBitmap);
return *this;
}

void Attach(HBITMAP hBitmap)
{
if(t_bManaged && m_hBitmap != NULL&& m_hBitmap != hBitmap)
::DeleteObject(m_hBitmap);
m_hBitmap = hBitmap;
}

HBITMAP Detach()
{
HBITMAP hBitmap = m_hBitmap;
m_hBitmap = NULL;
return hBitmap;
}

所以是 CBitmap overwrite 了 operator "="
配合 attach, detach 來看,這有點像 smart_ptr 的作法。... 雖然他是handle wrapper,不是 pointer wrapper..

typedef CBitmapT CBitmap;
true 代表 memory management 由 class 自己 handle。


所以那個 CBitmap bmNew = NULL 代表將 bmNew 的 member m_hBitmap 設為 NULL。
這應該只是為了好看吧..否則寫兩行也可以呀:
CBitmap bmNew;
bmNew.m_hBitmap = NULL;

6.23.2010

GDI - SelectObject

DC (Device Context) 是畫布
一堆 GDI 物件:Pen, Brush, Font, Bitmap, ..都是可以畫在畫布(DC)上的物件。


所以要用這些 GDI 畫圖時,要用 SelectObject(DC_A,Object_A) ,告訴kernel 我要 DC_A上用Object_A 畫圖了。

SelectObject( ) 會傳回那個 DC 原來的 Object 內容,讓你畫完後,可以 Select 回來原來物件。
例如原來是 12 點字,後來用 14 點字寫幾個字後,選回原來的 12點字


... 希望這個想法可以用....

6.17.2010

show progress bar when booting - CE

這一篇 說道如何作 開機動畫。

他的作法是在 CE driver 中作,他選 backlight driver。
-- 應該要把 backlight driver 放在前面一點。

在 backlight driver 啟動(Init or PowerOn ?)的時候 create 一個 thread,定時的 update lcd buffer。一直到 Stopflash 的 event 送達。

Stop event 可以由 shell 送出。代表開機完成了。


問題: Driver PowerUp/Down 時好像是 single thread,可以create thread 嗎?

auto_ptr

auto_ptr 是 smart_ptr 的一種。

利用 auto variable 在離開 scope 會自動被 delete 的特性。
讓 一般的 pointer variable 在 new object 後,也有這樣的特性。
這樣,就不必特地在 function return 前 手動 call delete 了。

參考 http://ootips.org/yonat/4dev/smart-pointers.html

原來 pointer 的寫法:
void foo()
{
MyClass* p(new MyClass);
p->DoSomething();
delete p;
}

改用 auto_ptr 後,可以這樣寫:
void foo()
{
auto_ptr<MyClass> p(new MyClass);
p->DoSomething();
}

針對 memory 管理這一點,auto_ptr 還提供一些其他的功能:
  • 指定;當一個 ptr = 另一個 ptr,原來 ptr 的 object 會先 delete 掉。
  • exception handling : 在所有動作作try-catch,這樣當 exception 時,還可以正常 free 掉 object

6.15.2010

Bookmark - Monte Carlo Profiler for CE 6.0 (MSDN)

http://msdn.microsoft.com/en-US/library/ee481579.aspx 這一篇 MSDN 有講 CE 6.0 Monte Carlo Profiler 的作法,可以試試看。

用 target control 下 prof 可以看到help

6.14.2010

WTL - request to send WM_PAINT message

WM_PAIN message 被送出的機會有:
  • OS 發現你的視窗區域需要重劃了,例如:被其他windows 蓋過,size 改變..
  • 你自己呼叫 function,叫 OS 送 message 給你
WTL 里要呼叫 Invalidate( ),實際上是 ATL implement 的,不是 WTL。
在 altwin.h 。
實際上他也是呼叫 InvalidateRect( ) 而已。


順便寫一下 CPaintDC

原本在 Win32SDK 中,要對 DC 作動作,都要 beginpaint, get xx 等一堆,然後畫完又要 endpaint.. etc.

CPaintDC 就把剛剛的動作包裝起來,在 constructor 中作 BeginPain,在Destrctor 作 EndPaint。

又 CPaintDC 繼承自 CDCT。

CDCT 是 WTL 把所有 Win32 的 DC 繪圖包裝起來的 class。
所以一旦生成 CPaintDC 後,就可以任意使用 DC繪圖 function 了。

6.10.2010

Simple Dialog Program with WTL

一個簡單的 Dialog 程式:
main.cpp:
#pragma once
#define WINVER 0x0420

#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>

#include "resource.h"

class CMainDialog : public CDialogImpl<CMainDialog>
{
public:
enum { IDD = IDD_MAINDLG };

BEGIN_MSG_MAP(CMainDialog)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP()

LRESULT OnCancel(WORD,WORD wID,HWND,BOOL&)
{
::PostQuitMessage(wID);
return 0;
}
};

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE,LPTSTR lpstrCmdLine, int nCmdShow)
{
HRESULT hRes = ::CoInitialize(NULL);

::DefWindowProc(NULL,0,0,0L);

AtlInitCommonControls(NULL);

hRes = _Module.Init(NULL,hInstance);

CMainDialog dlgMain;
hRes = dlgMain.DoModal();

_Module.Term();
::CoUninitialize();

return hRes;
}

resource.h
#define IDD_MAINDLG 101

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

resource.rc 就是一個 dialog,沒有 button。


奇怪,現在我自己照著作,反而要改這樣:
.c
#pragma once
#define WINVER 0x0600

#include <atlbase.h>
#include <atlapp.h>
#include <atlwin.h>

#include "resource.h"

class CMainDialog : public CDialogImpl<CMainDialog>
{
public:
enum { IDD = IDD_DIALOG1 };

BEGIN_MSG_MAP(CMainDialog)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
END_MSG_MAP()

LRESULT OnCancel(WORD,WORD wID,HWND, BOOL&)
{
::PostQuitMessage(wID);
return 0;
}
};

CAppModule _Module;

int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE,LPTSTR lpstrCmdLine,int nCmdShow)
{
HRESULT hRes = ::CoInitializeEx(NULL,COINIT_MULTITHREADED);
::DefWindowProc(NULL,0,0,0L);
AtlInitCommonControls(NULL);
hRes = _Module.Init(NULL,hInstance);

CMainDialog dlgMain;
hRes = dlgMain.DoModal();
::CoUninitialize();

return hRes;
}


.h 大概就跟上面一樣。

Close button on Dialog Menu

原來 msdn 有寫

Dialog Create 時有加上 "WS_SYSMENU" flag 的話,dialog 上方就會出現 menu bar,然後有 minimize, maximum, close 三個方塊在右邊。

當按下 close 方塊時,windows 會送出 IDCANCEL 這個 command。

所以要加上 IDCANCEL 的 command id handler ,才會關掉 dialog。

6.09.2010

WTL : the simple ATL Windows Program


#define STRICT
#define VC_EXTRALEAN

#include <atlbase.h>
#include <atlwin.h>

class CMyWindow : public CWindowImpl<CMyWindow,CWindow,CFrameWinTraits>
{
public:
DECLARE_WND_CLASS(_T("My Window Class"))

BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_DESTROY,OnDestroy)
END_MSG_MAP()

LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
DestroyWindow();
return 0;
}

LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0);
return 0;
}
};


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPTSTR szCmdLine, int nCmdShow)
{

CMyWindow WndMain;
MSG msg;

if (NULL == WndMain.Create(NULL,CWindow::rcDefault,_T("Hello")))
{
return 1;
}

WndMain.ShowWindow(nCmdShow);
WndMain.UpdateWindow();

while(GetMessage(&msg,NULL,0,0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}

可以用在 Win32 和 Win32_CE 上。

ISDBT Error Correction Code

ISDBT 信號使用 Reed Solomoon 作 Error Correction Code。

有時候,為了要能測試出 RF 接收的特性,必須把接收端的 Reed Solomoon Correction 關閉。

6.07.2010

WTL : Windows Template Library

WTL 是 Template Library,所以安裝的方法就是解開後,把 WTL\include 加到 project 的 include path 里就可以。
Tools--Options--ProjectAndSolutions--VC++Directory
這個option 每個 platform (Win32, Ce, SmartPhone..) 都不樣,所以要一一設定。


AppWiz 是安裝 WTL AppWizard 的javascript,根據 VS的不同,有不同的 script
  • setup80x.js 是 for VS2005 express 版本,但是 express 版不包含 ATL,所以要而外安裝一版 platform SDK 。
  • 也有提供 WinCE版本的 wizard install script
Wizard 執行完後,New Project,選 WTL, Dialog base ,就可以create 一個 dialog program。

就先由 Sample 的:ImageView 作練習,sample 是 for smart phone,照著 copy 到 standard sdk


看 起來好像是 SDI application。所以用 Wizard create 一個 SDI..
一開始就遇到一個問題....CString 宣告不認識 -- 結果好像是 WTL8 有改了,要 include atlmisc.h。


感覺起來就是利用 template ,做到針對 function implement class/template。
使用時依照需要繼承 class/template,然後改寫某 function。
這就跟 RBT 的 coding 構想一樣:找class繼承,然後修改

這樣的設計理念應該是每個 class/template 只做一件事。使用的方法就是繼承,修改,然後生成。

另一種理念應該是...萬能的 class,使用發法是生成(給予適當參數),然後使用。
所以 WTL 的程式設計好像是...了解MFC 原來 一些 event hander -- OnCreate, OnPaint, OnClick,,,, 在 WTL 中處理的 template/class,依照需要的時候繼承下來,然後就可以改寫 那些event handler。


唉~~對於 FrameWindow 跟 Window 的區別還是不了解..

在 atlcrack.h 的 BEGIN_MSG_MAP_EX 註解:
// Note about message maps with cracked handlers:
// For ATL 3.0, a message map using cracked handlers MUST use BEGIN_MSG_MAP_EX.
// For ATL 7.0 or higher, you can use BEGIN_MSG_MAP for CWindowImpl/CDialogImpl derived classes,
// but must use BEGIN_MSG_MAP_EX for classes that don't derive from CWindowImpl/CDialogImpl.
所以繼承 CWindowImpl和 CDialogImpl的話,就可以用 BEGIN_MSG_MAP,如果不是繼承這兩個,就要用 BEGIN_MSG_MAP_EX (?)
CWindowImpl和CDialogImpl 定義在 ATL。
  • CWindow (也定義在ATL),只包含 HWND這個資料結構的內容,還有一些標準 WIN32 function 。並沒有做出 message loop,message handler 這樣的架構出來。
  • CWindowImpl 就有 implement message loop/handler 的架構。
所以
  • 繼承 CWindow 的話,要自己作 message loop/handler -- WTL 提供 BEGIN_MSG_MAP_EX 這類 macro。
  • 繼承 CWindowImpl 的話,已經有 message loop 了,就用 BEGIN_MSG_MAP 就可以。
ATL 有關 Windows 部份可以參考 MSDN
http://wtl.wikispaces.com/ 這個有比較好的wiki說明。

6.04.2010

IJG - Inependent JPEG Group

IJG 提供一個JPEG 操作的 library,目前已經到 v8,有持續在 update。

download source code 下來後,看一下 install.txt,裡面有說在各 platform 的 build 方法。
在 Windows VC 的話,分為兩種:
  • 使用 command line
  • 使用 VS 開project
用 VS 開 project 的方法我不會用,project 開起來會 fail,所以我只好用 command line 的方法:
  1. VC command build 用 makefile.vc,config file 用 jconfig.vc
  2. 所以先 copy 一份 jconfig.vc 為 jconfig.h
  3. nmake -f makefile.vc
OK。

要注意,在 VC Command line 下 build,要先 run 過 VC 目錄下的 SETVCVAR.BAT 設好path.


build 好後:
  • cjpeg.exe 是壓縮
  • djpeg.exe 是解壓縮


看makefile.vc 可以看一下 libjpeg 的 source,
依照 compress,decompress分成
CLIBOBJECTS= jcapimin.obj jcapistd.obj jcarith.obj jctrans.obj jcparam.obj \
jdatadst.obj jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj \
jcprepct.obj jccoefct.obj jccolor.obj jcsample.obj jchuff.obj \
jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj

DLIBOBJECTS= jdapimin.obj jdapistd.obj jdarith.obj jdtrans.obj jdatasrc.obj \
jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdmainct.obj \
jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj jidctflt.obj \
jidctint.obj jdsample.obj jdcolor.obj jquant1.obj jquant2.obj \
jdmerge.obj

只需要 decompress 的就只要 build DLIBOBJECTS 就可以

CPU 與週邊 的速度

CPU 跑 600,週邊 IO 的 clock 是 60。
所以當 CPU 對 GPIO register 寫資料時,是同步在 60MHz...


ldr r0, =GPIO1_PAD_EN
mov r1, #0x00100000 ; pin 20
str r1,[r0]
ldr r0, =GPIO1_CTRL20
mov r1,#0x120
mov r2,#0x160
1
str r1,[r0]
nop
str r2,[r0]
nop
b %b1

這一段 code,有沒有加 nop 輸出的方波都是 10MHz。
但是把 nop 改為

str r1,[r0]
str r1,[r0]
str r2,[r0]
str r2,[r0]
b %b1

這樣改完,輸出方波變成 5MHz。


也就是說..如果一直 polling 週邊得的話,就等於是用 60MHz 在跑....