2011年1月9日 星期日

看到Tegra2推展影片感想

整個影片只有一個地方是比較讓Bee有感覺的。

那就是ARM處理器對x86處理器數目比。

現在ARM處理器年產量是10倍於x86處理器。

Bee以為只是數倍,顯然太久沒去注意了。

其實從Object-C快速崛起時,應該就有十倍差。

難怪nVidia要轉戰ARM。

以目前ARM的產量再走下去,真正隨手可以撿到的處理器,遲早會是ARM,而不是x86。

那Bee還是要加緊腳步移到ARM才是。


虛擬機器模擬I/O方法

想了一段時間,沒想到是個簡單的方法。
還虧Bee是電子出身的,竟然要想這麼久。
就回歸到原始的信號就行了。

只有幾個項目:時間、位址、資料。
當自己寫下要如何傳的瞬間,就想到示波器(邏輯分析儀比較正確)。
真是笨啊!不就和寫verilog相去不遠。才幾年就忘了那個感覺了嗎?

可以先做檔案將時間表格記錄,再根據時間載入模擬的I/O記憶體。
這樣可以完成初步版本。
其實可以用邏輯分析儀將Bus抓一次,檔案就算完成了。
不過身在軟體部,要借恐不易,還是自己慢慢寫。

進階版本,具有物理模擬系統也不難。因為最後要輸出的還是基本信號。

在軟體實現上。用檔案也是Open File,用Pipe也是用Open File。
所以用檔案讀入,或者用另一個程式寫入,都是用Open File指令,完全不用改。
先去完成用檔案的方式就行了。

註:寫完才想到,直接和電子部去要verilog模擬檔就行了。唉!反應變慢了。

2011年1月6日 星期四

多核心時代真的到了

近二個月收到一些訊息。
有DSP開始推展多核心,有在賣八核心的DSP。
也看到了Forth也出了144核心的chip。
而Bee自己在玩OpenMP及CUDA。
ARM也出了不少雙核,只是Bee沒有接觸到。
這些都是多核心的處理器。且隨手可得。那接下來呢?
當然就看軟體如何去應用了。

不過工程上遇到的第一個問題會是如何去設定編譯器(Compiler)。
這個一直是一般工程師很少去注意的問題。大部分都是安裝好就不會去動了。
如果您像Bee一樣是嵌入式系統工程師,那就必須去面對Compiler相關的問題。

主要的問題是,主流的語言都是由單核心發展起來的。
所以要控制多核心時,就要調整Compiler的設定。可以由語言內或語言外的設定去調整。
但是Bee常常看到網路上有一堆人在問,為何設定不起來。
沒辦法,大部分人在學compiler都是一知半解。更何況是半路出家的工程師。
有許多在使用嵌入式系統的工程師都不是學軟體的。
Bee感覺到從機械來的人也不少,可能是因為從事和機器人相關的,所以才會如此感覺。

好了回歸主題,多核心時代到來。要做的準備工作就是:記得準備好使用工具,把Compiler學好點!

2011年1月2日 星期日

64位元作業系統推廣關鍵:3TB硬碟

Bee最近換筆電,使用Win7-64。對於慣用XP的人來說,真是一場災難。

連平常用於嵌入式系統的開發工具都無法順利使用。原來Win7-64不支援16位元DOS模擬。
所以Bee實在不知這個64位元作業系統的需求在那裏。

比較大的記憶體?又沒有在玩影像編輯,所以很少破3GB的記憶體使用。
剩下還有什麼非換不可。實在想不出來。

最近發現一篇在談3TB的硬碟要如何安裝。這才發現硬碟才是真正驅動使用者去換的關鍵。
為何?因為要64位元CPU才能安裝3TB的硬碟。
原因有興趣的人自己連過去看。
揭曉3TB秘辛,全程追輯,帶領你成功安裝作業系統!

為何是關鍵?主要還是網路的流行,在使用網路會用到硬碟,卻用不到記憶體。

要不然就要一顆顆硬碟買下去。但硬碟價格只會低,遲早會撞到價格問題。到時才會一口氣換。
那下一波的換機潮,就看3TB硬碟的價格了。


2011年1月1日 星期六

再次移植uCOS-II Win32 porting

這次目標是公司的嵌入式作業系統。
它是很奇怪的系統。主要會長成這個樣子是歷史因素。
全程式原始檔大小約20MB。除去工作展示用的資料,原始程式碼也有10MB以上。
發展維護時間可以查到的有15年,但Bee認為超過20年。
因為使用的技術都是20年前的。
從原先的沒有作業系統的核心程式,採用狀態機控制系統。
到移植現代作業系統,程式都存在。
形成半狀態機半作業系統程式混合型。程式碼還夾雜從前狀態機於DOS上模擬的痕跡。
但後面無人再發動於DOS下模擬的程式,所以程式是壞的。
而編譯器用的是公司已經消失的68K compiler。
故只要離開公司,程式碼是無法編譯的。
原系統在組合語言的成份好像還很大。但後期有被大量用C改寫。除了作業系統核心外。

Bee接下程式已超過4年,仍無法弄清楚程式的運作。
主因是沒有軟體除錯器。因為作業系統會干擾Debugger運行。
但在這次的移植工作中,開始打開一扇門。利用Windows來看整套程式的運行。

在此還是感謝直屬主管願意讓我花一個月的時間去做這件工作。
因為在投資者的角度來看這種沒有產出產品的工作是沒有價值的。
其實這件事Bee已偷偷做了數個月的程式碼整理工作。
除去了程式碼約200個compiler warning。
實際在移植時又發現了200多個Warning,也是一一想辦法去除。

Warning以這幾類居多
1.型別不合
  compiler有部分會提示。部分的意思是,在放入Windows後,數目又大了三倍。
2.未用到的區域變數
  歷任維護者除錯用的。因為compiler完全不理會,所以此垃圾數量龐大。
3.沒有初始值就使用
  因為初始值會佔用ROM,故90%以上的變數都是這樣寫。
4.有路徑沒有回傳值
  就是使用switch case完全沒有default項。
  還有函式應有回傳值,在眾多的if-else之中就一個有return但沒有值。
  最常發生在走全為else的路徑,就直接走到函式最後一行。
  Compiler沒提示,所以無人發現。
這些Warning花了數個月。

建造Windows下的Project也是一件辛苦的工作。
約有150個C檔案以及150個H檔案。
C檔案有不同結構模式,所以有數個main()。
這次針對的是有130個C檔案的狀況。因為有許多同名函式,光是main()就有數個。
所以建造project的檔案不能錯,不能多,更不能少。
這一個月中,為了建立成exe檔就花了二週多。Warning多到不知何時才能完成。

建好exe檔,才是第一關,再來是執行時的不合法存取,被Windows踢出來。
有CPU的設定,Flash ROM的存取,FPGA I/O存取,這些都是。
就使用條件巨集切換,不是跳過就是導向另一個自己寫的I/O函式。
因為Bee先將FPGA I/O先用一塊記憶體先模擬。至少可以讓Debugger可以動。

main()終於可以跑完,第一關結束。OS模擬,才開始。
這是要參考uCOS,Windows以及嵌入式作業系統各作業函式的功能進行比對。
才能決定如何將這三者做融合。
終於這個星期做出來了。
現在同一套檔案可以直接編譯成Windows及目標系統的目的檔。
不過目前仍因為I/O是用記憶體模擬,要模擬到像機器,仍有好一段路。

2010年12月13日 星期一

組合語言轉成C語言

這是在一個不知不覺下完成的一個工作。
做完了才發覺是完成這個動作。

發生的狀況是:
Bee在做不同平台間的移植作業。
來源是68K的系統,目的系統不便明說。
為了方便移植工作順利,先移到Windows平台做模擬驗證動作。
有些和系統及作業系統相關的組合語言,因為在Windows下有另一套函式取代,所以不轉移。
有的則是使用內嵌組合語言的,因為和處理器設定有關的,則是利用條件編譯的方式跳掉。
一路修改所有組合語言相關的程式。直到最後一個...
最後一個函式是atol(),這是標準C的函式庫,但原系統就不用標準C的函式庫,而是用一個手寫函式。
問題是它是100%的組合語言,本想改寫,後來就寫成另一個樣子。

原始函式為:
long atol (const char * Str)
{
    asm ("    move.l    `Str`,a0    ; Address of String");
    asm ("    move.l    d2,-(sp)    ; Save D2");
    asm ("    moveq    #0,d0        ; Initialize sum to 0 in D0");
    asm ("    moveq.l    #0,d1");
    asm ("    moveq    #0,d2        ; Assume positive number");
    asm ("    move.l    d0,a1");
    asm ("white:");
    asm ("    move.b    (a0)+,d1    ; Get one char into D1");
    asm ("    cmpi.l    #32,d1        ; Skip leading white spaces");
    asm ("    beq    white");
    asm ("    cmpi.l    #13,d1        ; White space include HT,LF,VT,FF,CR");
    asm ("    bgt.s    sign");
    asm ("    cmpi.l    #9,d1        ; Is it >= tab ?");
    asm ("    bge    white");
    asm ("sign:");
    asm ("    cmpi.l    #43,d1        ; Is there a (+) sign ?");
    asm ("    beq.s    nextc        ; Skip to the next char");
    asm ("    cmpi.l    #45,d1        ; Is it negative ?");
    asm ("    bne.s    digit        ;   No, start to check for digits");
    asm ("    moveq    #1,d2        ; Remember the number is negative");
    asm ("nextc:");
    asm ("    move.b    (a0)+,d1    ; Get next char");
    asm ("digit:            ; Find the first non-zero digit");
    asm ("    subi.l    #48,d1        ; Integer value of this digit");
    asm ("    beq    nextc        ; Skip leading zeros");
    asm ("    bcs.s    return        ; Value is 0, return");
    asm ("    cmpi.l    #9,d1        ; Test for valid digits");
    asm ("    bgt.s    return        ; Value is 0, return");
    asm ("loop:");
    asm ("    add.l    d1,d0        ; Add value of this digit to sum");
    asm ("    move.b    (a0)+,d1    ; Next char");
    asm ("    subi.l    #48,d1        ; Integer value of this digit");
    asm ("    bcs.s    done        ; No more digits");
    asm ("    cmpi.l    #9,d1        ; Test for valid digits");
    asm ("    bgt.s    done");
    asm ("        ; multiply value in D0 by 10 using shifts and add");
    asm ("    add.l    d0,d0        ; Sum * 2");
    asm ("    move.l    d0,a1        ; Save a copy in A1");
    asm ("    lsl.l    #2,d0        ; Sum * 8");
    asm ("    add.l    a1,d0        ; Sum * 10");
    asm ("    bra    loop");
    asm ("done:");
    asm ("    tst.b    d2        ; Is the number negative ?");
    asm ("    beq.s    return");
    asm ("    neg.l    d0");
    asm ("return:");
    asm ("    move.l    (sp)+,d2    ; Restore D2");
}

改寫為
long atol (const char * Str)
{
    register char *a0=(char *)Str;
    register long  d2=0;
    register int   d0=0;
    register int   d1=0;
    register int   a1=0;
White:
    d1 = *a0++;
    if( d1 == ' ') goto White;
    if( d1 > 13  ) goto Sign;
    if( d1 >= 9  ) goto White;
Sign:
    if( d1 == 43 ) goto Nextc;
    if( d1 != 45 ) goto Digit;
    d2 = 1;
Nextc:
    d1 = *a0++;
Digit:
    d1 -= 48;
    if( d1 == 0) goto Nextc;
    if( d1 < 0 ) goto Return;
    if( d1 > 9 ) goto Return;
Loop:
    d0 += d1;
    d1 = *a0++;
    d1 -= 48;
    if( d1 < 0 ) goto Done;
    if( d1 > 9 ) goto Done;
    d0 += d0;
    a1 = d0;
    d0 = d0 << 2;
    d0 += a1;
    goto Loop;
Done:       
    if( d2 == 0 ) goto Return;
    d0 = -d0;
Return:    
    return d0;
}

這是新改函式產生出來的組合語言檔
    XDEF    _atol
    ?type    260,x,'atol',0,1,14336,20,1,259,0
    ?f_x_d    'atol',12,260
_atol:
    ?v_a_d    'Str',4,259
    ?v_l_d    'a0',0,a0,261
    ?v_l_d    'd2',0,d1,20
    ?v_l_d    'd0',0,d3,16
    ?v_l_d    'd1',0,d2,16
    ?v_l_d    'a1',0,d4,16
    ?line    21,30
    lea.l    -12(sp),sp
    movem.l    d2/d3/d4,(sp)
    moveq    #0,d0
    ?line    74,33
    movea.l    16(sp),a0
    ?line    75,23
    moveq    #0,d1
    ?line    76,23
    moveq    #0,d3
    ?line    77,23
    moveq    #0,d2
    ?line    78,23
    moveq    #0,d4
    ?line    80,14
L1:
    move.b    (a0)+,d2
    extb.l    d2
    ?line    81,17
    moveq    #32,d0
    cmp.l    d2,d0
    beq.s    L1
    ?line    82,15
    moveq    #13,d0
    cmp.l    d2,d0
    blt.s    L4
    ?line    83,15
    moveq    #9,d0
    cmp.l    d2,d0
    ble.s    L1
    ?line    85,16
L4:
    moveq    #43,d0
    cmp.l    d2,d0
    beq.s    L7
    ?line    86,16
    moveq    #45,d0
    cmp.l    d2,d0
    bne.s    L9
    ?line    87,10
    moveq    #1,d1
    ?line    89,14
L7:
    move.b    (a0)+,d2
    extb.l    d2
    ?line    91,12
L9:
    moveq    #-48,d0
    add.l    d0,d2
    ?line    92,15
    beq.s    L7
    ?line    93,14
    tst.l    d2
    bmi.s    L12
    ?line    94,14
    moveq    #9,d0
    cmp.l    d2,d0
    blt.s    L12
    ?line    96,12
L14:
    add.l    d2,d3
    ?line    97,14
    move.b    (a0)+,d2
    extb.l    d2
    ?line    98,12
    moveq    #-48,d0
    add.l    d0,d2
    ?line    99,14
    bmi.s    L16
    ?line    100,14
    moveq    #9,d0
    cmp.l    d2,d0
    blt.s    L16
    ?line    101,12
    add.l    d3,d3
    ?line    102,11
    move.l    d3,d4
    ?line    103,16
    lsl.l    #2,d3
    ?line    104,12
    add.l    d4,d3
    ?line    105,13
    bra.s    L14
    ?line    107,15
L16:
    tst.l    d1
    beq.s    L12
    ?line    108,12
    neg.l    d3
    ?line    110,13
L12:
    move.l    d3,d0
    ?line    111,1
    movem.l    (sp),d2/d3/d4
    lea.l    12(sp),sp
    rts
;     code: 124 bytes   stack: 12 bytes
    ?end
    
經比對轉出的組合語言動作符合。然後也可以在Windows系統下順利編譯。
寫完後無聊,用Google找找看有沒有組合語言轉成C語言相關的事。
所得答案是:沒有這種方法。

可是Bee完成了這樣的事!
而且在寫的過程中發現轉換的方法。
大部分組合語言可以轉成單行的C語言。
Bee不去處理程式結構的轉換,所以只要把標記(Label)直接轉成C的標記。
無條件跳越直接可以翻成 goto Label;
比較有問題的是程式控制指令。
做法很簡單,就直接轉成 if() goto Label;
唯一要處理的是if括號內的東西。
括號內的,和上一個指令有關。
上個指令是比較指令,就直接移進括號內。
上個指令不是比較指令,就將有影響的暫存器放入括號內。
一路就做完了,也沒有問題。

沒想到就這樣完成了一個網路找不到答案的問題。
只是確保可以動作,但效率不好。
可以看看翻出來的組合語言,多出了許多動作。
好在只是在Windows上模擬,先可以過再說。還有一堆的問題還要解決啊!


2010年12月1日 星期三

OpenCV2.1+CUDA 64位元整合:結果失敗

  最近Bee換筆記電腦是具有GeForce GT 420M的顯示卡。
  現在都是安裝Windows 7 x64的版本。故Bee下載CUDA 64位元回來安裝。
  到這裡都沒有問題。只有CUDA 64部分設定要自己手工調整。
 
  之後有許多工具都很不習慣,花了不少時間去找。整個Windows和XP實在差太多了。
  另外有一些其他奇怪的地方有些程式找不到裝置,原來還有UAC的問題。
  好吧!看在64位元可以不受4GB限制,還是去適應好了 。

  弄了數週,才想到回來看看CUDA程式。
  結果,CUDA 64無法和Win32的OpenCV做Link。
  而OpenCV沒有64位元的Library。那只好自己編函式庫了。
 
  奇怪的是OpenCV2.1明明就有寫支援64位元,但一直編不出可以用的函式庫。
  查過在其他平台都是可以用的。但在VS2008及VS2010就有問題。
  沒錯!就是這個問題。但....沒有人解成功。
 
  Bee又安裝了好幾次,沒一次成。查了很久,發現是沒有載入該有的函式庫。
  為何!M$的C++老是玩這種,每次編出來的程式都很難搬。
 
  最後沒辦法,回去Win32。安裝CUDA 32然後Link OpenCV,就過了。
  再等OpenCV下一版再看看。
  不過64位元整合算是失敗了。看來時代還沒有到。

  還有很多應用軟體也都是在Win32模式下,沒有幾套是64位元。
  要換到64位元,看來還是不容易取得優勢。反而是環境大改,真是不習慣。