2009年8月18日 星期二

指標的藝術,讀後感



書名:指標的藝術,程式設計最絢麗的星星

作者:蔡明志

出版:碁峰

日期:2009.07

 

這本書吸引我的是,中文很少有專門探討指標的進階書。

但就目錄上來看,我才發現原先以為沒有指標的電腦語言竟也出現在內。

因為我本來就熟C也很清楚學會了,幾乎就等同掌控其語言的控制能力。

不過另一點的是,作者"蔡明志"之前出的書也很不錯。之前出資料結構及C語言的書都寫得不錯。

書可以看到的語言有CC++C++/CLRJavaC#Visual BASIC

那一本書看完了,不就一次會六種語言的核心了,我是這樣想。而且只需安裝Visual StudioJava二套軟體就可以玩了。

 

就書內容結構來看,仍以C語言的篇幅最大。這也是合理,因為除了C++其他語言無明顯指標。

內容以每一種語言皆使用同一種資料結構的表示法來示範如何寫。

本以為進階書會提出更深入的內容,但沒有,只是示範最基本的資料結構。大幅度的將難度降低了。

其實我覺得這樣做是合理的,因為進階書本來就不好賣,太深入恐怕讀者更少,降低難度有助於推廣。

 

對於想在程式上有進階參考的工程師,我認為這仍是一本值得看的書。

而指標已經熟悉的人,看了此書也可以一次通曉六種語言,仍是值得買來參考的。

2009年8月17日 星期一

CUDA程式設計比賽

參加nVidia舉辦GPU程式設計比賽。
http://www.nvidia.com.tw/object/cuda_contest_main_tw.html

2009年8月10日 星期一

立體視覺計算

這是之前專題的照片。主要是解雙目視覺。因為現在已改成由GPGPU來做了,就將以前實驗的成果張貼一下。
之前用Matlab做的,計算時間很久。當時只是驗證可行性。

實驗環境:


左眼照片:


右眼照片:


視差計算結果:

立體圖:

uCOS-II Win32 Port解析及改善 -- 3

Win32 port運作原理解析:


基本原理是使用WindowsThread機制來做為uCOS-IITask管理。但實際上有許多細節要處理。一般要移植有幾件事要處理。


1.    Critical Section方法選擇


2.    Context Switch的方法


3.    InterruptTimer Interrupt處理


在移植到CPU時,因CPU的特性有一定行為,可以找出對應方法。


但在作業系統上做移植,仍要處理,但面對的行為不同,所要處理方式變得完全不同。


在使用作業系統的Thread做為管理時,所要考量的項目及目標為:


1.    Context Switch的方法:因為己非CPU動作,所以此項行為要借用被寄生作業系統的既有動作。在此次porting是使用Event觸發的方式做,借由另一個優先權最高的排程器程式來執行,而Context Switch真正工作已由被寄生作業完成,只剩下排程。而排程不可能由Task來執行,因為Thread只可以被suspendresume,中間無法插入其他程式去執行,故必須產生一個獨立的Thread來執行。


2.    Interrupt方法:由被寄生作業系統的Event觸發執行的Thread來做,也會使用排程器,另外加上UserInterrupt hook


3.    Critical Section設定:只需關閉寄生作業系統所使用的Event就可以做到。


4.    Idle Task的方法:在CPU時會跑計數器,但在寄生則要加上Sleep(),將工作權還給被寄生作業系統。


依函式名稱有修改的列表為:


OSCtxSw(void)


OSIntCtxSw(void)


OSStartHighRdy(void)


OSTaskIdleHook()


OSTimeTickInit(void)


OSTaskStkInit(...)


OSTCBInitHook(OS_TCB * pTcb)


OSInitHookBegin()


以上皆為使用原先的功能及Hook功能加載來加入所需處理程序。


四種重要的函式為


OSEnableInterruptFlag(void)


OSDisableInterruptFlag(void)


OSScheduleThread(INT32U param)


OSInterruptThread(INT32U param)




前二個函式為Critical Section所使用。後面二個為Thread程式本身,也是此porting關鍵之所在。而使用二個獨立的Thread來做為ScheduleInterrupt的工作是在CPU移植上不會見到。可以若以多重CPU的系統來說,這反而是更為合理的做法,因為在CPU數量無限的狀況下,O.S. context switch是浪費時間的,而由另一個CPU做排程會是更好的方法。經由了解二個額外的Thread可以更清楚的了解在Win32 port的工作內容。




OSScheduleThread(INT32U param)主要工作是承接由OSCtxSw(void)呼叫之後的工作。故此Thread就必須擁有最高的執行優先權,由Win32API的行程同步函式WaitForSingleObject()做為其等待的函式。在等到有觸發產生執行時先以維護uC/OS-II應做的事,最後再以SuspendThread()ResumeThread()此二個Win32API函式做為uCOS-II中的Task切換的工作的控制。在此並不像切換,反倒是更像開關。而所有的Task必須在Win32API下註冊為一獨立的Thread才可以正常運作。在Win32 port中以hTaskThread[]變數做為ThreadHandle存放矩陣,對應數目和TCB相同。故可以看到在處理TCB時也必須修改。但在OS_TaskChangePrio()因無Hook函式可以用,因而無法使用。




OSInterruptThread(INT32U param)工作內容較為簡單,在Win32 port中主要是模擬出八個中斷給uC/OS-II用,除了interrupt 0是保留給Timer用,其餘皆為使用者定義。使用Win32APIWaitForMultiObjects()為其等待函式,hInterruptEvent[]變數則為存放Event Handle的地方。Win32APIEvent在使用後必須呼叫ResetEvent()Event做清除動作。而User Interrupt function則存放於interruptTable[n]()函式指標矩陣中。




由以上解析可知,在Windows端使用到的函式為


OpenEvent()


SetEvent()


WaitForSingleObject()


WaitForMultiObjects()


setTimeEvent()


ResetEvent()


可以查Win 32A PI中對於這些函式的使用方式就可以了解寄生及被寄生作業系統之間的相關性。


uCOS-II Win32 Port解析及改善 -- 2


使用Win32 port實作:

此次實作環境為:

Windows XP作業系統

uC/OS v2.80

Borland C++ Builder 6.0

 

uC/OS中的檔案修改如下:

CPU相關的檔案有

OS_CPU.H

OS_CPU_C.C

此二個檔案必須更換為Win32 port用的檔案。而原先必須使用組合語言的OS_CPU_A.ASM則未使用,原因是使用的是高階呼叫,故不需要,而在此檔案內的功能則由OS_CPU_C.C取代。

PC介面相關的檔案為

PC.H

PC.C

則也必須更換為Win32 port下使用的版本。

C++ Builder中則是以Console Applications為程式行為主體。所以可以知道程式只有一個進入點main(),和原先CPU的單工環境相類似。

先利用原作者提供之Example檔案建造執行檔,看有無其他問題。但部分程式碼仍會產生一些Warning,主要是原型宣告在不同的Compiler下有些不同,經稍為修飾後即可執行。其畫面如下:

原始碼有提供使用外部中斷的程式,一樣使用C++ Builder重建,在執行後可以改變Example的輸出結果,可以證明確實可以使用另一程式對Win32 port的程式產生中斷觸發的動作。結果如下:


因為並非常用此Example做為開發用。故以原始的Example #2為例修改並編譯,發現原始碼中有許多為DOS專用程式碼,必須刪除。但為了維持其可移植性,改使用巨集調整的方式做為不同平台之間原始碼調整用。在Win32 port中可以找到一些特有巨集定義在使用Windows時,以”__WIN32__”巨集可以使用。

相關的修改包括有:

DOS中斷設定及回復:在Win32中不需要。

程式結束的處理:在Win32中處理的函式不同。

浮點運算器的處理:在Win32中不使用模擬浮點相關設定。

在設定好了巨集切換後,可以執行的畫面如下:


可以看出外型雖然有像DOS版本程式,但仍有許多不一樣的地方。

1.    Free Stack的大小,呈現完全沒有使用的狀態。原因是Task StackWin32下是由作業系統安排,人工配置Stack並不會使用。但為了維持和DOS相同的程式碼,仍配置Stack用記憶體。

2.    最下面一行的閃爍字元並不閃爍,這是因為PC.C中的Win 32A PI中的Console控制並沒有設定閃爍字元。但不影響主要功能。

3.    螢幕大小是可以縮放,所以右側多了滑動棒。DOS是固定25*80字元,而Win32 port無此限定。在使用Printf()函式時,可以保留更多的資訊。

4.    Windows上面CPU使用率維持不超過10%,因為使用WindowsSleep(),相對於uC/OS上的CPU使用率是不準的。




uCOS-II Win32 Port解析及改善 -- 1

摘要:


uCOS-II移植到Win 32A PI函式下,使之成為寄生在Win 32A PI下的作業系統。並改進和外部通信的部分,增加可使用能力。對於桯式邏輯除錯及模擬上有較佳支援。


 


介紹:


了解uCOS-II作業系統結構和Windows作業系統中的行程管理函式,經由移植的方式增加作業系統之了解。在此移植中要實現的功能有:


1.        uCOS-II中斷模擬。


2.        WindowsuCOS-II資料傳輸通道連接。


一般在學習uCOS-II會在Windows下使用DOS模式來學習,但純DOS程式在Windows下會很消耗CPU使用率,在使用Windows port程式則使用Windows管理則不會消耗CPU使用率,而且可以使用一般Windows的程式除錯器,對於程式邏輯的除錯效率上可以發揮很大的功用。


uC/OS Win32 port主要是採用Werner.Zimmermann的版本為主。採用此版本的主要原因是原作者只利用到原始uC/OS程式碼中的hook功能,不去更動作業系統中的程式碼,如此可以保有在各處理器及各版本之間的相容性。而且在各版本的uC/OS Windows port中亦為有在維護在最新狀況下的版本。不只可以在Windows下執行,亦可以在Linux中實現,足可見此版本的移植力甚強。故以此版本為其基礎,探討其運作原理及加入模擬所需之改進。但此版本目前仍有部分功能並不是完全做到,第一點是即時性,因為是寄生,所以無法做超越基礎作業系統的能力;第二點是限定無法使用OS_TaskChangePrio()


在其他版本則有其功能不全,故未予以採用。以下簡介不採用原因:


www.micrium.com 中有使用Win32 Thread的版本,此版本並沒有支援uC/OS中斷的能力,所以無法有效使用其版本。


http://wsim.pc.cz 亦有uC/OS win32 port,但其uC/OS版本在2.00版本,必須使用其專用模擬器,且版本亦沒有維護,恐與後面版本產生不相容現象,故亦不予採用。