| 介紹 在嵌入式微控制器應(yīng)用中,通常都要用到非易失性存儲(chǔ)器。無論是掉電時(shí)維持需要保存的設(shè)置,還是存儲(chǔ)公司的重要記錄,可靠的非易失性存儲(chǔ)器都是現(xiàn)代微控制器領(lǐng)域的一個(gè)基本單元。非易失性存儲(chǔ)常常采用外部串行存儲(chǔ)器實(shí)現(xiàn)。多年以來,該領(lǐng)域用到了數(shù)十億顆類似存儲(chǔ)器件,它們的可靠性得到了的廣泛認(rèn)可。目前,存儲(chǔ)器可以做到幾百字節(jié)到1兆字節(jié)甚至更大的容量,在每一個(gè)需要保持設(shè)置的設(shè)備中,都能找到這樣一個(gè)緊湊、廉價(jià)的器件。 包括EEPROM、閃存和旋轉(zhuǎn)式存儲(chǔ)器在內(nèi),所有類型的非易失性存儲(chǔ)器都面臨一個(gè)共同的問題:寫周期被中斷時(shí),數(shù)據(jù)會(huì)丟失。一旦在寫周期執(zhí)行過程中掉電,那么即使再恢復(fù)電源,也很難修復(fù)損壞的數(shù)據(jù)。 本文提出了一種基于事務(wù)的提交-回退機(jī)制,用于保護(hù)一個(gè)外部串行EEPROM存儲(chǔ)器件的內(nèi)容。這些措施同樣適用于大多數(shù)MAXQ微控制器的內(nèi)置EEPROM?梢韵螺d本應(yīng)用的代碼文件(ZIP,20.5kb)。 I2C EEPROM的特點(diǎn) 串行存儲(chǔ)器件有多種接口,但最常用的接口是I2C接口。這種總線接口有很多優(yōu)點(diǎn):高度標(biāo)準(zhǔn)化的接口;控制器和存儲(chǔ)器之間只需兩條線;而且具有靈活的時(shí)序要求,可以由軟件驅(qū)動(dòng)。一個(gè)I2C主機(jī)可以驅(qū)動(dòng)很多I2C從機(jī),從而最大程度減少了主機(jī)的引腳數(shù)。在所有EEPROM器件中,寫周期都要比讀周期長的多。因?yàn)樵趯懼芷谶^程中,電荷需要借助隧道效應(yīng)并通過絕緣層進(jìn)行轉(zhuǎn)移,而這個(gè)過程很費(fèi)時(shí)間。雖然增加電壓可以加快這個(gè)過程,但是過高的電壓會(huì)導(dǎo)致絕緣層的介質(zhì)擊穿,從而損壞器件。典型的EEPROM器件寫周期持續(xù)10毫秒左右;而讀周期通常需要幾百個(gè)納秒。 為了顯著縮短寫周期的時(shí)間,許多I2C EEPROM器件采用頁面模式。該模式允許將多個(gè)字節(jié)傳送到緩存中,然后將數(shù)據(jù)一次性寫入存儲(chǔ)區(qū)。I2C存儲(chǔ)器件的典型頁面尺寸為32字節(jié)。因此,可以在一個(gè)寫周期內(nèi)向EEPROM填入32個(gè)字節(jié)。 這一點(diǎn)非常重要,因?yàn)榇蠩EPROM器件都具有特定的耐久度:即每個(gè)頁面所能承受的寫周期次數(shù)上限。典型的寫周期次數(shù)從10,000到1,000,000次。然而,即使存儲(chǔ)器件能夠承受1百萬次寫周期,軟件也會(huì)很快將其損耗殆盡。軟件每秒僅執(zhí)行100次寫周期,那么不到3個(gè)小時(shí)就會(huì)耗盡器件的寫周期次數(shù)。 考慮到這些基本的EEPROM特性,設(shè)計(jì)者為一個(gè)嵌入式處理器設(shè)計(jì)可靠的非易失存儲(chǔ)系統(tǒng)時(shí),需切記以下幾點(diǎn): 不要在同一頁面上反復(fù)執(zhí)行寫操作。尤其是不要將某個(gè)頁面設(shè)置成寫入任何其它頁面時(shí)都要更新的“目錄”。如果在寫周期過程中電源被中斷,必須提供以下機(jī)制:(1) 檢測被中斷的寫操作;(2) 完成被中斷的操作;(3) 或者將事件回退至寫操作之前的狀態(tài)。必須通過某些數(shù)據(jù)校驗(yàn)機(jī)制(校驗(yàn)和、CRC或消息摘要)來保證數(shù)據(jù)的完整性。 設(shè)計(jì)目標(biāo) 雖然上面提到的EEPROM問題可通過多種非易失文件系統(tǒng)加以解決,但這樣的文件機(jī)制對于小型嵌入式微控制器來說負(fù)擔(dān)過重。很多文件系統(tǒng)需要更多的RAM,遠(yuǎn)遠(yuǎn)超出了小型微控制器所能提供的容量,而且對于多數(shù)應(yīng)用,也不需要一個(gè)完整的文件系統(tǒng)?紤]到這一點(diǎn),下面列出了EEPROM數(shù)據(jù)保護(hù)機(jī)制的設(shè)計(jì)目標(biāo): 精簡:保護(hù)機(jī)制用于存儲(chǔ)校驗(yàn)數(shù)據(jù)的空間不應(yīng)超過EEPROM的10%,它應(yīng)該只需要少量的計(jì)算開銷。 塊大。罕槐Wo(hù)的塊大小,應(yīng)該和EEPROM的寫操作頁面大小一樣。由于EEPROM器件的頁面大小通常是2的偶數(shù)次冪,因此與每個(gè)塊保留1或2個(gè)字節(jié)的做法相比,相同的尺寸大小更便于軟件編碼。 耐久性:每個(gè)保護(hù)周期不要對同一頁面進(jìn)行寫操作。 可靠性:每次掉電情況下,數(shù)據(jù)都應(yīng)是可恢復(fù)的。 這里提到的保護(hù)機(jī)制有6個(gè)接口函數(shù):讀、寫、提交、回退、檢查和清理。 讀函數(shù)接收一個(gè)塊編號(hào)和一個(gè)指向32字節(jié)緩存的指針。如果緩存地址和塊編號(hào)處于有效范圍內(nèi),程序就會(huì)將指定的塊數(shù)據(jù)讀入緩存,并校驗(yàn)數(shù)據(jù)的有效性。它會(huì)返回如下狀態(tài):有效讀(valid read)、無效讀(invalid read)、無效緩存地址(invalid buffer address)、無效頁面編號(hào)(invalid page number)或保護(hù)失敗(protection failure)。 寫函數(shù)接收一個(gè)塊編號(hào)和一個(gè)指向填好數(shù)據(jù)的32字節(jié)緩存的指針。如果緩存地址和塊編號(hào)處于有效范圍內(nèi),程序就會(huì)將數(shù)據(jù)寫入非易失性緩存,并標(biāo)記緩存狀態(tài)以準(zhǔn)備提交。 提交和回退函數(shù),是可以在寫操作之后執(zhí)行的互補(bǔ)型操作。提交函數(shù)將最近被寫入的緩存數(shù)據(jù)復(fù)制到對應(yīng)的存儲(chǔ)區(qū)最終位置,并為下一個(gè)待寫入的數(shù)據(jù)塊準(zhǔn)備好緩存結(jié)構(gòu)。回退函數(shù)實(shí)際上就是一個(gè)“取消”操作。它消除最近一次寫操作產(chǎn)生的效果,并為下一個(gè)寫操作準(zhǔn)備好緩存子系統(tǒng)。 檢查函數(shù)讀取存儲(chǔ)器件的每個(gè)數(shù)據(jù)塊,并檢查存儲(chǔ)數(shù)據(jù)的有效性。該函數(shù)還檢查緩存子系統(tǒng),以確保沒有未執(zhí)行的寫操作。任何無效塊或未執(zhí)行的寫操作都會(huì)使檢查函數(shù)返回一個(gè)錯(cuò)誤狀態(tài)。 清理函數(shù)修復(fù)一個(gè)數(shù)據(jù)損壞的EEPROM。實(shí)際上,它將試圖找出發(fā)生的錯(cuò)誤,并采取相應(yīng)的解決措施。關(guān)于這些函數(shù)的更多細(xì)節(jié),參見下面的操作詳解。  圖1. EEPROM存儲(chǔ)器的結(jié)構(gòu)。存儲(chǔ)器被劃分為3個(gè)區(qū)域:主存儲(chǔ)區(qū),包含實(shí)際用戶數(shù)據(jù);校驗(yàn)存儲(chǔ)區(qū),包含主存儲(chǔ)區(qū)每1頁的CRC;緩存,包含存儲(chǔ)臨時(shí)寫入數(shù)據(jù)的四個(gè)緩存。 EEPROM結(jié)構(gòu) 參考上面圖1給出的EEPROM結(jié)構(gòu)。EEPROM包含三個(gè)主要區(qū)域: 主存儲(chǔ)區(qū):EEPROM的最大區(qū)域用于存儲(chǔ)用戶數(shù)據(jù)。在一個(gè)16kB器件內(nèi),包括512頁、每頁32字節(jié)的存儲(chǔ)空間。在這樣的器件中,開始的473個(gè)頁面專門用來存儲(chǔ)數(shù)據(jù)。 校驗(yàn)存儲(chǔ)區(qū):EEPROM的第二個(gè)部分,用于校驗(yàn)主存儲(chǔ)區(qū)每個(gè)頁面的數(shù)據(jù)。校驗(yàn)存儲(chǔ)區(qū)的每1頁都包含15個(gè)16位的CRC值。每1頁的最后1個(gè)CRC用于校驗(yàn)本頁數(shù)據(jù)。校驗(yàn)存儲(chǔ)區(qū)占用31頁(從473到503頁)。 緩存:EEPROM的最后部分,包含由8個(gè)頁面構(gòu)成的4個(gè)寫緩存。每個(gè)緩存包含4個(gè)域:數(shù)據(jù)域,它包含32字節(jié)數(shù)據(jù),執(zhí)行下一個(gè)提交命令時(shí),數(shù)據(jù)將被寫入主存儲(chǔ)區(qū);地址域,它表示緩存數(shù)據(jù)要寫入的頁面地址;狀態(tài)域,它表示緩存的狀態(tài)(包括可用(available)、占用(occupied)和終止(expired)狀態(tài));16位CRC域,用來校驗(yàn)整個(gè)寫緩存。緩存結(jié)構(gòu)見圖1所示。 這種EEPROM結(jié)構(gòu)可以實(shí)現(xiàn)主要的設(shè)計(jì)目標(biāo)。首先,由于主存儲(chǔ)區(qū)每1頁數(shù)據(jù)的校驗(yàn)結(jié)果都存儲(chǔ)在另一個(gè)位置,所以頁面的所有位都用于存儲(chǔ)用戶數(shù)據(jù)。其次,由于主存儲(chǔ)區(qū)的每1頁都通過校驗(yàn)存儲(chǔ)區(qū)的特定字來校驗(yàn),因此校驗(yàn)存儲(chǔ)區(qū)不會(huì)有單點(diǎn)錯(cuò)誤,并且也不會(huì)在每個(gè)寫周期中都去更新整個(gè)校驗(yàn)存儲(chǔ)區(qū)的同一頁面。最后,使用4個(gè)寫緩存分散了寫周期帶來的損耗。 操作詳解 對于一個(gè)不帶保護(hù)功能的EEPROM,具體操作非常簡單。一個(gè)讀周期簡單地將字節(jié)從所選擇的地址傳送給主機(jī);一個(gè)寫周期將字節(jié)從主機(jī)寫入EEPROM,并等待操作完成(大多數(shù)器件需要幾個(gè)毫秒的時(shí)間)。然而,在一個(gè)提供保護(hù)的EEPROM環(huán)境下,讀和寫操作就比較復(fù)雜了。在以下各節(jié)中,對每個(gè)操作進(jìn)行了分解,以便了解函數(shù)被調(diào)用時(shí)到底是如何操作的。 讀操作 |