2023年2月5日 星期日

第6隻創作的木雕貓頭鷹

 這次主題是禪坐的貓頭鷹,看起來好像睡著了……

此次同第5隻,將它作成藍牙喇叭,以上6隻到目前總共花了多少業餘時間,真的很難算,前後已經過了一整年。歲月如梭~




以下是總覽:





--> 閱讀更多...

第5隻創作的木雕貓頭鷹

 這次的主題是台灣草鴞,另外刻意將作品的腳設計變短,加強其可愛的表相,並使用藍牙喇叭讓它播放音效。






--> 閱讀更多...

第4隻創作的木雕貓頭鷹

 這次雕的主題是魚鴞,所以頭型會盡可能與魚鴞的頭型類似,再加入自己的想像雕塑而成。






--> 閱讀更多...

第3隻創作的木雕貓頭鷹

 這次選不一樣的類型來雕,並刻意將眼睛斜一邊。我知道,貓頭鷹眼球是無法移動的,它們都是靠更多節的頸椎來轉動脖子來移動視線。

目的是雕出可愛的貓頭鷹,所以我雕的貓頭鷹都不會是用真正的貓頭鷹外型一樣。而是加入自己的想像去雕塑。








--> 閱讀更多...

第二隻創作的木雕貓頭鷹

 功能與第一隻相同,但這隻之前有全身上色,後來發現不喜歡,就全部磨平重雕。感覺還是比較喜歡保留原木的紋路。







--> 閱讀更多...

第一隻創作完成的木雕貓頭鷹

這個作品大約在2022年的5月分就已完成。但由於未上漆,也尚未雷上Logo,因此到今日才放到布blog發表。
功能是只會播放一首曲子,並提供按鈕來操作聲音大小及播放與暫停,以及EQ設定。





 

--> 閱讀更多...

2016年8月16日 星期二

Finger Print 指紋碟 Mac OS X Development

Finger Print  for Mac OS X這樣的產品見過嗎?或許您會說Finger Print 本來就support Mac OS X,然而市售Finger Print指紋碟都有個操作設定介面,否則如何將產品使用者的指紋設定到裝置裡面呢?而這樣的設定介面軟體,目前都是Only for Windows.(改天再來搞各Android版本).
隨身碟的用意就是走到哪用到哪,因為攜帶方便,但若真要隨處可用,軟體本身的支援不夠就等於是跛腳產品。因此今天的主角就是針對指紋碟開發可在Mac OS X操作設定介面的軟體。也就是說我已經完成此產品Mac OS X solution(support:10.7~10.11)的整個專案,在此只記錄一些開發過程又無關機密問題的敘述。
產品連結: RHINO ARMOR犀牛甲指紋辨識碟 USB3.0 64GB (但目前該項產品尚未將 Mac OS X功能整合進去).
操作畫面截圖(screenshot)在OS X El Capitan:



Mac OS X USB SCSI command其實並不完全支援,需另外寫驅動kext,才能使standard SCSI command(Vendor command) 能順利下command到裝置。這部分其實不難,網路上有相關sample code可以參考。討厭的是從OS X 10.10版開始,kext強制要code sign(憑證簽署(就是要成為已付費Develop ID[就是要你付每年100美金]))才能正確載入系統。code signing的過程稍後說明。然而開發階段系統可設定kext-dev-mode,使kext不須憑證仍可被載入系統。切到dev mode,10.10 Yosemite 及10.11 El Capitan作法完全不同,說明如下:
10.10:
    $sudo nvram boot-args= kext-dev-mode=1
10.11:
    先進入Recovery OS Mode,並開啟terminal,輸入如下指令:
    #csrutil disable
    #reboot
然而正規產品release,不可能要求使用者自行切換kext-dev-mode,何況這還會有安全疑慮。

App開發當然使用Xcode,因為Xamarin要錢.
開新專案設定時,記得linking選項加入-framework IOKit -framework CoreFoundation
...改天再續
新增多國語言版本截圖




--> 閱讀更多...

2015年7月21日 星期二

memtest86+ 5.01多核心程式 bug 說明

若使用網路下載usb安裝程式Download - Auto-installer for USB Key (Win 9x/2k/xp/7),製作完成後,開機執行出現測試程式畫面後有2~3秒的時間,若不按F2鍵,其實只是跑單核心程式,但是按F2執行多核程式,發現記憶體只要大於2GB,則到pattern7,block move便當掉了。若你會自行編譯,那就找出4.20版的source code,再比對和5.01版pattern7之間的差異,就可修正這個問題了。若你不執行多核程式測試,其實是沒有這個bug的。針對5.01版已經修完成DOS版本的.exe執行檔,並具備下參數功能,驗證沒有問題,找時間再來說如何實作了…
--> 閱讀更多...

2015年3月9日 星期一

Mint 17.1 32bits下compile memtest86+注意事項

不知道是否是linux kernel 版本號更新還是怎樣,當使用較新版的Mint進行compile memtets86+時,出現#include 找不到。
解決辦法:
sudo apt-get update && sudo apt-get install build-essential linux-headers-$(uname -r)
就搞定了!

另一個問題是,編譯時使用gcc 4.8.2產生的執行檔會當機,因此再使用Synapptic 進行安裝 gcc 4.4版,另外再將makefile :
CC=gcc改成CC=gcc-4.4,重新編譯,就可以了!
--> 閱讀更多...

2012年1月10日 星期二

BCB (Multi-thread)

轉載自http://96katt.blogspot.com/2010/09/bcb-multi-thread.html
單線程就是進程只有一個線程
多線程就是進程有多個線程!!!!
下面是多線程的例子
還在Dos時代,人們就在尋求一種多任務的實現。於是出現了TSR類型的後台駐留程序,比較有代表性的有Side Kick、Vsafe等優秀的TSR程序,這類程序的出現和應用確實給用戶使用計算機帶來了極大的方便,比如Side Kick,我們編程可以在不用進編輯程序的狀態下,一邊編輯源程序,一邊編譯運行,非常方便。但是,Dos單任務操作系統的致命缺陷注定了在Dos下不可 能開發出真正的多任務程序。進入Windows3.1時代,這種情況依然沒有根本的改變,一次應用只能做一件事。比如數據庫查詢,除非應用編得很好,在查 詢期間整個系統將不響應用戶的輸入。
進入了Windows NT和Windows 9x時代,情況就有了徹底的改觀,操作系統從真正意義上實現了多任務(嚴格地說,Win9x還算不上)。一個應用程序,在需要的時候可以有許多個執行線 程,每個線程就是一個小的執行程序,操作系統自動使各個線程共享CPU資源,確保任一線程都不能使系統死鎖。這樣,在編程的時候,可以把費時間的任務移到 後台,在前台用另一個線程接受用戶的輸入。對那些對實時性要求比較高的編程任務,如網絡客戶服務、串行通信等應用時,多線程的實現無疑大大地增強了程序的 可用性和穩固性。
在Windows NT和Windows 9x中,多線程的編程實現需要調用一系列的API函數,如CreateThread、ResumeThread等,比較麻煩而且容易出錯。我們使用 Inprise公司的新一代RAD開發工具C++Builder,可以方便地實現多線程的編程。與老牌RAD工具Visual Basic和Delphi比,C++Builer不僅功能非常強大,而且它的編程語言是C++,對於系統開發語言是C的Windows系列操作系統,它具 有其它編程語言無可比擬的優勢。利用C++Builder提供的TThread對象,多線程的編程變得非常簡便易用。那麼,如何實現呢?且待我慢慢道來, 讓你體會一下多線程的強大功能。
1. 創建多線程程序:
首先,先介紹一下實現多線程的具體步驟。在C++Builder中雖然用Tthread對像說明了線程的概念,但是Tthread對像本身並不完整, 需要在TThread下新建其子類,並重載Execute方法來使用線程對象。在C++Builder下可以很方便地實現這一點。
在C++Builder IDE環境下選擇菜單File|New,在New欄中選中Thread Object,按OK,接下來彈出輸入框,輸入TThread對像子類的名字MyThread,這樣C++Builder自動為你創建了一個名為 TMyThread的TThread子類。同時編輯器中多了一個名為Unit2.cpp的單元,這就是我們創建的TMyThread子類的原碼,如下:
#include
#pragma hdrstop

#include 「Unit2.h」
#pragma package(smart_init)
//────────────────────-
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall MyThread::UpdateCaption()
// {
// Form1->Caption = 「Updated in a thread」;
// }
//────────────────────
__fastcall MyThread::MyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//────────────────────
void __fastcall MyThread::Execute()
{
//──── Place thread code here ────
}
//────────────────────-
其中的Execute()函數就是我們要在線程中實現的任務的代碼所在處。在原代碼中包含Unit2.cpp,這個由我們創建的TMyThread對象就可以使用了。使用時,動態創建一個TMyThread 對象,在構造函數中使用Resume()方法,那麼程序中就增加了一個新的我們自己定義的線程TMyThread,具體執行的代碼就是Execute()方法重載的代碼。要加載更多的線程,沒關係,只要繼續創建需要數量的TMyThread 對象就成。
以上我們初步地實現了在程序中創建一個自定義的線程,並使程序實現了多線程應用。但是,多線程應用的實現,並不是一件簡單的工作,還需要考慮很多使多 個線程能在系統中共存、互不影響的因素。比如,程序中公共變量的訪問、資源的分配,如果處理不當,不僅線程會死鎖陷入混亂,甚至可能會造成系統崩潰。總的 來講,在多線程編程中要注意共享對像和數據的處理,不能忽視。因此,下面我們要講的就是多線程中常見問題:
2. 多線程中VCL對象的使用
我們都知道,C++Builder編程是建立在VCL類庫的基礎上的。在程序中經常需要訪問VCL對象的屬性和方法。不幸的是,VCL類庫並不保證其 中對象的屬性和方法是線程訪問安全的(Thread_safe),訪問VCL對象的屬性或調用其方法可能會訪問到不被別的線程所保護的內存區域而產生錯 誤。因此,TThread對像提供了一個Synchronize方法,當需要在線程中訪問VCL對像屬性或調用方法時,通過Synchronize方法來 訪問屬性或調用方法就能避免衝突,使各個線程之間協調而不會產生意外的錯誤。如下所示:
void __fastcall TMyThread::PushTheButton(void)

{
Button1->Click();
}

void __fastcall TMyThread::Execute()
{
...
Synchronize((TThreadMethod)PushTheButton);
...
}
對Button1-〉Click()方法的調用就是通過Synchronize()方法來實現的,它可以自動避免發生多線程訪問衝突。在 C++Builder中,雖然有一些VCL對象也是線程訪問安全的(如TFont、TPen、TBrush等),可以不用Sychronize()方法對 它們的屬性方法進行訪問調用以提高程序性能,但是,對於更多的無法確定的VCL對象,還是強烈建議使用Synchronize()方法確保程序的可靠性。
3. 多線程中公共數據的使用
程序設計中難免要在多個線程中共享數據或者對象。為了避免在多線程中因為同時訪問了公共數據塊而造成災難性的後果,我們需要對公共數據塊進行保護,直 到一個線程對它的訪問結束為止。這可以通過臨界區域(Critical Section)的使用來實現,所幸的是在C++Builder中,給我們提供了一個TCriticalSection對像來進行臨界區域的劃定。該對像 有兩個方法,Acquire()和Release()。它設定的臨界區域可以保證一次只有一個線程對該區域進行訪問。如下例所示:
class MyThread : public TThread
{
...
private:
TCriticalSection pLockX;
int x;
float y;
...
};
void __fastcall MyThread::Execute()
{
...
pLockX->Acquire();//Here pLockX is a Global CriticalSection variable.
x++;
y=sin(x);
pLockX->Release();
...
}
這樣,對公共變量x,y的訪問就通過全局TCriticalSection 對像保護起來,避免了多個線程同時訪問的衝突。
4. 多線程間的同步
當程序中多個線程同時運行,難免要遇到使用同一系統資源,或者一個線程的運行要依賴另一個線程的完成等等,這樣需要在線程間進行同步的問題。由於線程 同時運行,無法從程序本身來決定運行的先後快慢,使得線程的同步看起來很難實現。所幸的是Windows系統是多任務操作系統,系統內核為我們提供了事件 (Event)、Mutex、信號燈(semaphore)和計時器4種對像來控制線程間的同步。在C++Builder中,為我們提供了用於創建 Event的TEvent 對像供我們使用。
當程序中一個線程的運行要等待一項特定的操作的完成而不是等待一個特定的線程完成時,我們就可以很方便地用TEvent對像來實現這個目標。首先創建 一個全局的TEvent對像作為所有線程可監測的標誌。當一個線程完成某項特定的操作時,調用TEvent對象的SetEvent()方法,這樣將設置這 個標誌,其他的線程可以通過監測這個標誌獲知操作的完成。相反,要取消這個標誌,可以調用ResetEvent()方法。在需要等待操作完成的線程中使用 WaitFor()方法,將一直等待這個標誌被設置為止。注意WaitFor()方法的參數是等待標誌設置的時間,一般用INFINITE表示無限等待事 件的發生,如果其它線程運行有誤,很容易使這個線程死住(等待一個永不發生的事件)。
其實直接用Windows API函數也可以很方便地實現事件(Event)、信號燈(semaphore)控制技術。尤其是C++Builder,在調用Windows API方面有著其它語言無可比擬的優勢。所用的函數主要有:CreateSemaphore()、CreateEvent()、WaitForSingleObject()、ReleaseSemaphore()、SetEvent()等等,這裡就不贅述了。
本文結合Inprise(Borland)公司開發的強大的RAD工具C++Builder的編程,對Windows下的多線程編程作了比較全面的介紹。其實多線程的實現並不神秘,看了本文,你也可以編出自己的多線程程序,真正體會多任務操作系統的威力




如何判斷一個執行緒已經結束
Terminoated可以判斷是否結束運行,如果你的執行緒是自動回收的(加這行FreeOnTerminate=true),那麼結束後將釋放記憶體。否則要用delete。否則可以重新使用,不用new
在程式中如何知道一個執行緒已經結束。例如用Terminated屬性。不過這個屬性是私有的,只能在Excute()中用,在執行緒外部要判斷就不能用他了。在執行緒外部判斷執行緒是否結束, 如果是這樣的話,只有兩種方法:一是你在子執行緒的類中加一個全域變數,在結束前一句上改變它的值,那就可以了。而我覺得更好的方法是在子執行緒結束前,用SenMessagePostMessage 來發送一個自訂的消息。
在執行緒外面可以用GetExitCodeThread看執行緒是否已經退出。

如果你的執行緒是用VCL中的TThread類派生出來的,可以在主程中這樣使用 

主程序: 

TMyThread   *   thread; 

thread   =   new   TMyThread(true);//   創建執行緒並將其設為暫停狀態 
thread   ->   FreeOnTerminate   =   false   ;       執行緒結束後不自動釋放對象 
thread   ->   Resume();                     //   執行執行緒 

... 

thread   ->   Terminate();       //   退出執行緒 
thread   ->   WaitFor();         //   主程序等待中的執行緒結束,後此函數才返回 
delete   thread;                       //   釋放執行緒對象 

執行緒中: 

void   __fastcall   TMyThread::Execute() 
{ 
        while(   !Terminated) 
      { 
              ... 
      } 
}
--> 閱讀更多...

2012年1月5日 星期四

memtest86 4.0a/4.0b(server) 多核心測試軟體(千呼萬喚始出來)

期待已久的多核心測試軟體Memtest86 Original版已經出版,而且還分(工作站/伺服機Server版本),可見不久的未來,Memtest86+版也會update到這個多核心的功能。記憶體容量越做越大,測試時間也會相對的增加,軟體工程早已支援多核心架構,但記憶體測試軟體由於演算法及定址等特殊因素,不能與當下多核心執行架構完全相同,雖然RST已經有釋出多核測試版本。但memtest卻遲遲未跟上。這也不能怪它,畢竟是Free版。雖然目前版本還沒有像Memtest86+可以compile後,加上Exe的執行檔頭,製作程DOS Env下的執行檔,但我覺得這應該不是難事,總之先Try看看,到底時間可以省多少,嚴謹度是否有差異,都是須要作比對分析的。
以下就來說明如何製作成DOS環境下的Exe執行檔:
1.首先我們須先download memtest86+ 4.20版的source code。解壓縮之後呢,找到ma86+_loader.asm並存放到我們現在所要作的memtest86 4.0a版目錄下。
待敘‧‧‧

--> 閱讀更多...

2011年12月7日 星期三

我的CJSCOPE JS-131HR新NB

為什麼會選擇這個牌子ㄋ?當然是為了荷包和性能。就是C/P值啦。目前使用至今算是非常滿意,重量真的很輕(和ULTRA BOOK比也才多個300g)。加到8G的RAM後同時開了3個虛擬機還真是非常順暢,四核心加上HT技術果然和兩年前買的Core 2 Due有明顯的效能差異。編譯linux核心也不用等完喝一杯咖啡的時間。
目前VM都只安裝Oracle VirtualBox,為什麼用它呢?優點說不盡,缺點呢:None.。好比說你已在xp使用多年的軟體,偏偏安裝到64bit的win7或Vista就問題一堆。燒錄軟體、很多Embeded的軟體也都只有for 2k/Xp。這時候你就等於買了一部實體NB,但卻擁有N部虛擬computer,只要你的RAM夠大,同時開10個OS也不怕。所以我目前已經開始再觀察512*8的DRAM IC價格。當它來到了平民價,且品質也趨於穩定就是將我的寶貝增加到16GB的時候了。說真的,玩GAME也用不到那麼多記憶體;若是您有使用VM才會建議將DRAM擴充到那麼大。
總之,花了21k擁有4核的NB,真的只有這一部。若是您考慮的是這個品牌的存續或日後的維修等問題‧‧‧我想這些都是未知數。所以我願意冒這個險。總之我使用的評價就是"爽"。
為了荷包,我也沒有添購正版Win7,所以只用試用版!!!!!
--> 閱讀更多...

2011年11月29日 星期二

x64存儲管理機制初窺

x64存儲管理機制初窺
x64存儲管理機制,經proljmik指點,去找intel手冊和AMD手冊看,看完之後把我的理解寫下,
如有什麼理解偏差之處,還望各位不要笑話。
1.長模式(long mode
   AMD64架構的長模式中包括兩個子模式:64bit模式和compatibility模式。
   64bit模式:在此模式中虛擬位址空間使用平坦(flat)模式,段寄存器包括CS,DS,ES,SS全部清零(FS,GS除外,在線性位址計算時,提供額外base寄存器定址某些OS的系統資料結構),能為64bitOS和應用程式提供64位元定址支援。
   compatiblity模式:在此模式中使用與lagecy保護模式一樣的存儲管理模式,為的是平滑運行32bit16bit的應用程式,無需重新編譯,注意:在長模式中不支援真實模式和虛擬8086模式!!











由於在64bit模式下使用flat模式,所以無lagecy保護模式下的分段管理模式,所以虛擬位址直接對應線性位址。所以x64的分頁管理模式才是64bit下的重頭戲
  
   2.x64分頁管理模式
   如下圖,是x86-64下的所有頁大小和物理位址大小的匯總.










x64下,理論上可以通過使用PAE(實體位址擴充)分頁結構支援64bit的線性位址到52bit物理位址的映射的,但在對這一架構的首次實現中,只實現了48位元的線性位址到40位元物理位址的映射。現在你可以通過CPUID指令查看自己的cpu所支援的最大物理位址(MAXPHYDDR.
   大家一定還記得在lagecy保護模式下通過PAE功能來訪問超過32bit(36bit)的物理位址,但是在x64模式下的PAE與先前的PAE是不一樣的!!
   從線性位址到物理位址的轉換中用到了四級頁資料結構,一個新的頁表資料結構---PML4被引入用來指向頁目錄指標表。PML4只能在x64模式下使用。而且頁目錄表指標從原來的4個項增加到了512個,所以要從線性位址中分配9bit用來索引PDP表(原來是2bit)。
   PDEPTE的大小保持不變。所以我們可以看到PML4+PDP+PDE+PTE+page offset=48bit,高16bit保留(其實是用以符號擴展,下面將看到符號擴展的用途)。
   CR3指向了PML4的基底位址。
   需要注意的是在使用x64模式之前,必須使CR4.PAE=1PAE用來擴展PDEPTE64bit)。如果你在未使CR4.PAE=1之前,企圖開啟x64模式的話,會引發#GP異常。
   我們從上圖還可以看到頁大小的選擇完全取決於PDE.PS(但我並沒有在文檔中看到ps位,是直接在文檔中置10),無視CR4.PSE的存在。
   2.1x64分頁管理(4kb
   上圖再說




















sign extended--符號擴展位元
   PML4 entry--在線性位址3947bit用於索引PML4 entry,指向PDP
   PDP entry--在線性位址的3038bit用來索引PDP entry,指向PDE
   PDE entry--在線性位址的2129bit用來索引PDEentry,指向PTE
   PTE entry--在線性位址的1220bit用來索引PTE entry,指向page offset
   page offset--在線性位址的011bit提供在頁中的offset
   2.2x64分頁管理(2mb




















我們可以看到與4kb的頁相比少了PTE,page offset從原來的12bit增加到了21bit下面我們來看看各分頁表項目的內部結構.
























(4kB)上圖看到,用上述方法可以得到512×512×512×512=2^36個頁面,2^36*4kb=2^48個線性位址.



















上圖看到,用上述方法可以得到512×512×512=2^27個頁面,2^27*2mb=2^48個線性位址 0bitP位,即存在位,表示由項所指的頁面或頁表當前是否載入到了物理記憶體中,如不存在,可以通過引發#PF異常從磁片中載入到物理記憶體中
   1bitR/W,即讀寫位,為頁表指定讀寫特權,當置位時可讀可寫;清零是唯讀
   2bit:使用者/系統位元,即為頁表指定系統還是普通使用者特權
   3bit:頁面通寫,指定快取記憶體寫策略是回寫還是通寫
   4bit:快取記憶體禁止位,當置位元時禁止相關的頁面和頁表進行快取記憶體,反之,可以
   5bit:訪問位,當置位時表示已經被訪問,反之,沒有
   6bit(非PTEPDE2MB)):可用位
   6bitPTEPDE2MB)):D位,dirty,即髒位,置位元時表示頁面被寫過
   78bit(非PTEPDE2MB)):0
   avail:系統程式師可用
   G:全域標誌
   PAT:頁表屬性
   各種base address是用來得到下一級表的基底位址的,最後的物理位址=page base address*2^12(2^21)+2^12(2^21),page base address的大小取決於你的cpu的最大物理位址了。
   3.最後,我來看一看sign extended會形成什麼效果。
   由於sign extended的作用會將線性位址分成相同大小的兩段,從000007FFF`FFFFFFFF,以及從 FFFF8000`00000000FFFFFFFF`FFFFFFFF總計256TB的地址範圍,這非常符合作業系統的習慣。
   這種“古怪”的規則為日後擴展到真正的64位定址保留了一個重要的特性:很多的作業系統(包括但不限於Windows NT系列)將位址空間的高半部分(被稱作內核空間)留給自己,將低半部分(使用者空間)留給應用程式碼、用戶態棧、堆和其他數據區。這種設計保證了每一個符合AMD64的實現都擁有兩個記憶體片段:低半段從00000000`00000000開始,隨著更多的虛擬位址位元變得可用而“向上生長”;高半部分被“懸掛”在位址空間的頂部而“向下生長”。同樣,將未被使用的位址位元內容固定下來防止被作業系統用作標誌位元、特權級標號等其他用途,是為了避免當架構擴展至52,56, 60 64位的時候出現問題。















參考資料:
   1.http://zh.wikipedia.org/zh-cn/X86-64
   2.intel手冊
   3AMD手冊
--> 閱讀更多...