嵌入式系統產品是如何使用Linux

來源:互聯網
上載者:User

 

多數Linux系統是在PC平台上運行,然而Linux作為嵌入式系統也是非常穩定的。本文描繪了一個嵌入式系統的概覽,並展示嵌入式系統產品是如何使用Linux的。

嵌入式系統比摩西還老的故事

  電腦用於控制裝置或嵌入系統的曆史幾乎電腦自身的曆史一樣長。在通訊領域,六十年代晚期,電腦被用於電子電話交換器,稱為“儲存程式控制”系統。“電腦”這詞那時並不普遍,儲存程式指記憶體裝有程式和常式資訊。儲存控制邏輯,而不是將其固化在硬體中,在當時確實是突破性的。今天,我們認為它本來就應如此。

 

 

  那時的電腦是為每一個應用而定製的,按今天的標準,它們是一些不正常的、由奇怪的特殊指令和I/O裝置整合在一部電腦中。

  微處理器通過提供構建大系統模組的小型、低成本、CPU引擎改變了這一切。它提出了外設通過匯流排聯結的固定硬體架構及稱為編程的一般編程模型。

  軟體也隨著硬體提出。最初,編寫和測試軟體只有簡單的編程開發工具。每個項目實際啟動並執行軟體通常來自於草稿的修改。編程常用組合語言或宏語言,因為編譯器常常有缺陷和缺乏完善的調試工具。軟體構建模組和標準化庫只是到了七十年代才流行起來的概念。

  嵌入式系統的商品化作業系統在1970年代後期才出現,許多是用組合語言寫成的,並且只能用於特定的微處理器,當微處理器被淘汰時,它的作業系統除非為新處理器重寫,否則也要被淘汰。今天,許多這類早期的系統成了些模糊的記憶;還有誰記得MTOS嗎?當C語言出現時,作業系統編寫的效率、穩定性、可移植性都提高了很多。這一點在管理上立刻表現出來,它為微處理器被淘汰時保護軟體投資帶來了希望。對於市場來說這是一個好訊息。用C語言寫成的作業系統今天越來越普遍。一般來說,可重複使用的軟體已經佔主導並越做越好。

  在八十年代早期,我最喜歡的作業系統是Wendon作業系統,大約150美元就可以得到一個C源碼庫。它是一個包,你可以通過選擇組件建立自己的作業系統,類似在菜單上點菜。例如,你可以在庫清單上點工作排程安排和記憶體管理方案。 很多嵌入式系統的商品化作業系統是在八十年代出現的。這一熱潮持續到現在,今天,有很多可行的商品化作業系統可供選擇。一些大佬出現了,如VxWorks, pSOS, Neculeus和Windows CE。

  許多嵌入式系統根本沒有作業系統,只有迴圈控制。對於一些簡單裝置這是足夠的,但是隨著系統越來越複雜,作業系統就很必要了或軟體變得不可思議的複雜。不幸的是,有些複雜得可怕的嵌入式系統只因為設計者堅持不要作業系統才那麼複雜。

  漸漸地,更多嵌入式系統需要與各類網路聯結,因此需要網路功能。即便是酒店的門把手也嵌入了微處理器與網路相聯。 對於僅僅是編碼控制迴圈的嵌入式系統,增加網路功能將導致系統複雜程度提高以致要求作業系統。

  除了商品化作業系統,還有大量專用作業系統。其中大部分來自於草案,如CISCO的IOS;還有是從其他動作系統中派生出來的。例如,許多作業系統是從同一版本的Berkeley Unix系統派生,因為它有完整的網路功能。其他是基於主要作業系統的如KA9Q來自Phil Karn。

  Linux作為嵌入式系統是一個帶有很多優勢的新成員。它對許多CPU和硬體平台都是可移植的、穩定、功能強大、易於開發。

工具包突破ICE的障礙

  開發嵌入式系統的關鍵的是可用的工具包。像任何工作一樣,好的工具使得工作更快更好。開發的不同階段需要不同的工具。

  傳統上,首先用於開發嵌入式系統工具是內部電路模擬器(ICE),它是一個相對昂貴的組件,用於植入微處理器與匯流排之間的電路中,允許使用者監視和控制微處理器所有訊號的進出。這有點難做,因為它是異體,可能會引起不穩定。但是它提供了匯流排工作的清晰狀況,免了許多對硬體軟體底層工作狀況的猜測。

  過去,一些工作依賴ICE為主要調試工具,用於整個開發過程。但是,一旦初始化軟體對串口支援良好的話,多數的調試可以不用ICE而用其他方法進行。較新的嵌入式系統利用非常清晰的微處理器設計。有時,相應工作初始碼已經有了能夠快速獲得串口工作。這意味著沒有ICE人們也能夠方便地工作。省去ICE降低了開發的成本。一旦串口開始工作,它可以支援各種專業開發工具。

  Linux是基於GNU的C編譯器,作為GNU工具鏈的一部分,與gdb源調試器一起工作。它提供了開發嵌入式Linux系統的所有軟體工具。這有些典型的、用於在新硬體上開發嵌入式Linux系統的調試工具。

1. 寫入或植入引導碼

2. 向串口列印字串的編碼,如“Hello World”(事實上我更喜歡“Watson,Come hre I need you”,電話上常用的第一個詞。)

3. 將gdb目標碼植入工作串口,這可與另一台運行gdb程式的Linux主機系統對話。只要簡單地告訴gdb通過串口偵錯工具。它通過串口與測試機的gdb目標碼對話,你可以進行C原始碼調試,也可以用這個功能將更多的碼載入RAM或Flash Memory中。

4. 利用gdb讓硬體和軟體初始化碼在Linux核心啟動時工作。

5. 一旦Linux核心啟動,串口成為Linux控制口並可用於後續開發。利用kgdb,核心調試版的gdb,這步常常不作要求,如果你與網路聯結,如10BaseT,下一步你可能要啟動它。

6. 如果在你的目標硬體上運行了完整的Linux核心,你可以調試你的應用進程。利用其他的gdb或覆蓋gdb的圖形如xgdb。

什麼是即時系統?

  嵌入式系統常常被錯誤地分為即時系統, 儘管多數系統一般並不要求即時功能。即時是一個相對的詞,純化論者常常嚴格地定義即時為對一事件以預定的方式在極短的時間如微秒作出響應漸漸地,在如此短暫時間間隔內的嚴格即時功能在專用DSP晶片或ASIC上實現了。只有在設計低層硬體FIFO、分散/聚集DMA引擎和定製硬體時才會有這樣的要求。

  許多設計人員因為對真實的要求設有清晰的理解而對即時的要求焦慮不安。對於大多數的系統,在一至五微秒的近似即時響應已經足夠。同樣軟需求也是可以接受的。如 Windows 98 已經崩潰的中斷必須在4毫秒內(±98%)內、或20毫秒(±0)內進行處理。

  這種軟要求是比較容易滿足的,包括環境轉換時間、中斷等待時間、任務優先順序和排序。環境轉換時間曾是作業系統的一個熱門話題。總之,多數 CPU 這些要求處理得很好,而且CPU的速度現在已經快了很多,這個問題也就不重要了。

  嚴格的即時要求通常由中斷常式或其他核心環境驅動程式功能處理,以確保穩定的表現,等待時間,一旦請求出現要求服務的時間很大程度上取決於中斷的優先及其他能暫時掩蓋中斷的軟體。

  中斷必須進行處理和管理以確保時間要求能符合,如同許多其他的作業系統。在IntelX86處理器中,這工作很容易由Linux即時擴充處理。這是提供了一個以背景工作方式運行Linux的中斷處理調度。關鍵的中斷響應不必通知Linux。因此可以得到許多對於關鍵時鐘的控制。在即時控制級和時間限制寬鬆的基本Linux級之間提供介面,這提供了與其他嵌入式作業系統相似的即時架構。因此,即時關鍵代碼是隔開的、並“設計”成滿足要求的。代碼處理的結果是以更一般的方法也許只在應用任務級。

嵌入式系統定義

  一個觀點是如果一個應用沒有使用者介面,它必須是嵌入式的,因為使用者不能直接與之互動。當然這是簡單化的。一個電梯控制的電腦被認為是嵌入式的:按鍵選擇樓層指示燈顯示電梯的停層。對於連網的嵌入式系統,如果系統包含監視和控制的網路瀏覽器,這種界限就更加模糊了。更好些的定義注重系統的集中的功能和主要的目的。

  因為Linux提供了完成嵌入功能的基本的核心和你所需要的所有使用者介面,它是多面的。它能處理嵌入式任務和使用者介面。將Linux看作是連續的統一體,從一個具有記憶體管理、任務切換和時間服務及其他的分拆的、微核心到完整的伺服器,支援所有的檔案系統和網路服務。

一個小型的嵌入式Linux系統只需要下面三個基本元素:

引導工具

Linux微核心,由記憶體管理、進程管理和交易處理構成

初始化進程:

如果要讓它能幹點什麼且繼續保持小型化,還得加上:

硬體驅動程式

提供所需功能的一個或更多應用程式。

再增加功能,或許需要這些

一個檔案系統(也許在ROM或RAM中)

TCP/IP網路堆棧

儲存半過渡資料和交換用的磁碟。

硬體平台

  選擇最好的硬體是一個複雜的工作、充滿了公司其他項目的政治、偏見、傳統,缺乏完整或精確的資訊。 成本經常是關鍵的議題。當考慮成本時、確信你在考慮產品的整個成本、不僅是CPU。有時快的、便宜的CPU一旦加上匯流排邏輯和時延使之與外設一起工作,能變成一個昂貴的狗的產品。如果你在尋找軟體,首先是硬體已經有產品了。如果你是系統設計者,由你決定製定即時的預算及硬體的工作是否滿意。

  現實中需要多快的CPU來完成一項工作,然後放大三倍。奇怪,CPU理論上的速度竟與現實中一樣,別忘了應用程式將會充分利用cache。

  想象匯流排的速度需要多快,如果有其他匯流排如PCI匯流排,包括進來。慢的匯流排或產生DMA阻塞的匯流排會降低CPU的速度造成擁擠。 有整合裝置的CPU是好的,因為只須調試很少的裝置,並且支援通用CPU的驅動程式通常都很容易獲得。在我的項目中,晶片與外設的聯結經常出問題或不滿足我們所需的相容性。因為外設是整合的,不要認為這會便宜。

將10斤重的Linux塞入只能裝5斤的袋中

  對於Linux一個共同的認識是它用於嵌入式系統簡直是神奇極了。這可能不大對,典型的PC上的Linux 對PC使用者來說功能有多。

  對初學者而言,可以將核心與任務分開,標準的Linux核心通常駐留在記憶體中,每一個應用程式都是從磁碟運到記憶體上執行。當程式結束後,它所佔用的記憶體就被釋放,程式就被下載了。

  在一個嵌入式系統裡,可能沒有磁碟。有兩種途徑可以消除對磁碟的依賴,這要看系統的複雜性和硬體的設計。

  在一個簡單的系統裡,當系統啟動後,核心和所有的應用程式都在記憶體裡。這就是大多數傳統的嵌入式系統工作模式,它同樣可以被Linux支援。

  有了Linux,就有了第二種可能性。因為Linux已經有能力“載入”和“卸載”程式,一個嵌入式系統就可以利用它來節省記憶體。試想一個典型的包括一個大概8MB到16MB的Flash Memory和8MB記憶體的系統。Flash Memory可以作為一個檔案系統。Flash Memory驅動程式用來串連Flash Memory和檔案系統。作為替代,可使用Flash Disk。這Flash組件用軟體模擬磁碟。其中一個例是M-Systems的DiskOnChip,可以達到160MB。(http://www.m-systems.com)。所有的程式都以檔案形式儲存在Flash檔案中,需要時可以裝入記憶體。這種動態、“根據需要載入”的能力是支援其它一系列功能的重要特徵:

  它使初始化代碼在系統引導後被釋放。Linux同樣有很多核心外啟動並執行公用程式。這些通常程式在初始化時運行一次,以後就不再運行。而且,這些公用程式可以用它們相互共有的方式,一個接一個按順序運行。這樣,相同記憶體空間可以被反覆使用以“召入”每一個程式,就象系統引導一樣。這的確可以節省記憶體,特別是那些配置一次以後就不再更改的網路堆棧 如果Linux可載入模組的功能包括在核心裡,驅動程式和應用程式就都可以被載入。它可以檢查硬體環境並且為硬體裝上相應的軟體。這就消除了用一個程式佔用許多Flash Memory來處理多種硬體的複雜性。

  軟體的升級更模組化。你可以在系統啟動並執行時候在Flash上升級應用程式和可載入驅動程式。

  配置資訊和已耗用時間參數可以作為資料檔案儲存在Flash上。

非虛擬記憶體

  標準 Linux 的另一個待征是虛擬記憶體的能力。正是這種神奇的特徵使應用程式員可以狂熱的編寫代碼而不計後果,不管程式有多大。程式溢出到了磁碟交換區。在沒有磁碟的嵌入式系統裡,通常不能這麼做。

  在嵌入式系統裡不需要這種強大的功能。實際上,你可能不希望它在即時的關鍵系統裡,因為它會帶來無法控制的時間因素。這個軟體必須設計得更加精悍,以適合市面上實體記憶體,就象其它嵌入式系統一樣。

  注意由於CPU的原因,通常在Linux中儲存虛擬記憶體代碼是明智的,因為將它清除很費事。而且還有另外一個原因是它支援共用文本,這樣就可以使許多程式共用一個軟體。沒有這個,每一個程式都要有它自己的庫,就象printf一樣。

  虛擬記憶體的調入功能可以被關掉,只要將交換空間的大小設定為零。然後,如果你寫的程式比實際的記憶體大,系統就會當作你的運行用盡了交換空間來處理;這個程式將不會運行,或者malloc將會失靈。

  在許多CPU上,虛擬記憶體提供的記憶體管理可以將不同程式分開,防止它們寫到其它地址的空間上。這在嵌入式系統上通常不可能,因為它只支援一個簡單、扁平的地址空間。Linux的這種功能有助於其發展。它減少了胡亂的編寫程式造成系統崩潰的可能性。許多嵌入式系統基於效率方面的原因有意識使用程式間可以共用的“全域”資料。這也可以通過Linux共用記憶體功能來支援,共用的只是指定的記憶體部分。

檔案系統

  許多嵌入式系統沒有磁碟或者檔案系統。Linux不需要它們也能運行。如前所述,應用程式任務可以和核心一起編寫,並且在引導時作為一個影像載入。對於簡單的系統來說,這就夠了。然而,它缺乏前面所說的靈活性。

  實際上,許多商業性嵌入式系統,提供檔案系統作為選項。許多或者是專用的檔案系統或者是MS-DOS-Compatible檔案系統。Linux提供MS-DOS-Compatible檔案系統,同時還有其它多種選擇。之所以提供其它選擇是因為它們更加強大而且具有容錯功能。Linux還具有檢查和維護的功能,商業性供應商往往不提供這些。這對於Flash系統來說尤其重要,因為它是通過網路更新的。如果系統在升級過程中失去了能力,那它就沒有用了。維護的功能通常可以解決這類問題。

  檔案系統可以被放在傳統的磁碟機、Flash Memory或其它這類的介質上。而且,用於暫時儲存檔案,一個小RAM盤就足夠了。Flash Memories被分割成塊。這些塊中也許包括一個含有當CPU啟動時啟動並執行最初的軟體的引導塊。這可能包括Linux 引導代碼。剩餘的Flash可以用作檔案系統。Linux的核心可以通過引導代碼從Flash複製到RAM,或者還有一個選擇,核心可以被儲存在Flash的一個獨立部分,並且直接從那裡執行。

  另外對於一些系統來說還有一個有趣的選擇,那就是將一個便宜的CD-ROM包含在內。這比Flash Memory 便宜,而且通過交換CD-ROM支援簡單的升級。有了這個,Linux 只要從 CD-ROM上引導,並且象從硬碟上一樣從CD-ROM上獲得所有的程式。

  最後,對於連網的嵌入式系統來說,Linux 支援NFS(Network File System)。這為實現連網系統的許多增值功能開啟了大門。第一,它允許通過網路上載入應用程式。這是控制軟體修改的基礎,因為每一個嵌入式系統的軟體都可以在一個普通的伺服器上載入。它在啟動並執行時候也可以用來輸入或輸出大量的資料、配置和狀態資訊。這對使用者監督和控制來說是一個非常強大的功能。舉例來說,嵌入式系統可以建立一個小的RAM磁碟,包含的檔案中有與目前狀態資訊同步的內容。其它系統可以簡單的把這個RAM磁碟設定為基於網路的遠程磁碟,並且空中存取狀態檔案。這就允許另一個機器上的Web伺服器通過簡單的CGI Script存取狀態資訊。在其它電腦上啟動並執行其它應用程式套件組合可以很容易的存取資料。對更複雜的監控,應用程式套件組合如Matlab(http://www.mathworks.com/products/matlab/),可以用來在操作員的PC或工作站的提供系統啟動並執行圖形展示。

引導LILO和BIOS在哪裡

  當一個微處理器第一次啟動的時候,它開始在預先設定的地址上執行指令。通常在那裡有一些唯讀記憶體,包括初始化或引導代碼。在PC上,這是BIOS。它執行了一些低水平的CPU初始化和其它硬體的配置。BIOS 繼續辨認哪個磁碟裡有作業系統,把作業系統複製到RAM並且轉向它。實際上,這非常複雜,但對我們的目標來說也非常重要。在PC上啟動並執行Linux依靠PC的BIOS來提供這些配置和OS載入功能。

  在一個嵌入式系統裡經常沒有這種BIOS。這樣你就要提供同等的啟動代碼。幸運的是,嵌入式系統並不需要PC BIOS 引導程式那樣的靈活性,因為它通常只需要處理一個硬體的配置。這個代碼更簡單也更枯燥。它只是一指令清單,將固定的數字塞到硬體寄存器中去。然而,這是關鍵的代碼,因為這些數值要與你的硬體相符而且要按照特定的順序進行。所以在大多數情況下,一個最小的通電自檢模組,可以檢查記憶體的正常運行、讓LED閃爍,並且驅動其它必須的硬體以使主Linux OS啟動和運行。這些啟動代碼完全根據硬體決定,不可隨意移動。

  幸運的是,許多系統都有為核心微處理器和記憶體所定製的菜單式硬體設計。典型的是,晶片製造商有一個樣本主板,可以用來作為設計的參考或多或少與新設計相同。通常這些菜單式設計的啟動代碼是可以獲得的,它可以根據你的需要輕易的修改。在少數情況下,啟動代碼需要重新編寫。 為了測試這些代碼,你可以使用一個包含‘類比記憶體’的電路內建模擬器,它可以代替目標記憶體。你把代碼裝到模擬器上並通過模擬器調試。如果這樣不行,你可以跳過這一步,但這樣就要一個更長的調試周期。

  這個代碼最終要在較為穩定的記憶體上運行,通常是Flash或EPROM晶片。你需要使用一些方法將代碼放在晶片上。怎麼做,要根據“目標”硬體和工具來定。

  一種流行的方法是把Flash或EPROM晶片插入EPROM或Flash燒制器。這將把你的程式“燒”(存)入晶片。然後,把晶片插入你的目標板的插座,開啟電源。這個方法需要板上配有插座,但有些裝置是不能配插座的。 另一個方法是通過一個JTAG介面。一些晶片有JTAG介面可以用來對晶片進行編程。這是最方便的方法。晶片可以永遠被焊在主板上,一個小電纜從板上的JTAG連接器,通常是一個PC卡,聯到JTAG介面。下面是PC運行JTAG介面所需的一些慣用程式。這個裝置還可以用來小量生產。

健壯性比政治家的承諾更可靠

  在PC硬體上運行時,Linux是非常可靠和穩定的,特別是和現在流行的一些作業系統相比。嵌入式核心本身有多穩定呢?對大多數微處理器來說,Linux非常好。移植到新微處理器家族的Linux核心運行起來與本微處理器一樣穩定。它經常被移植到一個或多個特定的主板上。這些板包括特定的外圍裝置和CPU。

  幸運的是,許多代碼是與處理器的,所以移植集中在差異上。其中大多數是在記憶體管理和中斷控制領域。一旦成功移植,它們就非常穩定。前面我們討論過,引導策略廣泛依賴於硬體要求,而且你必須有計劃地做一些定製的工作。

  裝置驅動程式更加混亂:有些穩定有些不穩定。而且選擇很有限;一旦你離開了通用的PC平台,你需要自己編寫。幸運的是,周圍有許多驅動程式,你可能可以找到一個與你的需求相近的修改一下。這種驅動程式介面已定義好。許多類的驅動程式都非常相近,所以把磁碟、網路或一系列的連接埠驅動程式從一個裝置移植到另一個裝置上通常並不難。我發現許多驅動程式都寫得很好,很容易理解,但你還是要準備一本關於核心結構的書在手頭。 依我的經驗,Linux至少和我用過的著名的商業性作業系統一樣穩定。總之,這些作業系統和Linux的問題在於對工作過程微秒之處的誤解,而不在於代碼的難度或基本的設計錯誤。任何作業系統都有很多爭論不休的故事,這裡不需要重複。Linux的優勢在於原始碼是公開、注釋清晰和文檔齊全的。這樣,你就可以控制和處理所出現的任何問題。

  伴隨著基本核心和驅動程式,還有其它問題。如果系統有一個硬碟, 那麼檔案系統的可靠性就成問題。我們有用磁碟進行Linux系統設計超過兩年的經驗。這些系統幾乎從未正常關閉過。電源隨時都可能被中斷。感覺非常好,使用的是標準(EXT2)檔案系統。標準Linux初始化指令碼運行fsck程式,它在檢查和清除不穩定的inodes方面非常有效。將預設的每隔30秒運行更新程式改為每隔5或10秒運行是比較明智的。這樣縮短了資料在進入磁碟之前,待在高速緩衝儲存空間內的時間,降低了遺失資料的可能性。

如何發展

  嵌入式Linux的確有它的缺陷。比如,雖然它並不比某些商業競爭者差多少,但它的確是個貪婪的儲存空間。這可以通過減少一些不必要的功能來彌補,但這可能會花很長的時間,而且如果不仔細的話,還可能帶來很大的困擾。

  許多Linux的應用程式都要用到虛擬記憶體,在許多嵌入式系統中,是沒有價值的,所以不要以為一個沒有磁碟的嵌入式系統可以運行任何Linux應用程式。

  核心調試工具都不怎麼好,特別是在較底層的。kgdb可以使錯誤定位非常容易,你只要重新啟動。不幸的是,列印語句更麻煩。

  然而,對我來說最糟糕的是心理上的問題。Linux非常的靈活。嵌入式系統總的來說卻不靈活;而且它們完全是為最有效實現預定功能而嚴格設計的。現在的趨勢是保持靈活性、保持總體目標功能、盡量少做修改。這個目標是崇高的,但是,所付出的代價將是針對具體的工作做出巨大的調整。保持靈活性將導致額外的工作,帶著額外的軟體包,而且有時還要降低效能。一個反覆出現的例子就是配置。考慮在一個網路介面配置IP地址,這通常是通過從啟動 script上運行ifconfig程式來完成的。這是一個28K的程式,從設定檔上調用資料,可以用幾行代碼代替,初始化合適的結構。然而,即使這非常合理,但它仍然有害,因為它用一種從未使用過的方法扭曲了軟體。

  Linux在嵌入式系統中的應用是可行的。它有用、可靠。它的發展成本和替代者一致。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.