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