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