需要非易失性數(shù)據存儲的應用幾乎總是使用外部串行EEPROM。本文介紹如何僅使用MAXQ微控制器中已有的閃存來提供非易失性數(shù)據存儲。
介紹
大多數(shù)需要微控制器的應用還需要一些機制來存儲設置,即使斷電也會被記住。例如,在更換電池時忘記其電臺預設的收音機在當今的市場上不會成功??蛻粝M麑⑾矏鄣碾娕_、溫度預設、首選項和其他持久性信息從一次使用保存到下一次使用。
為了滿足客戶對非易失性數(shù)據存儲的期望,設計人員傳統(tǒng)上使用串行EEPROM。這些EEPROM器件體積小,價格低廉,歷史悠久,使設計工程師能夠放心使用。但在當今對成本敏感的市場中,即使是在設計中添加廉價的EEPROM器件也會超出預算。
許多處理器使用閃存來存儲程序代碼,并使用靜態(tài)RAM來存儲數(shù)據。雖然利用閃存的未使用部分進行非易失性數(shù)據存儲可能很有吸引力,但傳統(tǒng)的哈佛架構排除了這種用途。但MAXQ架構是一臺具有獨立代碼和數(shù)據路徑的哈佛機器。MAXQ器件包含實現(xiàn)偽馮諾依曼架構的硬件,允許方便地訪問代碼空間作為數(shù)據存儲器。這種額外的多功能性,結合MAXQ提供存儲器寫和擦除服務的實用功能,為完整的讀寫、非易失性存儲器子系統(tǒng)提供了背景。
有關閃存的基本注意事項
閃存是一種電可擦除存儲器。它通常被認為是“大部分閱讀”。簡單來說,雖然閃存是可寫的,但它的使用假設數(shù)據更新將不頻繁,并且大部分操作將是讀取操作。大多數(shù)閃存設備在字級別是可寫的,但一次只能擦除整個塊。這使得這些存儲設備通常不適合可變存儲,并且僅適用于永不改變的常量數(shù)據表。
閃存有兩種:NAND閃存和NOR閃存。NAND閃存用于存儲卡和閃存驅動器。通常,從NAND設備讀取數(shù)據需要幾個周期,因為數(shù)據是串行從設備中輸出的。這種順序操作使NAND閃存不適合存儲程序代碼,因為訪問時間太長。相比之下,NOR閃存類似于傳統(tǒng)的字節(jié)或字范圍內存。NOR閃存可以像讀取ROM器件一樣讀?。簲嘌云骷x擇和地址,并在從總線讀取數(shù)據之前等待訪問時間。 NOR閃存用于MAXQ處理器系列。
MAXQ處理器中的閃存
MAXQ處理器中使用的閃存塊擦除為“1”狀態(tài)。因此,擦除后,塊中的每個位置都將包含0xFFFF。對閃存位置進行編程會將一些位從“1”狀態(tài)更改為“0”狀態(tài)。要將編程位返回到“1”狀態(tài),必須擦除整個塊。
任何電動可擦除存儲設備都必須面對的問題是耐用性。根據具體技術的不同,閃存單元在永久失效之前可以承受低至 1,000 次或多達 1,000,000 次擦除程序周期。因此,任何使用閃存進行數(shù)據存儲的方案都必須確保寫入周期在陣列中均勻分布,并且沒有一組位置比另一組位置更頻繁地被擦除和編程。
大多數(shù)閃存設備將允許先前編程位置中的任何未編程位從“1”更改為“0”狀態(tài)。例如,大多數(shù)設備允許使用值0xFFFE編程的位置隨后使用值0x7FFE進行編程,因為這不會將任何位值從“0”更改為“1”。然而,MAXQ系列器件中使用的閃存不允許對先前編程的位置進行重新編程,即使沒有嘗試將“0”位改回“1”。此類寫入嘗試將失敗,使值保持在 0xFFFE。
在MAXQ器件中存在這種編程限制是有充分理由的。正在編程的內存塊主要用作代碼空間,因此謹慎的做法是禁止對先前寫入的位置進行任何寫入操作。由于指令0xFFFF指定了無效的源子解碼,因此它不太可能出現(xiàn)在有效的代碼塊中。因此,阻止寫入先前編程的位置有助于保持代碼塊的完整性。
使用MAXQ2000的設計方案
本文重點介紹MAXQ器件:MAXQ2000。該微控制器具有 64kB 的程序存儲,由 128 個塊組成,每個塊 256 個 16 位字。下面介紹兩種設計方案。第一種方案適用于只寫入一次,然后在產品生命周期內不經常更改的信息,例如校準數(shù)據、版本信息和功能字符串。第二種方案是一種更通用的機制,旨在容納更頻繁更改的數(shù)據,例如使用信息或詳細記錄。
方案 1
問題:校準數(shù)據需要存儲在產品中。有時,產品需要重新校準,因此校準數(shù)據必須存儲在可重寫存儲器中。
解決方案:這實際上是可以想象的最簡單的情況。MAXQ2000程序閃存陣列中的兩個模塊保留用于校準數(shù)據存儲,一個位于字地址0x7E00,另一個位于0x7F00。第一次收到保存校準數(shù)據的命令時,MAXQ2000檢查兩個模塊,發(fā)現(xiàn)它們都是空白的。校準數(shù)據將保存到第一個模塊中。
在保存校準數(shù)據的第二個命令中,MAXQ2000再次檢查兩個模塊。當它發(fā)現(xiàn)塊 0 正在使用時,它會將校準數(shù)據復制到塊 1,然后擦除塊 0。
當收到讀取校準數(shù)據的請求時(例如上電時),MAXQ2000讀取兩個模塊以確定哪個模塊正在使用。無論哪個塊未擦除,都用于將設備配置為其校準狀態(tài)。
該方案的主要優(yōu)點是簡單。如果應用程序需要在上電(或其他配置還原事件)進行塊配置,則此方法非常有效。read 例程接受單詞指針并返回該地址處的值;寫入例程接受字指針,并嘗試在該地址處執(zhí)行寫入周期。擦除例程只是擦除兩個塊。
這種方案有一個缺點:例程非常簡單。不會嘗試確定寫入是否會成功。嘗試寫入,如果寫入失敗,則不執(zhí)行任何操作來嘗試解決問題。這種限制就是該方案僅用于寫入已知空白塊的原因。
方案 2
問題:需要非易失性存儲來跟蹤能源使用情況和其他頻繁變化的數(shù)據。更新從每周幾次到每天幾次不等。電表是挑戰(zhàn)的一個很好的例子。
解決方案:在這種情況下,即使是傳統(tǒng)的EEPROM也需要幫助。問題在于:頻繁的更新以及所有電可擦除存儲器技術都具有有限的寫入壽命這一事實,因此無法一遍又一遍地寫入和擦除單個EEPROM單元??紤]每小時更新的情況。具有 10,000 次寫入擦除周期限制的 EEPROM 將在短短一年多內耗盡,遠低于為電表制定的十年設計目標。
這個問題的解決方案是實現(xiàn)某種形式的“磨損均衡”。這種方法意味著不會一遍又一遍地寫入單個位置。相反,寫入周期分布在整個內存陣列上,適當?shù)?a target="_blank">索引分布類似。
磨損均衡是一種眾所周知的技術,僅用于此目的的閃存設備。算法可能很復雜且難以理解。但就我們的目的而言,一個更簡單的機制就足夠了。
在此實現(xiàn)中,存儲數(shù)組中的數(shù)據項不是按地址引用,而是按數(shù)據元素編號引用。數(shù)據元素編號是唯一標識數(shù)據元素的任意 8 位值。因此,在此方案中最多可以有 255 個數(shù)據元素(保留數(shù)據元素 0)。每個數(shù)據元素都有:一個包含數(shù)據元素編號和數(shù)據元素長度的雙字節(jié)標頭(參見圖 1);指示一個、兩個、三個或四個 2 位字的 16 位代碼,如果需要,還有足夠的空間用于錯誤管理。
圖1.數(shù)據元素標頭的結構。
若要寫入數(shù)據元素,寫入子例程必須知道要寫入的數(shù)據、數(shù)據元素的長度以及要寫入數(shù)據的位置。確定數(shù)據將寫入的地址很簡單;數(shù)據元素(無論是新元素還是對現(xiàn)有元素的更新)都寫入存儲陣列的末尾。write 函數(shù)查找數(shù)組的末尾,然后緊跟在最后一條記錄之后寫入新的數(shù)據元素。如果 Flash 頁面中沒有足夠的空間來包含指定長度的記錄,則會寫入頁末標記并打開一個新頁面。有關典型數(shù)據頁的結構,請參見圖 2。
在此數(shù)據頁中,數(shù)據元素 1 是首先寫入的,并且經常更新。接下來編寫了數(shù)據元素 4,并且從未更新過。然后寫入數(shù)據元素 3,并已更新七次。最后,數(shù)據元素 2 已寫入且從未更新。
頁結束標記的存在表示進行了數(shù)據寫入嘗試,但數(shù)據元素太長,無法容納在頁面上。將打開一個新頁面以容納數(shù)據元素。整個數(shù)據結構的末尾由一個空白元素指定,其中的元素標頭應位于該空白元素的位置。
數(shù)字2. 典型的數(shù)據頁面。
請注意,此方案尚未解決重復記錄的問題。這是因為重復記錄不是問題。事實上,讀取和寫入例程完全忽略了重復記錄。寫入時,新記錄位于數(shù)組的末尾,無論是否已存在相同編號的記錄。讀取時,僅檢索與請求的記錄編號匹配的最后一條(因此也是最新的)記錄。
從數(shù)組中讀取數(shù)據元素比寫入更復雜。read 函數(shù)接受數(shù)據元素內容應寫入的元素編號和地址。調用時,read 函數(shù)從頭開始搜索數(shù)組。當它找到與請求的數(shù)據元素匹配的記錄時,它會存儲地址并繼續(xù)搜索。如果找到另一個匹配的記錄,則讀取函數(shù)會將存儲的地址替換為新地址。當?shù)竭_數(shù)組的末尾時,存儲的地址將指向所請求記錄的最新寫入副本。然后,read 函數(shù)將此數(shù)據復制到調用函數(shù)時傳遞的緩沖區(qū)。
盡管已經提出了一種可行的只讀機制來存儲和檢索存儲陣列中的記錄,但仍然存在一個問題:沒有重用過時記錄副本占用的空間的機制。(也沒有刪除記錄的機制,但由于此方案的結構是在嵌入式應用程序中工作的,因此這可能不是一個關鍵功能。如果不恢復一些空間,分配的空間將很快耗盡。然而,恢復空間意味著擦除整個頁面,因為閃存一次只能擦除一整頁。這個問題更加復雜,因為Flash頁面不能被任意刪除而不會刪除有用信息的風險。唯一的選擇是在擦除舊頁面之前將活動信息復制到新頁面。
從過時的記錄中恢復空間的過程分為三個階段。首先,打開新的 Flash 頁面,并將每個數(shù)據元素的最新版本復制到新頁面中。其次,舊頁面被擦除。最后,將頁面標記放置在新頁面上,以便讀取例程可以找到它們。
第一階段有些復雜,需要更詳細地檢查。執(zhí)行此步驟的一種簡單方法是將其分為兩個子步驟:首先,使用 RAM 數(shù)組存儲數(shù)組中最新記錄的記錄編號和地址;其次,逐步執(zhí)行 RAM 陣列,將最新記錄復制到新的閃存頁面。這個過程將是快速且相對簡單的。
這種雙子步方案的問題在于MAXQ2000具有1k字的RAM。上述方案將可存儲的唯一數(shù)據量限制為緩沖區(qū)可以保留的 RAM 大小。這顯然是不可接受的。
解決這一難題非常耗時,但無論存儲陣列變得多大(在合理范圍內)都有效。與其在 RAM 中構建指針列表,不如為每個唯一條目通過源數(shù)組進行多次傳遞。因此,壓縮算法變?yōu)椋?/p>
從源數(shù)組中讀取元素。
在目標數(shù)組中搜索元素。如果找到,則該元素已被寫入。遞增源指針并返回到 1。
掃描源數(shù)組以查找元素的最新副本。
將數(shù)據元素的最新副本寫入目標數(shù)組。
遞增源指針并返回到 1。
最后,目標數(shù)組中的每個唯一數(shù)據元素只有一個條目。
圖 3
給出了打包頁面的圖示?,F(xiàn)在可以安全地擦除源頁面,并將頁眉寫入目標數(shù)組。
圖3.空間恢復后,圖 2 的數(shù)據頁將如下所示。
此過程的結構對于存儲的數(shù)據盡可能安全。但是,在使用閃存設備時必須面對一個危險:寫入或擦除操作期間的電源故障。如果電源出現(xiàn)故障,則一個或多個頁面可能會損壞(在寫入的情況下)或未完全擦除(在擦除操作的情況下)。但緊湊的操作本質上是安全的。請考慮以下方案:
如果在打包操作期間發(fā)生電源故障,源頁將保持完全完整。電源恢復后,可以輕松識別新寫入的頁面(它們沒有頁面標題)并擦除,并重新啟動包操作。
如果在擦除舊頁面時發(fā)生電源故障,則它們可能包含無效的標題。可以擦除這些頁面,并將標題添加到新頁面。
如果在將頁眉寫入新頁時發(fā)生電源故障,則數(shù)據保持不變??梢灾匦聠禹撁几虏僮?。
簡而言之,不應存在任何機制,通過這種機制,意外事件可以不可挽回地損壞陣列數(shù)據。
方案 2 增強功能
此處介紹的存儲子系統(tǒng)沒有錯誤檢測機制。數(shù)據元素標識符中存在未提交的可用位(如所示的六個位)??梢允褂肅RC6算法(x6+ x + 1) 計算跨數(shù)據元素的 CRC,以確保沒有發(fā)生讀取或寫入錯誤。雖然這不是一個特別健壯的算法(它會錯過 64 個多位錯誤中的一個),但它會檢測可能發(fā)生的大多數(shù)實際錯誤。
系統(tǒng)的另一個限制是讀取訪問時間必然很長。對于每次讀取,都必須讀取數(shù)組中的每條記錄才能找到最新的記錄。有三種方法可以縮短訪問時間:
在數(shù)據元素中為前向指針留一個空白字。更新值時,填寫指向新條目的轉發(fā)指針。這樣,可以將表作為鏈表遍歷。
向后遍歷表?,F(xiàn)在只需在請求元素第一次出現(xiàn)時停止。
如果只有少量唯一元素,請在啟動時創(chuàng)建一個包含元素 ID 和指針的 RAM 數(shù)組。后續(xù)訪問非???。只需讀取 RAM 數(shù)組即可確定從何處獲取數(shù)據元素。
結論
非易失性數(shù)據存儲是每個設計工程師遲早必須面對的一個因素。有了MAXQ處理器靈活的閃存,再也沒有理由求助于小型串行存儲器來存儲配置數(shù)據。
審核編輯:郭婷
-
微控制器
+關注
關注
48文章
7454瀏覽量
150853 -
處理器
+關注
關注
68文章
19100瀏覽量
228814 -
存儲器
+關注
關注
38文章
7430瀏覽量
163514
發(fā)布評論請先 登錄
相關推薦
評論