2009年2月7日 星期六

嵌入式系統工程師應該懂的硬體觀念

嵌入式系統開啟了行動與網路裝置的蓬勃發展,因為裝置的多樣性,開發嵌入式系統涵蓋了軟體和硬體的層面,也可說嵌入式系統是介於軟、硬體間做為兩個領域的橋梁。在我的工作經驗中,曾遇過許多從純軟體領域轉換跑道進入嵌入式系統從事開發工作的工程師,也遇過對韌體有興趣而加入程式設計的硬體工程師。大抵來看,走純軟體的路線又多過純硬體。原因似乎很簡單,因為現在的SOC廠商主打系統與應用路線,幾乎已經包辦了所有硬體工程師該做的事情,不僅提供已經快要算是成品的開發公版,甚至連設計圖、線路圖、BOM表都是直接附送的,就算少部分需要硬體線路的修改,SOC廠商甚至可以搭配外包商,將硬體的問題處理掉。有些做嵌入式系統產品的公司,根本連硬體工程師都沒有,基於這樣的趨勢,有時候嵌入系統產品的公司甚至被稱為軟體公司呢。

因為許多公司根本沒有硬體人員,或只有負責外包的工程師,對從事軟體開發的人來說,具備一些基本的硬體觀念就變的非常重要,那,有哪些是軟體導向的嵌入式系統工程師該知道的呢?基本上有以下幾項:

1. SOC的內部規格

2. 硬體架構圖

3. 隨機取記憶體的規格

4. 快閃記憶體的規格

5. 網路控制器(MAC&PHY)的規格

6. GPIO

7. 處理器的Endianess

8. 資料在記憶體的Alignment

9. 匯流排的規格

10. DMA的規格


1. SOC的內部規格
首先是SOC的內部規格,所謂的SOC,顧名思義就是將許多常用的周邊設計在一個晶片內,因此單一個晶片,本身就已經具備許多系統所需的功能,對軟體工程師來說,理解一個SOC具備哪些能力可以說是最基本的功課,可是仍然有許多軟體工程師從來不去看SOC的規格,造成在大家在溝通時陷入名詞解釋的問題。底下是一個常見的SOC內部規格:
  • Gigabit Ethernet port
  • Integrated DDR2 memory controller
  • 16C550-compatible UART
  • 1 x1 PCI Express port
  • I2C
  • SPI
  • 8 GPIOs
2. 硬體架構圖
接著是硬體的架構圖,通常會以方塊圖(Block Diagram)的方式出現,這樣的一個方塊圖清楚說明這個SOC有的元件,或是將SOC規格所介紹的元件以相對位置的方式說明,以及連接SOC的其他元件。有經驗的工程師大多會從處理器的地方開始著手,畢竟處理器是一個系統的核心,接著再往四周延伸,不外乎就是記憶體的位置以及周邊連接的介面。如果產品需要利用到SATA連接硬碟機,這時候就要特別注意SATA的介面所連接的位置。那麼對軟體的工程師來說這張圖有甚麼作用呢?最大的作用當然就是可以確定當系統由Linux或VxWork啟動之後,哪些裝置應該已經被初始化,進入可以使用的狀態。


3. 隨機取記憶體的規格
對於習慣於軟體開發的工程師而言,很難理解為什麼需要特別了解隨機存取記憶體的規格,通常我們只要把RAM加到主機板上面,作業系統自然就可會把程式載到記憶體執行,DDR1還是DDR2一點關係也沒有。但是在嵌入式系統的環境,很多狀況讓我們必須自己處理硬體的初始化工作,以作業系統或Bootloader而言,錯誤的記憶體控制器設定,可能會讓系統錯誤動作,甚至根本無法執行。另外有些強調網路應用的系統,例如交換器或路由器,特別需要高速的記憶體來存放網路封包,只使用DDR是會影響網路封包的傳輸效能,這時候我們必須使用SRAM輔助,讓網路封包的處理更有效率。尤其是通訊協定方面的工程師,至少也要知道DRAM與SRAM的差異,以及何時該使用DRAM,何時該使用SRAM。

4. 快閃記憶體的規格
一般來說,在嵌入式系統,Linux核心與Bootloader的Binary程式碼是在快取記憶體裝置存放的,快取記憶體又稱為非揮發性的記憶體,意思是說就算電源關閉,存放的資料也不會消失。當我在8051的時代,唯讀記憶體(ROM)是唯一能夠用來存用程式碼的地方,但隨著快閃記憶體的普及,在開發上的彈性已經不是ROM能夠比的上的。快閃記憶體根據應用的差異,又可以分為NOR與NAND兩大類,一般來說NOR比較強調在讀取的能力,如果需要存放較大量或者頻繁讀寫資料的時候,多會採用NAND。至於程式與資料該放在哪裡,軟體工程師也必須要有基本的認識,因為這裡並不打算介紹硬體的規格,只說明軟體工程師該知道的知識,更詳細的硬體說明,等以後有機會再說囉。

5. 網路控制器(MAC&PHY)的規格
現今的嵌入式系統很難不跟網路打交道,於是網路控制器成了基本的配備。以軟體設計的角度來看,不外乎是採用Socket的方式,直接進行網路資料的交換。但是嵌入式系統可不一定都是那麼單純,例如說NAT之類必須處理網路封包的產品,就必須在網路驅動程式裡面加工,讓網路封包有不同的流向,在這樣的環境,軟體設計就必須包含了解網路控制器的動作原理,以及各種暫存器的使用方法。另外,在實際的硬體設計上,網路控制還會包含數位與類比的部分,而且通常這兩個部份是由不同的晶片負責的,必須分別對數位與類比進行各自初始化。

6. GPIO
GPIO稱為通用型的可程式IO,通常純軟體的工程師很少會碰到這種裝置,但是如果是寫BIOS的工程師應該會很熟悉,GPIO簡單來說是提供系統設計時的彈性,有時如果外接裝置能夠發出中斷,我們就可以利用GPIO來當作中斷接收器,這樣就不需要一直的輪詢外接裝置。反過來我們也可以利用GPIO當作發送中斷的通知訊號,讓其他的裝置得到控制的命令。此外,GPIO最常和LED連接,當系統沒有螢幕可以作為訊息輸出的時候,我們就可以利用LED燈號來表示各種狀態。實務上,GPIO的應用必須和硬體配合,當然軟體在設計的時候當然也就必須一起參予搭配。

7. 處理器的Endianess
一個常被忽略的硬體問題是處理器的資料處理方式,尤其是在需要網路傳輸資料的系統,軟體工程師必須特別注意到處理器的Endianess特性。Endianess指的是資料在記憶體的位元順序,依特性常見的可分為Big-endian與Little-endian。Big-endian是指資料的最高位是在記憶體位址最低位址,或說在記憶體中開始存放資料的起始處,而Little-endian則是指資料的最低位元在記憶體的最低位址。要注意的是對記憶體本身來說,是沒有所謂的Endianess的分別,只有處理器才會做資料存放的區分。既然資料在記憶體的存放方式會有差異,當然程式在設計的時候也就必須注意不同平台間資料交換的問題。

8. 資料在記憶體的Alignment
資料的Alignment是指資料存放在記憶體的方式,與系統處理效能有直接關聯,雖然Alignment幾乎都靠編譯器來處理,但在嵌入式系統的環境中,資料往往是從其他的硬體交換過來的,此時記憶體的Aligment問題就顯得更加重要。Alignment是資料對齊的意思,也就是說資料的存取必須遵循一個整數倍的方式才行,例如word的倍數,以一個word是4byte為例,如果資料是從位址非4的整數倍位址開始讀取,因為處理器的特性,讀出得資料可能會包含前一個位址的資料,或者跳過起始的位址,或者必須讀取兩次,然後再將兩個資料合併,以得到正確的結果,不管哪種情況,得到的資料不是錯誤的就是要浪費許多時間。因為資料可能在不同的裝置或系統間移動,不同的Aligment方式就有可能讓資料產生各種錯誤組合,如果太過依賴編譯器處理Aligment的能力,那可能會讓除錯變得很困難。

9. 匯流排的規格
處理器經過匯流排與周邊裝置連接,周邊裝置大抵可用速度來區分差異,所以會有高速匯流排與低速匯流排的分別。對於傳統的軟體設計,匯流排都是由作業系統來處理,很少直接會參與匯流排的動作,但在嵌入式系統,控制匯流排有時候就等於在控制周邊。匯流排有時會也會牽扯到時序與資料快取的機制,這些機制都要透過控制暫存器來設定,硬體的線路只是將必要的周邊接在一起,實際的控制仍然需要軟體搭配。

10. DMA的規格
在先進的系統中,資料的轉移或傳送都必須要依賴DMA,尤其是嵌入式系統的處理器效能通常都不是很高的時候,如果每次資料搬移都需要處理器處理,那處理器也做不了甚麼事情了。使用DMA的時機不見得只有周邊對周邊,有時候只是在記憶體之間移動,也可以利用DMA來處理,有些高效的網路應用系統,會利用DMA來最佳化User Space與Kernel Space之間的資料搬移。對DMA的控制基本上只有幾個動作,設定來源位址與目的位址,設定資料長度以及觸發DMA開始進行資料搬移,最後檢查DMA的動作是否已經完成,檢查的方式大部分會設定中斷,讓DMA控制器以中斷的方式通知系統最後的狀態。

以上說明的,只是入門的嵌入式系統工程師基本應該掌握的硬體知識,從事嵌入式系統開發的工作,最忌諱的就是以純軟體的方式思考系統發展,和硬體緊密結合是嵌入式產品一項獨特的特色,但很少接觸硬體的工程師也不必太擔心,實務上大部分的硬體問題都會由SOC廠商的FAE提供協助,反而軟體工程師最欠缺的是詳細閱讀規格書,或者對規格書的說明不夠了解,對嵌入式系統的有興趣的開發人員要特別注意。