引言
ECC是微控制器系統(tǒng)中用于保障信息安全的常用機(jī)制,主要是避免存儲設(shè)備中存放的數(shù)據(jù)因硬件干擾被篡改。國產(chǎn)車規(guī)微控制器原廠云途半導(dǎo)體設(shè)計和發(fā)布的YTM32微控制器芯片,全系配備了存儲器的ECC機(jī)制,可以有效的增強(qiáng)芯片運(yùn)行穩(wěn)定性,避免因為內(nèi)存位翻轉(zhuǎn)導(dǎo)致芯片產(chǎn)生嚴(yán)重故障。本文將以YTM32微控制器芯片為例,對內(nèi)存ECC的基本機(jī)制、實現(xiàn)原理和使用時的注意事項等進(jìn)行介紹。
ECC的基本原理
ECC全稱 Error Checking and Correcting,屬于一種錯誤檢查和糾正算法,典型的ECC算法一般可以做到糾正單比特錯誤和檢查2比特錯誤。
在介紹ECC算法之前,先看一種簡單的校驗算法:奇偶校驗。奇偶校驗是在傳輸數(shù)據(jù)流的末尾,增加1個比特的校驗信息,以保證完整的數(shù)據(jù)流中比特位的累加值一定是奇數(shù)或者偶數(shù):若采用偶數(shù)校驗的方式,發(fā)送方對偶數(shù)數(shù)據(jù)補(bǔ)充比特0,對于奇數(shù)數(shù)據(jù)補(bǔ)充比特1,這樣發(fā)送的數(shù)據(jù)一定是偶數(shù),接收方收到數(shù)據(jù)之后就對完整的數(shù)據(jù)幀進(jìn)行判斷, 如果不是偶數(shù)則代表數(shù)據(jù)出錯。通過增加1個比特的額外數(shù)據(jù),接收方就可以判斷數(shù)據(jù)流是否正確,以實現(xiàn)對數(shù)據(jù)的校驗。
但是,使用奇偶校驗機(jī)制對數(shù)據(jù)有效性的判定能力有限:
- 若有2個比特數(shù)據(jù)發(fā)生反轉(zhuǎn),那么接收方依然會判定接收到的數(shù)據(jù)是正常數(shù)據(jù);
- 如果有1個比特數(shù)據(jù)異常,接收方只能判斷數(shù)據(jù)是異常的,并不能從接收到的數(shù)據(jù)恢復(fù)出正確的數(shù)據(jù)(因為無法判斷具體是哪一位出現(xiàn)了異常)。
從上面兩種情況來看,奇偶校驗只能檢驗單個比特的數(shù)據(jù)錯誤。
基于奇偶校驗算法,ECC校驗算法通過增加更多的額外校驗數(shù)據(jù),以實現(xiàn)對傳輸數(shù)據(jù)的錯誤檢查和錯誤糾正。
這里簡單介紹ECC的實現(xiàn)原理。以4-bit ECC計算為例,如圖x所示,假定3個不同顏色的圓相交的4個小格代表著4個bit的數(shù)據(jù),與其他圓沒有交集的那個格就代表著ECC bit,即a4,a5,a6。
figure-ecc-principle-diagram
圖x 4-bit ECC計算方法
這里,人為設(shè)定一個規(guī)則: 每個圓內(nèi)的4個bit異或結(jié)果為0 (類似于奇偶校驗的機(jī)制)。當(dāng)4個bit的數(shù)據(jù)位確定后,例如圖中的1001,即可確定唯一ECC bit結(jié)果,即:a4=1,a5=0,a6=1。此時,發(fā)生任何1個bit的跳變(包括ECC bit),均可被檢查出來并糾正,從而達(dá)到ECC的目的。此處描述的是,每個數(shù)據(jù)位都會和一些ECC位建立約束關(guān)系,但這些數(shù)據(jù)位同時還會同另一些ECC位存在約束關(guān)系,如此,通過數(shù)據(jù)冗余,形成“鐵索連環(huán)”,相互照應(yīng)。以此為基礎(chǔ),使用更多的ECC位(增加數(shù)據(jù)冗余),可以讓數(shù)據(jù)更加“穩(wěn)固”,但也會付出更多存儲空間的代價。
最小ECC bit位數(shù)n要求 :2^n>數(shù)據(jù)位數(shù)+ECC位數(shù)n。
數(shù)據(jù)位每增加1倍,ECC只增加1位檢驗位。設(shè)計ECC時,可以設(shè)計數(shù)據(jù)位是8位對應(yīng)的ECC需要增加5位來進(jìn)行ECC錯誤檢查和糾正,當(dāng)數(shù)據(jù)位為16位時ECC位為6位,32位時ECC位為7位,數(shù)據(jù)位為64位時ECC位為8位,依此類推。
在實際應(yīng)用芯片的場景中,存儲單元(包含芯片內(nèi)部SRAM和Flash)通常發(fā)生的是位數(shù)據(jù)的翻轉(zhuǎn),也就是單比特錯誤居多。針對這種錯誤,ECC一般可以實現(xiàn)1個比特的錯誤糾正和2個比特錯誤的檢查,芯片的ECC組合一般是32+7和64+8的組合方式。如表x所示。
表x 常用的ECC數(shù)據(jù)長度
根據(jù)處理器特性和SRAM以及Flash的應(yīng)用特性,通常在MCU中,一般對SRAM采用32+7的ECC校驗方式,對Flash采用64+8的校驗方式。
ECC RAM的訪問方式和初始化
微控制器系統(tǒng)中的總線在讀寫支持ECC的SRAM時,會通過ECC編碼器(Encoder)和ECC解碼器(Decoder)對寫入和讀出的數(shù)據(jù)進(jìn)行處理,如圖x所示。
- 寫入SRAM數(shù)據(jù)時,總線將計算好該數(shù)據(jù)對應(yīng)的ECC,一并寫入
- 從SRAM讀數(shù)據(jù)時,總線同時讀取數(shù)據(jù)和ECC校驗信息,之后根據(jù)ECC對數(shù)據(jù)進(jìn)行校驗,然后才將數(shù)據(jù)返回系統(tǒng)中使用
figure-bus-access-ecc-mem
圖x MCU總線讀寫帶有ECC的SRAM
在圖x中可以看到,總線對于SRAM的讀寫都是以32位的帶寬進(jìn)行操作的,嵌入在32位總線上的ECC編碼器和解碼器也是基于32位數(shù)操作的,但是,軟件中有很多基于字節(jié)或者半字的操作方式,對于這種情況,總線并不能直接以字節(jié)或者半字節(jié)的方式向SRAM存儲區(qū)中寫數(shù),SRAM控制器首先會讀出SRAM中原有的32位數(shù),修改這個數(shù),重新計算ECC,然后將新的數(shù)據(jù)和ECC計算的結(jié)果一并寫入到SRAM中。
SRAM存儲器中的內(nèi)容在上電之后內(nèi)容是隨機(jī)的,其中的有效數(shù)據(jù)和ECC數(shù)據(jù)并未建立起關(guān)聯(lián)。此時,如果讀取SRAM的內(nèi)容并進(jìn)行ECC校驗,大概率上是會出現(xiàn)ECC錯誤的。因此,在使用支持ECC的SRAM之前,需要手動對SRAM進(jìn)行初始化操作。初始化SRAM的操作,就是簡單地向SRAM中按照32位的寬度寫入一個任意值,通過ECC編碼器計算好ECC數(shù)據(jù)并填充SRAM存儲器即可。注意,初始化的時候必須要按照32位的形式寫入,否則若按照字節(jié)或者半字的方式寫入的時候,系統(tǒng)會先讀后寫,最初讀到的數(shù)也是錯的,會出現(xiàn)ECC錯誤。
ECC的初始化過程一般會被放在MCU的啟動匯編代碼中,此時尚未初始化ECC,不能使用建立在ECC內(nèi)存中的堆棧。以YTM32微控制器芯片為例,其啟動程序使用如下代碼實現(xiàn)對ECC的初始化:
#ifndef START_NO_ECC_INIT
/* Init ECC RAM */
ldr r1, =__RAM_START
ldr r2, =__RAM_END
subs r2, r1
subs r2, #1
ble .LC5
movs r0, 0
movs r3, #4
.LC4:
str r0, [r1]
add r1, r1, r3
subs r2, 4
bge .LC4
.LC5:
#endif
上述代碼中,可以通過定義START_NO_ECC_INIT
宏配置初始化時繞過ECC初始化,ECC的初始化范圍是從__RAM_START
至__RAM_END
,這兩個地址是在linker文件中定義的,用戶可以根據(jù)應(yīng)用需求修改相應(yīng)的地址范圍。注意,這里設(shè)置初始化ECC的地址區(qū)域越大,系統(tǒng)啟動的時間將會越長。
YTM32芯片在SRAM產(chǎn)生ECC錯誤時,會產(chǎn)生Bus Error或者Hard Fault。
用戶在使用過程中,如果發(fā)現(xiàn)芯片在單步調(diào)試過程中使用正常(在斷點(diǎn)時,調(diào)試器會掃描存儲空間),但是在芯片重新上電之后就會出現(xiàn)異常,就可以檢查一下是否SRAM ECC沒有正常初始化,例如上述過程中的START_FROM_FLASH
宏定義是否在匯編調(diào)試階段有定義(針對舊版本SDK)。
還有一種判定ECC未正常初始化的方式,可通過調(diào)試器查看系統(tǒng)的SRAM,如果發(fā)現(xiàn)有的SRAM可以讀,有的SRAM地址無法正確讀,那么就是ECC沒有正常初始化。
RAM ECC錯誤注入及EMU外設(shè)
在程序開發(fā)過程中,考慮到功能安全的需求,還需要考慮出現(xiàn)ECC錯誤情況的處理機(jī)制。實際上,SRAM上比特位翻轉(zhuǎn)是一個小概率事件,在常規(guī)測試過程很難復(fù)現(xiàn)。工程師圈子里有一句廣為流傳的口號,“有困難要上,沒有困難制造困難也要上”。為了人為創(chuàng)造ECC錯誤的情況(以便開發(fā)ECC錯誤處理過程),YTM32的為控制上設(shè)計了一個EMU(ECC Management Unit)的外設(shè)模塊,專門用于主動產(chǎn)生和捕獲ECC錯誤。
EMU模塊在ECC過程中的位置,如圖x所示。
figure-emu-diagram
圖x EMC在ECC過程中的位置
EMU實際上是在SRAM的讀過程中增加的一個模塊,將從SRAM的讀取的數(shù)據(jù)同EMU設(shè)置的一個mask進(jìn)行異或運(yùn)算,從而對讀取數(shù)據(jù)的某個位進(jìn)行翻轉(zhuǎn)(以產(chǎn)生錯誤數(shù)據(jù)),然后送入ECC解碼器,從而模擬SRAM出現(xiàn)ECC錯誤。
另外,EMU還會監(jiān)測ECC解碼器的結(jié)果,當(dāng)產(chǎn)生ECC錯誤的時候,EMU會捕獲這個異常,并記錄出現(xiàn)ECC錯誤的地址和異常類型(單比特錯誤還是多比特錯誤)。應(yīng)用中,可通過讀取EMU的錯誤信息,進(jìn)而決定如何處理ECC錯誤。
對于ECC錯誤的處理方式,可以分為如下幾種情況:
- 如果系統(tǒng)允許復(fù)位的話,可以直接記錄診斷信息后復(fù)位運(yùn)行,這樣SRAM整體都會重新初始化成正常內(nèi)容
- 針對單比特錯誤,因為ECC可以直接糾正結(jié)果,可以直接讀取產(chǎn)生ECC錯誤地址上的內(nèi)容,然后將內(nèi)容重新寫回到該地址,即可恢復(fù)正常。注意,如果ECC錯誤是通過EMU模擬實現(xiàn)的,此時就需要關(guān)閉EMU注入通道,否則再次讀取的時候依然會有ECC錯誤,另外因為ECC是糾1檢2的算法,如果出現(xiàn)多于2比特的錯誤,這種情況SRAM的讀取結(jié)果可能會有正常、單比特錯誤和多比特錯誤幾種結(jié)果。
- 針對多比特錯誤,因為無法恢復(fù)正確信息,應(yīng)用只能向錯誤地址寫入一個默認(rèn)值,或者通過復(fù)位操作恢復(fù)正常值。
Flash ECC校驗
Flash內(nèi)部也是通過電荷狀態(tài)來存儲信息的,雖然Flash中電荷的狀態(tài)大部分時間都是穩(wěn)定的,但是當(dāng)受到某些干擾之后,F(xiàn)lash中電荷狀態(tài)也有可能發(fā)生反轉(zhuǎn)。所以,車規(guī)芯片對Flash的ECC校驗也提出了要求。因為Flash不支持隨機(jī)的寫入,所以ECC的操作方面相對SRAM比較簡單。
首先,F(xiàn)lash初始時擦除狀態(tài),有效數(shù)據(jù)全是1,而對應(yīng)的ECC算法可以保證全1的ECC校驗值也是全1(巧妙?。?,也就是說,F(xiàn)lash擦除狀態(tài)下,對Flash的讀操作并不會產(chǎn)生ECC錯誤。而對Flash的寫入都是通過一系列的命令實現(xiàn)的,在寫入的時候,硬件會自動計算好ECC,再將有效數(shù)據(jù)和ECC校驗值一并寫入到Flash的存儲區(qū)中。寫入完成之后,用戶正常讀取數(shù)據(jù)內(nèi)容即可。這種情況,即使Flash出現(xiàn)單比特的錯誤,ECC解碼器也可以正常糾正,以保證有效數(shù)據(jù)的完整性。
對于功能安全要求比較高的程序,應(yīng)用程序還需要針對Flash的ECC進(jìn)行處理,和SRAM ECC錯誤處理的方式類似,F(xiàn)lash ECC錯誤處理可以分為如下幾種形式:
- 當(dāng)出現(xiàn)單比特數(shù)據(jù)錯誤,由于總線可以自動恢復(fù)正確的原始數(shù)據(jù),應(yīng)用程序可以先記錄相應(yīng)的診斷數(shù)據(jù),然后備份Flash出錯數(shù)據(jù)所在的扇區(qū),再將扇區(qū)擦除后,從備份地址將原有數(shù)據(jù)重新寫入到擦除后到扇區(qū)。
- 當(dāng)出現(xiàn)多比特數(shù)據(jù)錯誤,如果錯誤出現(xiàn)在程序區(qū)域,那么只能記錄診斷數(shù)據(jù),然后嘗試運(yùn)行備份APP程序,嘗試系統(tǒng)復(fù)位,或者重新下載程序。
- 當(dāng)出現(xiàn)多比特錯誤錯誤,如果錯誤出現(xiàn)在數(shù)據(jù)區(qū)域,那么應(yīng)用程序需要嘗試使用默認(rèn)值填充錯誤區(qū)域,相當(dāng)于重新下載程序。
總之,當(dāng)檢測到Flash出現(xiàn)ECC錯誤時,F(xiàn)lash存儲器的內(nèi)容已經(jīng)有風(fēng)險,必須將出現(xiàn)錯誤的扇區(qū)進(jìn)行擦除和重新編程才能從根本上清除掉ECC錯誤。當(dāng)然,同一個地址產(chǎn)生多位的翻轉(zhuǎn)概率還是非常低的,考慮到設(shè)計實現(xiàn)這種自恢復(fù)的機(jī)制也需要消耗相當(dāng)?shù)某杀荆ǜL的開發(fā)周期,更復(fù)雜的應(yīng)用程序,更大的物理存儲空間),開發(fā)者可以酌情采取應(yīng)對策略。
評論
查看更多