Global Sources
電子工程專輯
 
電子工程專輯 > 記憶體/儲存
 
 
記憶體/儲存  

在快閃記憶體中進行作業系統韌體升級的設計策略

上網時間: 2003年11月30日     打印版  Bookmark and Share  字型大小:  

關鍵字:Firmware  microprogrammer  作業系統  微編程器  flash 

作業系統放於快閃記憶體中有很多好處,例如設計人員可以隨時在現場將軟體新版本下載到快閃記憶體中對其進行更新,但在下載過程中有一些因素需要注意,否則會造成系統崩潰的嚴重後果。本文介紹一種便利的軟體結構,它可以幫助工程師避免犯一些常見的錯誤。

所有更新作業系統的方法都存在這樣一個問題,即假如升級內容中存在缺陷,那麼目標系統可能需要花很大力氣才能更正,許多缺陷很簡單且顯而易見,但有些隱藏很深的缺陷只有在產品完成以後才能顯現出來。程式1:下載並執行微型處理器的程式碼。

用戶發現和處理缺陷的能力各有千秋,而更糟糕的是,他們往往不注意諸如‘如果在編程過程中電源系統中斷系統將受到損壞’一類的警告,在系統更新過程中,他們很願意重新啟動其它功能系統,然後再把‘出了問題’的產品拿去維修。

所有設計好的作業系統更新過程,都要能夠盡可能從用戶的錯誤和其它災難性事件中復原,做到這一點最好的方法就是採取可靠的作業系統更新策略,以完全避免這些問題。本文將討論這樣一種策略,它可以直接使用,但是也可以根據實際應用的特性對它進行修正。

微編程器


微編程器是對嵌入式系統在作業系統更新過程之前、過程中及之後執行情況的一種系統級描述,這種對工作情形的描述有助於避免與其它作業系統下載方法有關的問題,小心對待這些過程可以消除很多其它的擔心。

採用微編程器的作業系統更新方法第一步是使嵌入式系統進入下載產生時所期望的狀態。過渡到這個狀態可以採用好幾種方式,例如,它可以透過用戶按下設備控制介面上的‘升級’鍵來完成,或者在系統探測到文件傳輸開始或結束時進行,或者用其它方法。不管哪種情況,目標系統都會意識到作業系統馬上要更新了,於是讓其它控制過程進入安全和穩定的停止狀態。

下一步,目標系統會收到一個叫做微編程器的應用程式,微編程器將控制系統,並開始接收新的應用作業系統,將它寫到快閃記憶體中。一切完成後,目標系統就開始執行新的作業系統。

採用微編程器下載作業系統的最大特點之一是它的靈活性,微編程器的執行過程即使在作業系統開始更新前的最後一刻也可以更改,以便對系統進行錯誤糾正和改進。

微編程器不會消耗目標系統的資源,除非已開始進行編程。此外,由於微編程器很小,所以目標系統在更新過程開始時不需要龐大而複雜的通訊協定,只需簡單的文件文件傳輸就足夠了。

採用微編程器的作業系統更新其安全性一度是最引人注目的優點。當目標系統的快閃記憶體晶片只用於儲存作業系統時,系統將不會有對快閃記憶體晶片內容進行刪除和編程的程式碼,除非實際過程中需要這樣。因此即使在程式失控的嚴重情況下,系統也不會意外地刪除它本身的作業系統。

然而,微編程器也有缺點,它通常作為一個獨立的程式執行,因此下載和傳輸到目標系統的程式碼需要分開管理。處理程式組件時小心謹慎有助於減少後續工作量。

微編程器一般都載入RAM中執行,這在某些微處理器結構中是不可能的,尤其是古老的8051系列,雖然其結構都是針對硬體的,但它的限制大過它所帶來的好處。

下載過程

程式1中的程式碼顯示的是下載目標系統和執行微編程器所需要的功能。在這個例子中,目標系統從某個I/O通道(也許是串列埠)接收文件形式的摩托羅拉S Record文件,將它譯碼並寫到RAM中,然後在傳輸結束時目標系統跳轉到下載程式碼啟動微編程器。

注意programmer_buf[]儲存空間是自動調整的,也就是說它在目標系統的儲存單元裡沒有固定的位置,這意味著新記錄的地址是相對的而不是絕對的,新程式碼的位置是獨立的。如果匯編程式不能產生位置獨立的程式碼,那麼programmer_buf[]就要在記憶體中分配一個固定的位置,新記錄的地址也要留在那個位置。程式2:基本的微型編程器程式碼。

假如目標系統沒有資源可長期分配給programmer_buf[],則新來的微編程器內容可以放在其它數據的上面。此時,系統無論如何都要中斷其它作業,將RAM大部份空間留給微編程器。

基本微編程器

微型編程器的頂級程式碼如程式2所示,這個程式碼也可以從某些地方接收S Record文件並將其譯碼。微編程器將新接收到的數據記錄在快閃記憶體中,當文件傳輸完成後重新啟動系統。雖然過於簡單了些(用文件文件來傳輸大的程式也許不十分可靠),但這個程式碼表示了微編程器的所有重要特徵。

erase_flash()除了實際擦除快閃記憶體中的內容外,它還管理簡單的數據結構,繼續追蹤哪一段快閃記憶體中的數據需要擦除,哪一段已經被擦除。S Record文件中經常會出現數據雜亂無章的情況,這時數據結構要透過is_section_erased()來檢查以防止快閃記憶體重覆擦除。

唯讀記憶體

不管如何修改採用微編程器的系統描述來適應自己系統的要求,在最後執行的時候還是會遇到一些常見的問題。

有些除錯器特別是模擬器,將會與目標處理器爭奪可寫入程式碼的儲存空間。多數除錯工具將程式碼空間當作是唯讀的,當它們探測到要寫入內容時,有些會產生錯誤資訊或簡單地不允許寫入。

一般來說,除錯器保護程式碼空間本身是好意,因為程式在自身程式碼空間寫入數據通常會引發嚴重的程式錯誤,除非那時正進行作業系統的更新。不幸的是除錯器並不能夠判別出它們之間的區別。補救的方法是在除錯器不會認為是唯讀的其它儲存空間裡,對快閃記憶體晶片進行‘別名(alias)儲存’。

常用化名儲存方法很簡單,只需要將所選擇啟動的元件儲存空間加倍,然後將指向‘實體’地址區域的地址轉移到指向‘化名’區域就行了,進行轉移的最好的場所通常是快閃記憶體晶片驅動器本身,如程式3中的假設write_flash()函數。

完整的編程器

採用微編程器方式的另一種方法是將微編程器的功能建在目標系統中,即所謂的啟動加載,而不是把將它下載到RAM作為作業系統更新過程的第一步。這種策略有它的優點,但是在快閃記憶體晶片擦除重新編程前需要將快閃記憶體中的編程器程式碼複製到RAM中。換句話說,就是程式碼在執行的時候,要自己重新定位到RAM中的某一點上,然後才能擦除並寫到快閃記憶體晶片中。這種方法同樣需要涉及到的程式碼是位置獨立的。

程式4中的程式顯示如何將完整編程器的程式碼複製到RAM中,以及programmer()函數如何找到RAM的形式。符號RAM_PROG_START、PROG_LEN及ROM_PROG_START是RAM和ROM區域裡的標記,那裡存放著編程器程式碼(也可能是整個應用程式的一部份),通常可以用程式連接器自動運算出來。這種在entrypoint中看似複雜的運算方法迫使匯編程式在算entrypoint的值時按位元組大小進行運算。

當調用程式調用relocate_programmer()返回地址處的函數時,控制權就交給微編程器程式碼在RAM中的拷貝,如果這時除錯器還在執行,就會停止顯示任何與programmer()函數有關的符號資訊。為什麼會這樣呢?這是因為programmer()現在是從不同於以前分配的地址開始執行,因此任何透過連接器提供給除錯器的符號資訊都是毫無意義的。

解決這個問題的方法是將應用程式和RAM地址中的programmer()重新連接,然後將程式碼資訊導入除錯器中。這是一種很方便的糾正方法,只不過有些除錯器的程式碼表不支援新增內容。另外一種方法就是忍受,直到programmer()除錯完成,不管怎樣這時理論上是不需要再看程式碼的了。程式3:在wirte_flash函數裡實現記憶體別名作業。

重新定位

不是所有嵌入式系統開發工具鏈都可以產生在執行時可以重定位的程式碼,這種依賴位置的程式碼需要從存放有連接的地址開始執行,否則系統有可能崩潰。

如果只有位置固定的微編程器,則它必須下載到連接器希望執行的RAM地址中。正如前面所說,它顯示為微編程器而保留的記憶體必須安排在一個已知的位置。

採用啟動加載方式時,可以有兩種選擇。第一個是將編程器程式碼作為一個單獨程式進行匯編並放於它在RAM中的目標地址處,然後將這個程式碼映像包含在應用程式映像中(也許是透過將其二進制映像轉換成固定的字符陣列),最後在開始更新作業系統時複製到RAM中。這個過程有點類似於微編程器的執行過程,即從目標板上的記憶體下載微編程器,而不是從串列埠下載。

第二種是將完整的微編程器程式碼作為初始數據來處理,然後用執行時間環境的正常初始化程式將程式碼複製到RAM中。GNU匯編程式使用_attribute_語言擴展支援這種方式,還有好幾種商用匯編程式也可提供這種能力。這種方法的唯一侷限在於它需要足夠的RAM空間來容奈全部程式程式碼以及程式的其它數據。

防止系統崩潰

哪怕再小心設計作業系統下載,也還是存在目標硬體從空白記憶體進行啟動的可能性。要避免這種情況出現,就要迅速啟動應用程式的轉換機制,但這樣會使毫無準備的用戶手忙腳亂。解決這一問題需要仔細研究目標處理器對非法指示及快閃記憶體中未編程部份用0xff表示的數據的反應,最好是在用戶實際感受到問題前就開始研究。有些處理器最後會停止下來,並使其控制訊號處於三態,懸浮於外部硬體要求的任一值上,如果此時沒有上拉電阻或採取其它預防措施迫使這些不受控制的訊號進入安全狀態,很容易導致預料不到的當機結果。

監測計數器

在支援作業系統下載的系統中,一些無法避免的應用程式缺陷會使看門狗計數器停頓下來並使系統復位,因而將微編程器排除在嵌入式系統的外面。極端的情況是在程式的main()函數中意外出現的while(1)語句,產生的循環嵌套(無限程式循環外面又是無限看門狗超時及系統復位循環)使目標對升級按鈕沒有反應,因為在檢查按鈕之前系統就已經重啟了。

支援作業系統下載的系統要仔細檢查所有可能的狀態,以便決定為什麼系統要啟動,並在探測到大量連續的看門狗訊號和其它復位時迫使它轉換成升級模式。很多系統在看門狗計數器終止時不會中斷RAM的電源,因此可以在那裡安全地儲存關鍵數據以及復位的運算次數。計數器每復位一次時就加一,到達某一個數量時,啟動程式碼將停止應用程式,以避免程式碼強制產生復位。

電源中斷

如果在快閃記憶體寫程式過程中電源意外中斷,目標快閃記憶體晶片在電源恢復時將可能處於矛盾的狀態。也許可能已完成寫程式的作業,一切正常,但也可能不是這樣。最好的情形是系統啟動程式碼完整無缺,但部份應用程式程式碼丟失;最糟的情況是快閃記憶體晶片還是空白,什麼也沒寫進去。

對第一種情形可以用校驗和的方法檢測問題所在,這時不管用戶有沒有要求系統都會轉換到升級模式,對第二種情形唯一的解決辦法就是不要讓這種情況產生。

防止出現空白快閃記憶體晶片的方法就是不要刪除快閃記憶體中包含的系統啟動程式碼部份,將這些程式碼始終原封不動地保存起來,這樣即使電源中斷也可以維持足夠的啟動環境。然而這種方法也不是任何時候都適用。快閃記憶體晶片也許只有一個扇區,要麼全部刪除,要麼全部保留;或者快閃記憶體晶片的‘啟動區域’比它包含的啟動程式碼要大,這樣會浪費儲存應用程式碼的空間。程式4:一個簡單的重定位策略程式。

刪除以及寫入快閃記憶體晶片啟動區域時小心一點可以在電源突然中斷時減少系統受損的風險,有時可以完全避免。方法是這樣的,當檢測到需要對含啟動程式碼的快閃記憶體區重新寫入程式時,程式器首先會在另一個區域中製作一個與位置無關的程式碼副本(也可以設想有一個在預先位置複製好的系統啟動程式碼)。然後刪除啟動程式碼,同時目標復位向量迅速恢復到臨時啟動程式碼副本的位置。一旦啟動區域的程式寫進去之後,復位向量就重新寫入指向新的啟動程式碼位置。

成功實現這種方法要依賴兩個重要因素,其中之一是應仔細選擇臨時和永久存放啟動程式碼副本的地址。如果永久地址比臨時地址低兩級,只要數據位從1變成0臨時復位向量就會轉成永久復位向量,這樣就可能造成快閃記憶體區域不必要的刪除。使臨時復位向量轉成永久復位向量是一個細微的作業,不管電源何時中斷,向量始終應指向有效的位置。

另外一個關鍵因素是應避免在刪除啟動區域和寫入臨時復位向量之間電源中斷的風險。實現該目標所需能量可以從快閃記憶體晶片和微處理器規格表中的功耗運算出來,通常是在系統電源電路中增加一些電容器彌補斷電造成的中斷,確認電源在執行時繼續保持,並一直不中斷直至區域刪除且臨時復位向量寫好為止,這樣可以避免可能產生的損壞。該方法的侷限在於它依賴處理器啟動程式,要讀取復位向量得到初始程式計數器的值。復位後處理器簡單地從固定地址執行程式碼,也可將它修改成智慧作業程式碼的混合體以實現同樣的目的。

硬體選項

採用微編程器的作業系統更新方法及由這種方法衍生而來的其它的方法都是以作業系統為基礎的,因為它們都要求在程式碼重新編程前目標系統中已有程式碼存在。這就產生了一個先有雞還是先有蛋的問題。如果在嵌入式系統中需要有程式碼才能將新的程式碼寫進去,怎樣才能將那些最初的程式碼放進去呢?

要啟動這一過程現在有兩種現成的硬體可選,分別是後台除錯模式(BDM)和JTAG。

具有BDM埠的處理器可以提供一個基本的直接連接處理器本身內部結構的串列埠,透過向這個埠發送正確的指令和數據,可以在目標系統的RAM中增加微編程器的副本,並將控制權轉交給它。BDM埠也可以用來激勵快閃記憶體晶片的I/O線,這樣就可以直接對它進行編程。很多以BDM為基礎的開發系統都包括一些腳本和程式可實現這一功能,但也可以在仔細研究處理器說明書之後,透過幾個晶片和電腦列印埠用人工方式來完成。

JTAG是一種設計為便於晶片I/O線進行讀寫的完全不同的技術,通常是在晶片的微處理器(如果有的話)保持復位狀態時採用。然而與BDM相同,這種能力可以用來激勵RAM或快閃記憶體把微編程器加入到裡面,像BDM一樣,JTAG介面也可以透過研究目標處理器說明書然後用幾個元件來實現。JTAG匯流排收發晶片有多種型號,可從不同的供應商處得到,並加在不支援JTAG的系統中。

作者:Bill Gatliff


Email: bgat@bill-gatliff.com




投票數:   加入我的最愛
我來評論 - 在快閃記憶體中進行作業系統韌體升級的...
評論:  
*  您還能輸入[0]個字
*驗證碼:
 
論壇熱門主題 熱門下載
 •   將邁入40歲的你...存款多少了  •  深入電容觸控技術就從這個問題開始
 •  我有一個數位電源的專利...  •  磷酸鋰鐵電池一問
 •   關於設備商公司的工程師(廠商)薪資前景  •  計算諧振轉換器的同步整流MOSFET功耗損失
 •   Touch sensor & MEMS controller  •  針對智慧電表PLC通訊應用的線路驅動器
 •   下週 深圳 llC 2012 關於PCB免費工具的研討會  •  邏輯閘的應用


EE人生人氣排行
 
返回頁首