??????? 如何開發(fā)自己的嵌入式系統(tǒng)
嵌入式系統(tǒng)的悠久歷史
電腦用于控制設(shè)備或嵌入系統(tǒng)的歷史幾乎電腦自身的歷史一樣長(zhǎng)。在通訊領(lǐng)域,六十年代晚期,電腦被用于電子電話交換機(jī),稱為“存儲(chǔ)程序控制”系統(tǒng)?!半娔X”這詞那時(shí)并不普遍,存儲(chǔ)程序指內(nèi)存裝有程序和例程信息。存儲(chǔ)控制邏輯,而不是將其固化在硬件中,在當(dāng)時(shí)確實(shí)是突破性的。今天,我們認(rèn)為它本來就應(yīng)如此。
那時(shí)的電腦是為每一個(gè)應(yīng)用而定制的,按今天的標(biāo)準(zhǔn),它們是一些不正常的、由奇怪的特殊指令和I/O設(shè)備集成在一部電腦中。
微處理器通過提供構(gòu)建大系統(tǒng)模塊的小型、低成本、CPU引擎改變了這一切。它提出了外設(shè)通過總線聯(lián)接的固定硬件架構(gòu)及稱為編程的一般編程模型。
軟件也隨著硬件提出。最初,編寫和測(cè)試軟件只有簡(jiǎn)單的編程開發(fā)工具。每個(gè)項(xiàng)目實(shí)際運(yùn)行的軟件通常來自于草稿的修改。編程常用匯編語言或宏語言,因?yàn)榫幾g器常常有缺陷和缺乏完善的調(diào)試工具。軟件構(gòu)建模塊和標(biāo)準(zhǔn)化庫只是到了七十年代才流行起來的概念?! ?
嵌入式系統(tǒng)的商品化操作系統(tǒng)在1970年代后期才出現(xiàn),許多是用匯編語言寫成的,并且只能用于特定的微處理器,當(dāng)微處理器被淘汰時(shí),它的操作系統(tǒng)除非為新處理器重寫,否則也要被淘汰。今天,許多這類早期的系統(tǒng)成了些模糊的記憶;還有誰記得MTOS嗎?當(dāng)C語言出現(xiàn)時(shí),操作系統(tǒng)編寫的效率、穩(wěn)定性、可移植性都提高了很多。這一點(diǎn)在管理上立刻表現(xiàn)出來,它為微處理器被淘汰時(shí)保護(hù)軟件投資帶來了希望。對(duì)于市場(chǎng)來說這是一個(gè)好消息。用C語言寫成的操作系統(tǒng)今天越來越普遍。一般來說,可重復(fù)使用的軟件已經(jīng)占主導(dǎo)并越做越好?! ?
在八十年代早期,我最喜歡的操作系統(tǒng)是Wendon操作系統(tǒng),大約150美元就可以得到一個(gè)C源碼庫。它是一個(gè)包,你可以通過選擇部件建立自己的操作系統(tǒng),類似在菜單上點(diǎn)菜。例如,你可以在庫清單上點(diǎn)工作排程安排和內(nèi)存管理方案。 很多嵌入式系統(tǒng)的商品化操作系統(tǒng)是在八十年代出現(xiàn)的。這一熱潮持續(xù)到現(xiàn)在,今天,有很多可行的商品化操作系統(tǒng)可供選擇。一些大佬出現(xiàn)了,如VxWorks, pSOS, Neculeus和Windows CE。
許多嵌入式系統(tǒng)根本沒有操作系統(tǒng),只有循環(huán)控制。對(duì)于一些簡(jiǎn)單設(shè)備這是足夠的,但是隨著系統(tǒng)越來越復(fù)雜,操作系統(tǒng)就很必要了或軟件變得不可思議的復(fù)雜。不幸的是,有些復(fù)雜得可怕的嵌入式系統(tǒng)只因?yàn)樵O(shè)計(jì)者堅(jiān)持不要操作系統(tǒng)才那么復(fù)雜?! ?
漸漸地,更多嵌入式系統(tǒng)需要與各類網(wǎng)絡(luò)聯(lián)接,因此需要網(wǎng)絡(luò)功能。即便是酒店的門把手也嵌入了微處理器與網(wǎng)絡(luò)相聯(lián)。 對(duì)于僅僅是編碼控制循環(huán)的嵌入式系統(tǒng),增加網(wǎng)絡(luò)功能將導(dǎo)致系統(tǒng)復(fù)雜程度提高以致要求操作系統(tǒng)?! ?
除了商品化操作系統(tǒng),還有大量專用操作系統(tǒng)。其中大部分來自于草案,如CISCO的IOS;還有是從其他操作系統(tǒng)中派生出來的。例如,許多操作系統(tǒng)是從同一版本的Berkeley Unix系統(tǒng)派生,因?yàn)樗型暾木W(wǎng)絡(luò)功能。其他是基于主要操作系統(tǒng)的如KA9Q來自Phil Karn?! ?
Linux作為嵌入式系統(tǒng)是一個(gè)帶有很多優(yōu)勢(shì)的新成員。它對(duì)許多CPU和硬件平臺(tái)都是可移植的、穩(wěn)定、功能強(qiáng)大、易于開發(fā)?! ?
工具包突破ICE的障礙
開發(fā)嵌入式系統(tǒng)的關(guān)鍵的是可用的工具包。像任何工作一樣,好的工具使得工作更快更好。開發(fā)的不同階段需要不同的工具?! ?
傳統(tǒng)上,首先用于開發(fā)嵌入式系統(tǒng)工具是內(nèi)部電路仿真器(ICE),它是一個(gè)相對(duì)昂貴的部件,用于植入微處理器與總線之間的電路中,允許使用者監(jiān)視和控制微處理器所有信號(hào)的進(jìn)出。這有點(diǎn)難做,因?yàn)樗钱愺w,可能會(huì)引起不穩(wěn)定。但是它提供了總線工作的清晰狀況,免了許多對(duì)硬件軟件底層工作狀況的猜測(cè)?! ?
過去,一些工作依賴ICE為主要調(diào)試工具,用于整個(gè)開發(fā)過程。但是,一旦初始化軟件對(duì)串口支持良好的話,多數(shù)的調(diào)試可以不用ICE而用其他方法進(jìn)行。較新的嵌入式系統(tǒng)利用非常清晰的微處理器設(shè)計(jì)。有時(shí),相應(yīng)工作初始碼已經(jīng)有了能夠快速獲得串口工作。這意味著沒有ICE人們也能夠方便地工作。省去ICE降低了開發(fā)的成本。一旦串口開始工作,它可以支持各種專業(yè)開發(fā)工具?! ?
Linux是基于GNU的C編譯器,作為GNU工具鏈的一部分,與gdb源調(diào)試器一起工作。它提供了開發(fā)嵌入式Linux系統(tǒng)的所有軟件工具。這有些典型的、用于在新硬件上開發(fā)嵌入式Linux系統(tǒng)的調(diào)試工具?! ?
1.寫入或植入引導(dǎo)碼
2.向串口打印字符串的編碼,如“Hello World”(事實(shí)上我更喜歡“Watson,Come hre I need you”,電話上常用的第一個(gè)詞。)
3.將gdb目標(biāo)碼植入工作串口,這可與另一臺(tái)運(yùn)行g(shù)db程序的Linux主機(jī)系統(tǒng)對(duì)話。只要簡(jiǎn)單地告訴gdb通過串口調(diào)試程序。它通過串口與測(cè)試機(jī)的gdb目標(biāo)碼對(duì)話,你可以進(jìn)行C源代碼調(diào)試,也可以用這個(gè)功能將更多的碼載入RAM或Flash Memory中?! ?
4.利用gdb讓硬件和軟件初始化碼在Linux內(nèi)核啟動(dòng)時(shí)工作。
5.一旦Linux內(nèi)核啟動(dòng),串口成為L(zhǎng)inux控制口并可用于后續(xù)開發(fā)。利用kgdb,內(nèi)核調(diào)試版的gdb,這步常常不作要求,如果你與網(wǎng)絡(luò)聯(lián)接,如10BaseT,下一步你可能要啟動(dòng)它?! ?
6.如果在你的目標(biāo)硬件上運(yùn)行了完整的Linux內(nèi)核,你可以調(diào)試你的應(yīng)用進(jìn)程。利用其他的gdb或覆蓋gdb的圖形如xgdb?! ?
什么是實(shí)時(shí)系統(tǒng)?
嵌入式系統(tǒng)常常被錯(cuò)誤地分為實(shí)時(shí)系統(tǒng),盡管多數(shù)系統(tǒng)一般并不要求實(shí)時(shí)功能。實(shí)時(shí)是一個(gè)相對(duì)的詞,純化論者常常嚴(yán)格地定義實(shí)時(shí)為對(duì)一事件以預(yù)定的方式在極短的時(shí)間如微秒作出響應(yīng)漸漸地,在如此短暫時(shí)間間隔內(nèi)的嚴(yán)格實(shí)時(shí)功能在專用DSP芯片或ASIC上實(shí)現(xiàn)了。只有在設(shè)計(jì)低層硬件FIFO、分散/聚集DMA引擎和定制硬件時(shí)才會(huì)有這樣的要求?! ?
許多設(shè)計(jì)人員因?yàn)閷?duì)真實(shí)的要求設(shè)有清晰的理解而對(duì)實(shí)時(shí)的要求焦慮不安。對(duì)于大多數(shù)的系統(tǒng),在一至五微秒的近似實(shí)時(shí)響應(yīng)已經(jīng)足夠。同樣軟需求也是可以接受的。如 Windows 98 已經(jīng)崩潰的中斷必須在4毫秒內(nèi)(±98%)內(nèi)、或20毫秒(±0)內(nèi)進(jìn)行處理?! ?
這種軟要求是比較容易滿足的,包括環(huán)境轉(zhuǎn)換時(shí)間、中斷等待時(shí)間、任務(wù)優(yōu)先級(jí)和排序。環(huán)境轉(zhuǎn)換時(shí)間曾是操作系統(tǒng)的一個(gè)熱門話題。總之,多數(shù)CPU這些要求處理得很好,而且CPU的速度現(xiàn)在已經(jīng)快了很多,這個(gè)問題也就不重要了。
嚴(yán)格的實(shí)時(shí)要求通常由中斷例程或其他內(nèi)核環(huán)境驅(qū)動(dòng)程序功能處理,以確保穩(wěn)定的表現(xiàn),等待時(shí)間,一旦請(qǐng)求出現(xiàn)要求服務(wù)的時(shí)間很大程度上取決于中斷的優(yōu)先及其他能暫時(shí)掩蓋中斷的軟件?! ?
中斷必須進(jìn)行處理和管理以確保時(shí)間要求能符合,如同許多其他的操作系統(tǒng)。在IntelX86處理器中,這工作很容易由Linux實(shí)時(shí)擴(kuò)展處理。這是提供了一個(gè)以后臺(tái)任務(wù)方式運(yùn)行Linux的中斷處理調(diào)度。關(guān)鍵的中斷響應(yīng)不必通知Linux。因此可以得到許多對(duì)于關(guān)鍵時(shí)鐘的控制。在實(shí)時(shí)控制級(jí)和時(shí)間限制寬松的基本Linux級(jí)之間提供接口,這提供了與其他嵌入式操作系統(tǒng)相似的實(shí)時(shí)框架。因此,實(shí)時(shí)關(guān)鍵代碼是隔開的、并“設(shè)計(jì)”成滿足要求的。代碼處理的結(jié)果是以更一般的方法也許只在應(yīng)用任務(wù)級(jí)。
嵌入式系統(tǒng)定義
一個(gè)觀點(diǎn)是如果一個(gè)應(yīng)用沒有用戶界面,它必須是嵌入式的,因?yàn)橛脩舨荒苤苯优c之交互。當(dāng)然這是簡(jiǎn)單化的。一個(gè)電梯控制的電腦被認(rèn)為是嵌入式的:按鍵選擇樓層指示燈顯示電梯的停層。對(duì)于聯(lián)網(wǎng)的嵌入式系統(tǒng),如果系統(tǒng)包含監(jiān)視和控制的網(wǎng)絡(luò)瀏覽器,這種界限就更加模糊了。更好些的定義注重系統(tǒng)的集中的功能和主要的目的。
因?yàn)長(zhǎng)inux提供了完成嵌入功能的基本的內(nèi)核和你所需要的所有用戶界面,它是多面的。它能處理嵌入式任務(wù)和用戶界面。將Linux看作是連續(xù)的統(tǒng)一體,從一個(gè)具有內(nèi)存管理、任務(wù)切換和時(shí)間服務(wù)及其他的分拆的、微內(nèi)核到完整的服務(wù)器,支持所有的文件系統(tǒng)和網(wǎng)絡(luò)服務(wù)?! ?
一個(gè)小型的嵌入式Linux系統(tǒng)只需要下面三個(gè)基本元素:
1.引導(dǎo)工具:Linux微內(nèi)核,由內(nèi)存管理、進(jìn)程管理和事務(wù)處理構(gòu)成
2.初始化進(jìn)程:如果要讓它能干點(diǎn)什么且繼續(xù)保持小型化,還得加上:
3.硬件驅(qū)動(dòng)程序:提供所需功能的一個(gè)或更多應(yīng)用程序?! ?
再增加功能,或許需要這些:一個(gè)文件系統(tǒng)(也許在ROM或RAM中)TCP/IP網(wǎng)絡(luò)堆棧存儲(chǔ)半過渡數(shù)據(jù)和交換用的磁盤。
硬件平臺(tái)
選擇最好的硬件是一個(gè)復(fù)雜的工作、充滿了公司其他項(xiàng)目的政治、偏見、傳統(tǒng),缺乏完整或精確的信息。 成本經(jīng)常是關(guān)鍵的議題。當(dāng)考慮成本時(shí)、確信你在考慮產(chǎn)品的整個(gè)成本、不僅是CPU。有時(shí)快的、便宜的CPU一旦加上總線邏輯和時(shí)延使之與外設(shè)一起工作,能變成一個(gè)昂貴的狗的產(chǎn)品。如果你在尋找軟件,首先是硬件已經(jīng)有產(chǎn)品了。如果你是系統(tǒng)設(shè)計(jì)者,由你決定制定實(shí)時(shí)的預(yù)算及硬件的工作是否滿意?! ?
現(xiàn)實(shí)中需要多快的CPU來完成一項(xiàng)工作,然后放大三倍。奇怪,CPU理論上的速度竟與現(xiàn)實(shí)中一樣,別忘了應(yīng)用程序?qū)?huì)充分利用cache?! ?
想象總線的速度需要多快,如果有其他總線如PCI總線,包括進(jìn)來。慢的總線或產(chǎn)生DMA阻塞的總線會(huì)降低CPU的速度造成擁擠。 有集成設(shè)備的CPU是好的,因?yàn)橹豁氄{(diào)試很少的設(shè)備,并且支持通用CPU的驅(qū)動(dòng)程序通常都很容易獲得。在我的項(xiàng)目中,芯片與外設(shè)的聯(lián)接經(jīng)常出問題或不滿足我們所需的兼容性。因?yàn)橥庠O(shè)是集成的,不要認(rèn)為這會(huì)便宜。
將10斤重的Linux塞入只能裝5斤的袋中。對(duì)于Linux一個(gè)共同的認(rèn)識(shí)是它用于嵌入式系統(tǒng)簡(jiǎn)直是神奇極了。這可能不大對(duì),典型的PC上的Linux對(duì)PC用戶來說功能有多,對(duì)初學(xué)者而言,可以將內(nèi)核與任務(wù)分開,標(biāo)準(zhǔn)的Linux內(nèi)核通常駐留在內(nèi)存中,每一個(gè)應(yīng)用程序都是從磁盤運(yùn)到內(nèi)存上執(zhí)行。當(dāng)程序結(jié)束后,它所占用的內(nèi)存就被釋放,程序就被下載了。
在一個(gè)嵌入式系統(tǒng)里,可能沒有磁盤。有兩種途徑可以消除對(duì)磁盤的依賴,這要看系統(tǒng)的復(fù)雜性和硬件的設(shè)計(jì),在一個(gè)簡(jiǎn)單的系統(tǒng)里,當(dāng)系統(tǒng)啟動(dòng)后,內(nèi)核和所有的應(yīng)用程序都在內(nèi)存里。這就是大多數(shù)傳統(tǒng)的嵌入式系統(tǒng)工作模式,它同樣可以被Linux支持?! ?/P>
有了Linux,就有了第二種可能性。因?yàn)長(zhǎng)inux已經(jīng)有能力“加載”和“卸載”程序,一個(gè)嵌入式系統(tǒng)就可以利用它來節(jié)省內(nèi)存。試想一個(gè)典型的包括一個(gè)大概8MB到16MB的Flash Memory和8MB內(nèi)存的系統(tǒng)。Flash Memory可以作為一個(gè)文件系統(tǒng)。Flash Memory驅(qū)動(dòng)程序用來連接Flash Memory和文件系統(tǒng)。作為替代,可使用Flash Disk。這Flash部件用軟件仿真磁盤。其中一個(gè)例是M-Systems的DiskOnChip,可以達(dá)到160MB。所有的程序都以文件形式存儲(chǔ)在Flash文件中,需要時(shí)可以裝入內(nèi)存。這種動(dòng)態(tài)的、“根據(jù)需要加載”的能力是支持其它一系列功能的重要特征:它使初始化代碼在系統(tǒng)引導(dǎo)后被釋放。Linux同樣有很多內(nèi)核外運(yùn)行的公用程序。這些通常程序在初始化時(shí)運(yùn)行一次,以后就不再運(yùn)行。而且,這些公用程序可以用它們相互共有的方式,一個(gè)接一個(gè)按順序運(yùn)行。這樣,相同內(nèi)存空間可以被反復(fù)使用以“召入”每一個(gè)程序,就象系統(tǒng)引導(dǎo)一樣。這的確可以節(jié)省內(nèi)存,特別是那些配置一次以后就不再更改的網(wǎng)絡(luò)堆棧 如果Linux可加載模塊的功能包括在內(nèi)核里,驅(qū)動(dòng)程序和應(yīng)用程序就都可以被加載。它可以檢查硬件環(huán)境并且為硬件裝上相應(yīng)的軟件。這就消除了用一個(gè)程序占用許多Flash Memory來處理多種硬件的復(fù)雜性?! ?
軟件的升級(jí)更模塊化。你可以在系統(tǒng)運(yùn)行的時(shí)候在Flash上升級(jí)應(yīng)用程序和可加載驅(qū)動(dòng)程序,配置信息和運(yùn)行時(shí)間參數(shù)可以作為數(shù)據(jù)文件儲(chǔ)存在Flash上。
非虛擬內(nèi)存
標(biāo)準(zhǔn)Linux的另一個(gè)待征是虛擬內(nèi)存的能力。正是這種神奇的特征使應(yīng)用程序員可以狂熱的編寫代碼而不計(jì)后果,不管程序有多大。程序溢出到了磁盤交換區(qū)。在沒有磁盤的嵌入式系統(tǒng)里,通常不能這么做?! ?
在嵌入式系統(tǒng)里不需要這種強(qiáng)大的功能。實(shí)際上,你可能不希望它在實(shí)時(shí)的關(guān)鍵系統(tǒng)里,因?yàn)樗鼤?huì)帶來無法控制的時(shí)間因素。這個(gè)軟件必須設(shè)計(jì)得更加精悍,以適合市面上物理內(nèi)存,就象其它嵌入式系統(tǒng)一樣?! ?
注意由于CPU的原因,通常在Linux中保存虛擬內(nèi)存代碼是明智的,因?yàn)閷⑺宄苜M(fèi)事。而且還有另外一個(gè)原因是它支持共享文本,這樣就可以使許多程序共享一個(gè)軟件。沒有這個(gè),每一個(gè)程序都要有它自己的庫,就象printf一樣。
虛擬內(nèi)存的調(diào)入功能可以被關(guān)掉,只要將交換空間的大小設(shè)置為零。然后,如果你寫的程序比實(shí)際的內(nèi)存大,系統(tǒng)就會(huì)當(dāng)作你的運(yùn)行用盡了交換空間來處理;這個(gè)程序?qū)⒉粫?huì)運(yùn)行,或者malloc將會(huì)失靈。
在許多CPU上,虛擬內(nèi)存提供的內(nèi)存管理可以將不同程序分開,防止它們寫到其它地址的空間上。這在嵌入式系統(tǒng)上通常不可能,因?yàn)樗恢С忠粋€(gè)簡(jiǎn)單、扁平的地址空間。Linux的這種功能有助于其發(fā)展。它減少了胡亂的編寫程序造成系統(tǒng)崩潰的可能性。許多嵌入式系統(tǒng)基于效率方面的原因有意識(shí)使用程序間可以共享的“全局”數(shù)據(jù)。這也可以通過Linux共享內(nèi)存功能來支持,共享的只是指定的內(nèi)存部分。
文件系統(tǒng)
許多嵌入式系統(tǒng)沒有磁盤或者文件系統(tǒng)。Linux不需要它們也能運(yùn)行。如前所述,應(yīng)用程序任務(wù)可以和內(nèi)核一起編寫,并且在引導(dǎo)時(shí)作為一個(gè)影像加載。對(duì)于簡(jiǎn)單的系統(tǒng)來說,這就夠了。然而,它缺乏前面所說的靈活性?! ?
實(shí)際上,許多商業(yè)性嵌入式系統(tǒng),提供文件系統(tǒng)作為選項(xiàng)。許多或者是專用的文件系統(tǒng)或者是MS-DOS-Compatible文件系統(tǒng)。Linux提供MS-DOS-Compatible文件系統(tǒng),同時(shí)還有其它多種選擇。之所以提供其它選擇是因?yàn)樗鼈兏訌?qiáng)大而且具有容錯(cuò)功能。Linux還具有檢查和維護(hù)的功能,商業(yè)性供應(yīng)商往往不提供這些。這對(duì)于Flash系統(tǒng)來說尤其重要,因?yàn)樗峭ㄟ^網(wǎng)絡(luò)更新的。如果系統(tǒng)在升級(jí)過程中失去了能力,那它就沒有用了。維護(hù)的功能通??梢越鉀Q這類問題。
文件系統(tǒng)可以被放在傳統(tǒng)的磁盤驅(qū)動(dòng)器、Flash Memory或其它這類的介質(zhì)上。而且,用于暫時(shí)保存文件,一個(gè)小RAM盤就足夠了。Flash Memories被分割成塊。這些塊中也許包括一個(gè)含有當(dāng)CPU啟動(dòng)時(shí)運(yùn)行的最初的軟件的引導(dǎo)塊。這可能包括Linux 引導(dǎo)代碼。剩余的Flash可以用作文件系統(tǒng)。Linux的內(nèi)核可以通過引導(dǎo)代碼從Flash復(fù)制到RAM,或者還有一個(gè)選擇,內(nèi)核可以被存儲(chǔ)在Flash的一個(gè)獨(dú)立部分,并且直接從那里執(zhí)行?! ?
另外對(duì)于一些系統(tǒng)來說還有一個(gè)有趣的選擇,那就是將一個(gè)便宜的CD-ROM包含在內(nèi)。這比Flash Memory 便宜,而且通過交換CD-ROM支持簡(jiǎn)單的升級(jí)。有了這個(gè),Linux 只要從 CD-ROM上引導(dǎo),并且象從硬盤上一樣從CD-ROM上獲得所有的程序?! ?
最后,對(duì)于聯(lián)網(wǎng)的嵌入式系統(tǒng)來說,Linux 支持NFS(Network File System)。這為實(shí)現(xiàn)聯(lián)網(wǎng)系統(tǒng)的許多增值功能打開了大門。第一,它允許通過網(wǎng)絡(luò)上加載應(yīng)用程序。這是控制軟件修改的基礎(chǔ),因?yàn)槊恳粋€(gè)嵌入式系統(tǒng)的軟件都可以在一個(gè)普通的服務(wù)器上加載。它在運(yùn)行的時(shí)候也可以用來輸入或輸出大量的數(shù)據(jù)、配置和狀態(tài)信息。這對(duì)用戶監(jiān)督和控制來說是一個(gè)非常強(qiáng)大的功能。舉例來說,嵌入式系統(tǒng)可以建立一個(gè)小的RAM磁盤,包含的文件中有與當(dāng)前狀態(tài)信息同步的內(nèi)容。其它系統(tǒng)可以簡(jiǎn)單的把這個(gè)RAM磁盤設(shè)置為基于網(wǎng)絡(luò)的遠(yuǎn)程磁盤,并且空中存取狀態(tài)文件。這就允許另一個(gè)機(jī)器上的Web服務(wù)器通過簡(jiǎn)單的CGI Script存取狀態(tài)信息。在其它電腦上運(yùn)行的其它應(yīng)用程序包可以很容易的存取數(shù)據(jù)。對(duì)更復(fù)雜的監(jiān)控,應(yīng)用程序包如Matlab可以用來在操作員的PC或工作站的提供系統(tǒng)運(yùn)行的圖形展示?! ?
引導(dǎo)LILO和BIOS在哪里
當(dāng)一個(gè)微處理器第一次啟動(dòng)的時(shí)候,它開始在預(yù)先設(shè)置的地址上執(zhí)行指令。通常在那里有一些只讀內(nèi)存,包括初始化或引導(dǎo)代碼。在PC上,這是BIOS。它執(zhí)行了一些低水平的CPU初始化和其它硬件的配置。BIOS繼續(xù)辨認(rèn)哪個(gè)磁盤里有操作系統(tǒng),把操作系統(tǒng)復(fù)制到RAM并且轉(zhuǎn)向它。實(shí)際上,這非常復(fù)雜,但對(duì)我們的目標(biāo)來說也非常重要。在PC上運(yùn)行的Linux依靠PC的BIOS來提供這些配置和OS加載功能。
在一個(gè)嵌入式系統(tǒng)里經(jīng)常沒有這種BIOS。這樣你就要提供同等的啟動(dòng)代碼。幸運(yùn)的是,嵌入式系統(tǒng)并不需要PC BIOS引導(dǎo)程序那樣的靈活性,因?yàn)樗ǔV恍枰幚硪粋€(gè)硬件的配置。這個(gè)代碼更簡(jiǎn)單也更枯燥。它只是一指令清單,將固定的數(shù)字塞到硬件寄存器中去。然而,這是關(guān)鍵的代碼,因?yàn)檫@些數(shù)值要與你的硬件相符而且要按照特定的順序進(jìn)行。所以在大多數(shù)情況下,一個(gè)最小的通電自檢模塊,可以檢查內(nèi)存的正常運(yùn)行、讓LED閃爍,并且驅(qū)動(dòng)其它必須的硬件以使主Linux OS啟動(dòng)和運(yùn)行。這些啟動(dòng)代碼完全根據(jù)硬件決定,不可隨意移動(dòng)?! ?
幸運(yùn)的是,許多系統(tǒng)都有為核心微處理器和內(nèi)存所定制的菜單式硬件設(shè)計(jì)。典型的是,芯片制造商有一個(gè)樣本主板,可以用來作為設(shè)計(jì)的參考或多或少與新設(shè)計(jì)相同。通常這些菜單式設(shè)計(jì)的啟動(dòng)代碼是可以獲得的,它可以根據(jù)你的需要輕易的修改。在少數(shù)情況下,啟動(dòng)代碼需要重新編寫。 為了測(cè)試這些代碼,你可以使用一個(gè)包含‘模擬內(nèi)存’的電路內(nèi)置模擬器,它可以代替目標(biāo)內(nèi)存。你把代碼裝到模擬器上并通過模擬器調(diào)試。如果這樣不行,你可以跳過這一步,但這樣就要一個(gè)更長(zhǎng)的調(diào)試周期?! ?
這個(gè)代碼最終要在較為穩(wěn)定的內(nèi)存上運(yùn)行,通常是Flash或EPROM芯片。你需要使用一些方法將代碼放在芯片上。怎么做,要根據(jù)“目標(biāo)”硬件和工具來定?! ?
一種流行的方法是把Flash或EPROM芯片插入EPROM或Flash燒制器。這將把你的程序“燒”(存)入芯片。然后,把芯片插入你的目標(biāo)板的插座,打開電源。這個(gè)方法需要板上配有插座,但有些設(shè)備是不能配插座的。 另一個(gè)方法是通過一個(gè)JTAG界面。一些芯片有JTAG界面可以用來對(duì)芯片進(jìn)行編程。這是最方便的方法。芯片可以永遠(yuǎn)被焊在主板上,一個(gè)小電纜從板上的JTAG連接器,通常是一個(gè)PC卡,聯(lián)到JTAG界面。下面是PC運(yùn)行JTAG界面所需的一些慣用程序。這個(gè)設(shè)備還可以用來小量生產(chǎn)。
穩(wěn)定性是最可靠的
在PC硬件上運(yùn)行時(shí),Linux是非??煽亢头€(wěn)定的,特別是和現(xiàn)在流行的一些操作系統(tǒng)相比。嵌入式內(nèi)核本身有多穩(wěn)定呢?對(duì)大多數(shù)微處理器來說,Linux非常好。移植到新微處理器家族的Linux內(nèi)核運(yùn)行起來與本微處理器一樣穩(wěn)定。它經(jīng)常被移植到一個(gè)或多個(gè)特定的主板上。這些板包括特定的外圍設(shè)備和CPU。
幸運(yùn)的是,許多代碼是與處理器的,所以移植集中在差異上。其中大多數(shù)是在內(nèi)存管理和中斷控制領(lǐng)域。一旦成功移植,它們就非常穩(wěn)定。前面我們討論過,引導(dǎo)策略廣泛依賴于硬件要求,而且你必須有計(jì)劃地做一些定制的工作。
設(shè)備驅(qū)動(dòng)程序更加混亂:有些穩(wěn)定有些不穩(wěn)定。而且選擇很有限;一旦你離開了通用的PC平臺(tái),你需要自己編寫。幸運(yùn)的是,周圍有許多驅(qū)動(dòng)程序,你可能可以找到一個(gè)與你的需求相近的修改一下。這種驅(qū)動(dòng)程序界面已定義好。許多類的驅(qū)動(dòng)程序都非常相近,所以把磁盤、網(wǎng)絡(luò)或一系列的端口驅(qū)動(dòng)程序從一個(gè)設(shè)備移植到另一個(gè)設(shè)備上通常并不難。我發(fā)現(xiàn)許多驅(qū)動(dòng)程序都寫得很好,很容易理解,但你還是要準(zhǔn)備一本關(guān)于內(nèi)核結(jié)構(gòu)的書在手頭。 依我的經(jīng)驗(yàn),Linux至少和我用過的著名的商業(yè)性操作系統(tǒng)一樣穩(wěn)定??傊?,這些操作系統(tǒng)和Linux的問題在于對(duì)工作過程微秒之處的誤解,而不在于代碼的難度或基本的設(shè)計(jì)錯(cuò)誤。任何操作系統(tǒng)都有很多爭(zhēng)論不休的故事,這里不需要重復(fù)。Linux的優(yōu)勢(shì)在于源代碼是公開、注釋清晰和文檔齊全的。這樣,你就可以控制和處理所出現(xiàn)的任何問題?! ?
伴隨著基本內(nèi)核和驅(qū)動(dòng)程序,還有其它問題。如果系統(tǒng)有一個(gè)硬盤,那么文件系統(tǒng)的可靠性就成問題。我們有用磁盤進(jìn)行Linux系統(tǒng)設(shè)計(jì)超過兩年的經(jīng)驗(yàn)。這些系統(tǒng)幾乎從未正常關(guān)閉過。電源隨時(shí)都可能被中斷。感覺非常好,使用的是標(biāo)準(zhǔn)(EXT2)文件系統(tǒng)。標(biāo)準(zhǔn)Linux初始化腳本運(yùn)行fsck程序,它在檢查和清除不穩(wěn)定的inodes方面非常有效。將默認(rèn)的每隔30秒運(yùn)行更新程序改為每隔5或10秒運(yùn)行是比較明智的。這樣縮短了數(shù)據(jù)在進(jìn)入磁盤之前,待在高速緩沖存儲(chǔ)器內(nèi)的時(shí)間,降低了丟失數(shù)據(jù)的可能性?! ?
未來的發(fā)展
嵌入式Linux的確有它的缺陷。比如,雖然它并不比某些商業(yè)競(jìng)爭(zhēng)對(duì)手差多少,但它的確是個(gè)貪婪的存儲(chǔ)器。這可以通過減少一些不必要的功能來彌補(bǔ),但這可能會(huì)花很長(zhǎng)的時(shí)間,而且如果不仔細(xì)的話,還可能帶來很大的困擾。
許多Linux的應(yīng)用程序都要用到虛擬內(nèi)存,在許多嵌入式系統(tǒng)中,是沒有價(jià)值的,所以不要以為一個(gè)沒有磁盤的嵌入式系統(tǒng)可以運(yùn)行任何Linux應(yīng)用程序?! ?
內(nèi)核調(diào)試工具都不怎么好,特別是在較底層的。kgdb可以使錯(cuò)誤定位非常容易,你只要重新啟動(dòng)。不幸的是,打印語句更麻煩。
然而,對(duì)我來說最糟糕的是心理上的問題。Linux非常的靈活。嵌入式系統(tǒng)總的來說卻不靈活;而且它們完全是為最有效實(shí)現(xiàn)預(yù)定功能而嚴(yán)格設(shè)計(jì)的?,F(xiàn)在的趨勢(shì)是保持靈活性、保持總體目標(biāo)功能、盡量少做修改。這個(gè)目標(biāo)是崇高的,但是,所付出的代價(jià)將是針對(duì)具體的工作做出巨大的調(diào)整。保持靈活性將導(dǎo)致額外的工作,帶著額外的軟件包,而且有時(shí)還要降低性能。一個(gè)反復(fù)出現(xiàn)的例子就是配置??紤]在一個(gè)網(wǎng)絡(luò)界面配置IP地址,這通常是通過從啟動(dòng)script上運(yùn)行ifconfig程序來完成的。這是一個(gè)28K的程序,從配置文件上調(diào)用數(shù)據(jù),可以用幾行代碼代替,初始化合適的結(jié)構(gòu)。然而,即使這非常合理,但它仍然有害,因?yàn)樗靡环N從未使用過的方法扭曲了軟件。
Linux在嵌入式系統(tǒng)中的應(yīng)用是可行的。它有用、可靠。它的發(fā)展成本和替代者一致。
評(píng)論
查看更多