2013年10月19日 星期六

物件導向OOL basic

將大話設計模式作筆記

1.類別是具有相同屬性和功能的抽象集合。

2.實体,就是真實的物件。而實体化就是建立物件的過程。

3.方法重載-提供了建立同名的多個方法的能力,但這些方法需使用不同的參數類型。

   可在不改變原方法的基礎上,新增功能。

4.屬性與修飾子- 屬性是一個方法或一對方法,但在調用它的程式碼看來,它是一個欄位,即屬性適合於以欄位的方法使用方法調用的場合。;屬性有二個方法 get 和 set。 get存取器返回與宣告的屬性相同的資料類型,表示的意思是調用時可以得到內部欄位的值或參考:set存取器沒有顯式設定參數,為穩式參數value,它的作用是調用屬性時,可以給內部欄位。

欄位-是類別相關的變數。

5.封裝-物件特性(封裝' 繼承及多型) 。每個物件都包含它進行操作所需要的所有資訊,這個特性稱為封裝,因此物件不必依賴其它物件來完成操作。

A.良好的封裝可減少耦合。

B.類別內容的實現可以自由地修改.

C.類別有清晰的對外介面。

5.繼承-物件繼承是代表一種"is -a"的關係,如果二個物件A和B,可以描述為"B是A",則表明B可以繼承A。

  繼承者可理解為被繼承者的特殊化,因為它除了具備被繼承者的特性外,還具備自己的特性。

  A.子類別別擁有父類別非private的屬性和功能。

  B.子類別具有自己的屬性及功能,即子類別可以擴展父類別沒有的屬性和功能。

  C.子類別還可以用自己的方式實現父類別的功能(方法重寫)。

  D.在C#中,子類別可從父類別中繼承的成員有方法, 欄位, 屬性,事件,索引。 但對建構式,是不能被繼承的。而若要調用父類別的成員,可用 base(ex, base(element))

  E.缺點: 繼承會破壞包裝,增強了類別間的耦合性。故只有在二個有"is a"下才可使用。

6.多型:

  表示不同的物件可以執行相同的動作,但要透過它們自己的實現的程式碼來執行。

  A.子類別是以父類別的身份出場。

  B.子類別在工作時以自己方式來實現

  C.子類別以父類別出現(宣告時),子類別的特有的屬性及方法不可使用。

  D.虛擬方法和方法重寫: 為了使子類別的實体完全地接替來自父類別的類別成員,父類別必須將成員宣告成虛擬的。這是在讓成員的返回類型之前加上virtual。 而虛擬化,除了欄位不可以外其它均可的。也可以在虛擬成員中加入 而虛擬化,除了欄位不可以外其它均可的。也可以在虛擬成員中加入實体(實際的內容): 而方法重寫則是以override 來把父類別中的替換成自己的。

7.抽象類別:

  把實体化沒有意義的父類別,改成抽象abstract化(也可將方法抽象)。

  A.抽象類別不能實体化。

  B.抽象方法必須被子類別重寫。

  C.若類別中"有任一方法"是抽象則其類別也必為抽象。

  抽象方法和虛擬方法,?(擁有盡可能多的共同程式碼; 也擁有盡可能少的資料)

  D.抽象類別代表了一個抽象楖念,它提供了一個繼承的出發點,當設計成抽象時,一定是用在被繼承。

     樹技和樹葉.

8.介面:

   讓三個特殊類別具有特別的方法.

   把穩式公共方法和屬性組合起來,以封裝特別功能的一個集合。一旦類別實現了介面,類別就可以支援介面所指定的所有屬性和成員。宣告介面在語法上和抽象類別相同,但不允許提供介面中任何成員的執行方式(也不能實体化,建構式和欄位)。

在繼承介面的類別中,必須去實作其介面interface中的所有方法及屬性(get ,set)

  介面和抽象:

  A.一個類別可繼承多個介面,但只能一個抽象。

  B.抽象是可以給出一些成員的實現,介面卻不包含成員的實現,抽象類別中"抽象成員"才可被子類別部份實現。介面則需繼承的類中完全實現。

  C.抽象類別是對物件抽象; 介面則是對行為抽象。

  D.對不同類別的物件,可使用介面; 同一類似的則用抽象.

9.集合和泛型:

   集合, .Net Framework提供了用於資料儲存和檢索引的專用類別。提共了堆疊,佇列及雜湊表的支持。 且有相同的介面。

   ArrayList。不會去檢查其加入的類別型態,且在包/解 包裝,需大量資源。所以才有泛型

 

10.委託與事件: 

   委託是對函數的封裝,可以當作給方法的特徵指定一個名稱。 而事件則是委託的一種特殊的形式, 當有發生有意義的事情時,事件物件處理通知過程。

委託是一種參考方法的類型。一旦為委託分配了方法,委託將與該方法有完全相同的行為。委託物件利用delegate來宣告,而事件是說在發生其它類別或物件關注的事情時,類別可以透過事件通知。

using System;
using System.Collections.Generic;
using System.Text;
 
namespace 動物練習
{
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat("Tom");
            Mouse mouse1 = new Mouse("Jerry");
            Mouse mouse2 = new Mouse("Jack");
            cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
            cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
 
            cat.Shout();
 
            Console.Read();
        }
    }
 
    //無參數委託事件
    //class Cat
    //{
    //    private string name;
    //    public Cat(string name)
    //    {
    //        this.name = name;
    //    }
 
    //    public delegate void CatShoutEventHandler();
    //    public event CatShoutEventHandler CatShout;
 
    //    public void Shout()
    //    {
    //        Console.WriteLine("喵,我是{0}.", name);
 
    //        if (CatShout != null)
    //        {
    //            CatShout();
    //        }
    //    }
    //}
 
    //class Mouse
    //{
    //    private string name;
    //    public Mouse(string name)
    //    {
    //        this.name = name;
    //    }
 
    //    public void Run()
    //    {
    //        Console.WriteLine("老貓來了,{0}快跑!", name);
    //    }
    //}
 
    //有參數委託事件
    class Cat
    {
        private string name;
        public Cat(string name)
        {
            this.name = name;
        }
 
        public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs args);
        public event CatShoutEventHandler CatShout;
 
        public void Shout()
        {
            Console.WriteLine("喵,我是{0}.", name);
 
            if (CatShout != null)
            {
                CatShoutEventArgs e = new CatShoutEventArgs();
                e.Name = this.name;
                CatShout(this, e);
            }
        }
    }
 
    public class CatShoutEventArgs : EventArgs
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
 
    class Mouse
    {
        private string name;
        public Mouse(string name)
        {
            this.name = name;
        }
 
        public void Run(object sender, CatShoutEventArgs args)
        {
            Console.WriteLine("老貓{0}來了,{1}快跑!", args.Name, name);
        }
    }
}

設計模式

化苦為花.

所謂的設計模式,即是指物件導向(Object-Oriented Programming Language)。

所不論是以何種語言實作(C++,Jave,C #, .Net)其核心就是"抽象".

 

而這個對於我們這種搞C的黑手,到底又是如何?

(話說最近的案子,用到Apple 的iOS,Bluetooth而且還得自己寫application(app)

反而不去k 他們的底層東西。去用app真是莫明其妙。

即時要學object-C...就是物件C啊。

讓自己進步就是K 底層的東西,而不是學個一招半式。到頭來還是沒用的)

雖然我也是要必須一套的OO語言,但一直都沒有去決定.,原因是沒時間及精力。

 

在開發專案時,因時間/市場/金錢下,

什麼夠用就好;是啊。但你永遠都不夠用的。而且這應該是在有強大的基礎下才行.

回到原點,討論C與OO。我該如何學習(目標時間結果)

1.目標;

學習C和OO之間該如何結果(抽象化)

及結合嵌入式系統或是任一種的圖形界面程式。

2.時間;因為OO的學習太大了,

             所以應該是定出目標(長,中及短)再去決定時間。

  1.短: K 大話設計模式及做筆記。1~3M

  2.中:學習用C及OO的某一FrameWork.2~3M

  3.長:這應該是一直都要做,一邊學一邊寫入目前的嵌入式中。~~

最後,我採取用GTK。

 

擷取一些討論及內容:

我想知道的是: 基於什麼原因你要用 C 來作 C++ 的 OO 特性?
程式語言只是個工具. 不同的程式語言是用來以不同的角度來解決不同的問題.
如果你覺得你的問題需要用 OO 來做比較適合, 而且目標系統上也有 C++ 編譯器, 那為什麼不用 C++?
如果因為某些原因你無法用 C++, 只能用 C, 那你就要換個設計, 用 非-OO 的方法來解決你的問題. 非-OO 的方法可能沒有那麼適合, 但大多數的情況下, 應該好過用語言 A 去模擬語言 B 的特性.

 

c有辦法寫成物件導向嗎?
當然可以,但是C語言有自身的限制,例如編譯器不允許函式名稱重複,所以無法模擬overloading;此外,有關簽名的應用(尤其是constructor)部分,也因這相同的原因,無法實作。諸如此類的限制,讓許多原本可用C++輕鬆撰寫的程式,變得舉步維艱、哀苦連天!等等!在C++擁護者點頭如擣蒜前,我得趕緊提出一個問題:使用constructor、 overloading等語法的程式,"才是"物件導向程式設計嗎?這跟使用C語言,就"一定"是結構化程式設計一樣,是很弔詭的說法。
軟體工程的誕生,是很實際的、想要解決程式設計師的困境:當程式碼大到一個規模後、進度愈難掌控(請各位算算VISTA延淌了多久)!而當我們談到物件、封裝、抽象化等、這些軟體工程的重要理論時,其實他們表達的是同一個簡單的概念,那就是資訊隱藏。簡單的說,只要工程師越不瞭解細節,系統就越穩定!怪哉,真有這麼神奇嗎?
我記得剛接觸程式時,幾乎身邊的每個軟體工程師,都有一本所謂的BIBLE書。我當然也不例外,手上有一本TURBO-C的寶典,內容其實是將所有TC所支援的函式、全部分類說明,並提供使用範例(內附1.44M磁碟片)。在這樣的環境下,工程師習慣於"程序性"的解題思考,同樣地,對於所有熟悉ANSI-LIB(或Windows API)的人來說,其實也很容易的、陷入這樣的思維:用程序(函式)的組合來解決問題。這正是大力鼓吹結構化程式設計的年代,只要有一點年紀的工程師,都應該經歷過,只是,當時少有人去質疑這樣的正確性罷了。說起來,很幸運的,我在大約15年前,還是個程式菜鳥的時候,就已經見識到OO的思維了。在那個時代並沒有C++,所以程式碼全都是C語言所撰寫的,而我們老大所寫的程式碼,其實就是本篇的回應:用C語言撰寫物件導向的程式。事隔多年,我無法找出當時的程式碼,但我仍記得他巧妙的運用member function、將其物件化的的手法。在那個時代,研發單位有一半僅是專科的學歷(包括我),但動腦筋的功夫卻很了得是也。這就叫臥虎藏龍嗎?(對不起、軍曹看多了)
有感而發的跟各位先進分享,希望對大家有幫助。我個人用C語言寫了許多物件導向的程式(是有商品化的產品)應用,著重在繼承、template等應用上。至於為什麼不用C++呢?喔!在嵌入式的領域,C++還沒有這麼普及啦。

 

 

參考:

大語設計模式

Object-C

http://zh.wikipedia.org/zh-tw/Objective-C

c有辦法寫成物件導向嗎?

http://www.programmer-club.com/ShowSameTitleN/c/36555.html

以 C 語言實作物件封裝

http://ccckmit.wikidot.com/cp:encapsulation

不要從程式語言學習「物件導向」

http://www.kenming.idv.tw/ac_eb_af_cu_af_eo_eu_ascci_a_c_carpad_a

Ubuntu 下的哈囉!GTK+!

http://www.javaworld.com.tw/roller/caterpillar/entry/ubuntugtk

Can you write object oriented code in C?

http://stackoverflow.com/questions/351733/can-you-write-object-oriented-code-in-c

2013年9月25日 星期三

2013年8月30日 星期五

SPI(Serial Peripheral Interface)

Overview

  • Serial interface
  • Synchronous
  • Master-Slave
  • Data Exchange

其中Synchronous protocol

  1. 資料沿著clock(SCK)來傳送
  2. 當data 需改變及被讀取時,對clock 控制
  3. 因為是同步(synchronous),所以化的clock rate是可變的,不像RS-232等的通訊

Master-Slave protocol

  • 只有一個master可以去控制SCK(clock)
  • 直到其clock signal 出現才可以傳送資料
  • all slave 都是由master clock來控制
  • slave device 可能不會去管clock

Data Exchange protocol

  • data is being clocked out,new data is clocked in
  • data is exchanged-no device is only transmitter or receive only
  • the master controls the exchange by the clock line

它在"transmits" data一筆後,必先去讀取進來的資料,若進來的資料不可讀時

這一筆的資料,就會loss並且其SPI module變成disable as result.

 

SS(CS) pin define: Slave Select/Chip Select. the master wisch to staart an SPI data exchange between that slave device and itself.

it often used to improve noise (to reset the SPI slave so that it is ready to receive the next byte)

 

Data(MOSI/MISO): data is only output during the rising or falling edge of SCK.

而data會在相對的負edge(+->-)來latche;並確認資料正確後讀取

image

pin descritor:

SS(chip Select or Slave Select):

when this signal go to low ,the slave will listend for SPI clock and data

SCK(serial clock):

to control when data in/out

SDO(serial data out):

this signal carries the data sent out of the device.

SDI(serial data input):

this signal carries the data sent into the device.

image

image

SSPSR (shift register) for SPI module. it shift data in and out of the device . the data travels in a loop to the next shift register

image

image

 

image

image

 

74HC595+ SPI =expander(output)

&4HC165+SPI=

自強基金協會-上課心得Stellaris EKS_LM3S3748

image

image

image

image

image

image

image

image

image

 

其中,特別的是為了可以在多個開發工具(不同cpu/compiler..)

將其環境,以bat file 來加以設定.而非固定

path=C:\Program Files\Putty;%path%

set MCU_ROOT=c:
path=%MCU_ROOT%\UnxUtils\winXpBin;%MCU_ROOT%\UnxUtils\bin;%MCU_ROOT%\UnxUtils\usr\local\wbin;%path%

path=C:\Program Files\CodeSourcery\Sourcery_CodeBench_Lite_for_ARM_EABI\bin;%path%

ARM的定址與組合語言

ARM的定址:

在ARM中運算方式是採用Load/Stor架構

(即其運算,需先放在暫存器中且結果也是)

image

image

  • 立即定址:
    • 即其運算元本身即為其資料。故取出指令也就取得運算元.
    • ADD R3,R3,#1 ;R3=R3+1
    • ADD R8,R7,#&ff ;R8=R7[7:0]
    • 是"#"為頭開.十六進位為在"#"後加0x or &
  • 暫存器定址:
    • 以暫存器中的內含值作為運算元。
    • ADD r1,r2,r3 ;r1=r2+r3
  • 暫存器間接定址:
    • 以暫存器中的數值作為運算元的位址,而真正的運算元放在"memory"
    • ADD r0,r1,[r2] ;r0=r1+[r2]
    • Ldr r0,[r1] ; r0=[r1]
    • 暫存器間接定址大多使用一個暫存器(基底暫存器)的數值作為記憶体的位址.
  • 基底定址:
    • 將暫存器(基底)的內容與指今中所給多的位址偏移量加以相加,並進而得到一個運算元的有效位址
    • LDR r0,[r1,#4] ; r0=[r1+4]
    • 用來處理基底附近的記憶体,基底加偏移量:前索引(pre-index)和後索引(基底+索引定址)
    • "暫存器間接定址[]"是移移量為0的氐加上偏移定址 ;"基底加偏移[,#]"定址中基底暫存器包含的並非是確定位址,基底需加(減)若干偏移量(max 4KB)來計算所要處理的位址。
    • 除了找到基底定址所指資料外,還可改為基底暫存器內容
    • LDR r0,[r1,#4]! ;r0=[r1+4],r1=r1+4,以"!"表示在完成資料傳送後,同時更新基底暫存器內容.
    • 前索引 [r1,#4] ;後索引[r1],#4。
    • 後索引:基底不包今偏移量來做傳送的位址,且再傳送後,自動加上索引
    • LDR r0,[r1],#4 ;r0=[r1],r1=r1+#4
    • image
  • 相對定址:
    • 以PC計數暫存器為基底,而指今中的位址作為偏移量來得到有效位址
    • BL Next
    • …
    • Next
    • …
    • mov pc,lr
  • 多暫存器定址:
    • 一個指今完成多個暫存器的傳送
    • LDMIA R0,{R1,R2,R3,R4}; R1=[R0];R2=[R0+4];R3=[R0+8];R4=[R0+12]
    • 最多可傳16個暫存器及其"IA"為表示在執行完LOAD/STOR後,r0以work增加長度。
  • 堆疊定址:
    • LIFO/FILO
    • 以一個堆疊指標器來指向一塊stack的頂端,並且可分為
      • 向上:向高位址生長,
      • 向下:向低位址
    • 可分為滿遞增(FA)、空遞增(EA)、滿遞減(FD)及空遞減(ED)
    • 要pop, push存取

組合組言:

<opcode>{<cond>}{S} <Rd>,<Rn>,<Shifter-operand>

ADD r0,r1,r2 ; r0=r1+r2 ,no update flage

ADDS r0,r1,r2 ; r0=r1+r2,update flage

ADDCSS r0,r1,r2 ;if C flage set then r0=r1+r2 and update flage

CMP r0,r1 ;update flage based on r0-r1

//---------------

c file

if(z==1) r1=r2+(r3*4) ;

a.ADDS r1,r2,r3,LSL #2 ; r1=r2+r3*4 and update flage

b.EQADDS …; if zero flage is 1

其符號<>: 必存在; {}選擇項

//-----------------

ARM的指令集分為

  • 跳躍指今
  • 資料處理指令
  • 程式狀態暫存器(PSR)處理指令
  • 載入/存回指令
  • 協同處理器指今
  • 例外事件產生指令

 

image

image

image

image

image

 

image

image

image

image

 

image

image

 

image

image

image

 

image

image

image

image

 

image

image

 

image

image

程式狀態暫存器:

image

image

image

image

http://www.slideshare.net/jserv/arm-and-soc-traning-part-ii-system