【導讀】隨著(zhù)越來(lái)越多的工業(yè)應用對產(chǎn)品的可靠性和安全性要求越來(lái)越高,我們在做產(chǎn)品設計的時(shí)候不僅要正確的實(shí)現產(chǎn)品功能,同時(shí)也需要通過(guò)一些功能安全認證,比如家電行業(yè)的IEC60730等或者ISO13849等。一般的系統故障可以通過(guò)設計的迭代和嚴格測試來(lái)避免,但是硬件的隨機失效理論上是無(wú)法完全消除的,所以要想提高硬件隨機失效的診斷覆蓋率,就需要軟硬件診斷機制來(lái)保障。
作為系統的核心控制部分,MCU主平臺的診斷機制就是最關(guān)鍵的部分。針對一般通用的MCU,以Piccolo C2000系列為例,硬件上提供了一些診斷或者校驗機制,如下所示:
同時(shí)TI也提供了一些軟件診斷方案,如MSP430 IEC60730 Software Package和C2000 SafeTI 60730 SW Packages軟件庫等,可以提供很多的診斷測試功能,例如CPU、時(shí)鐘、外設、RAM等的診斷,已經(jīng)可以滿(mǎn)足一部分的需求。如下圖所示為C2000 SafeTI 60730 SW Packages中的功能和資源消耗。
然而在實(shí)際的應用中,有些安全標準要求對RAM進(jìn)行周期性的在線(xiàn)診斷,同時(shí)不能影響程序的正常運行。但是程序在運行過(guò)程中存儲在RAM中的數據會(huì )實(shí)時(shí)的變化,而RAM的診斷往往會(huì )破壞這些存儲的數據,比如電機控制類(lèi)的實(shí)時(shí)性要求較高的場(chǎng)合。所以在沒(méi)有ECC的情況下,如何對RAM進(jìn)行實(shí)時(shí)在線(xiàn)的診斷是一個(gè)值得討論的問(wèn)題。
下面以電機控制為例,討論硬件校驗的實(shí)現,尤其是RAM在線(xiàn)檢測的過(guò)程。
1. 系統軟件流程
非破壞性的診斷可以放在背景循環(huán)里面進(jìn)行,這些軟件診斷不會(huì )對實(shí)時(shí)性中斷造成影響,例如看門(mén)狗測試,內部
晶振測試,FLASH CRC校驗,靜態(tài)變量RAM CRC校驗,堆棧溢出判斷,以及GPIO口診斷等。另外一些破壞性的或者對實(shí)時(shí)控制有影響的診斷,可以放到主中斷中進(jìn)行,如RAM March校驗,ALU診斷以及CPU寄存器診斷等。具體流程圖如下所示:
2. RAM診斷的方法
以C2000 SafeTI 60730 SW Packages為例,主要提供了兩種RAM檢測方式。
一種是CRC檢測STL_CRC_TEST_testRam,此功能用于測試RAM的位錯誤。該測試以0和1的交替模式填充被測RAM區域,并使用PSA計算RAM的CRC。對于給定的RAM存儲器區域,如果RAM存儲器中沒(méi)有任何stuck bit,則CRC值應始終相同。并行串行分析器(PSA)是c28x器件中的一個(gè)模塊,可用于生成40位給定存儲區域上的CRC。 PSA多項式為Y = x40 + x21 + x19 + x2 + 1。PSA通過(guò)監視數據讀取數據總線(xiàn)(DRDB)來(lái)計算CRC值。 一旦激活就會(huì )監控Data Read Data Bus (DRDB),當CPU通過(guò)DRDB讀取數據時(shí),PSA每個(gè)時(shí)鐘周期會(huì )為DRDB上的數據生成一個(gè)CRC。由于此測試具有破壞性,因此需要將要測試的RAM內容保存到單獨的RAM位置。
當然也可以使用軟件CRC的方式,使用起來(lái)更靈活,并且可以選擇非破壞性的方式來(lái)計算CRC,對一些靜態(tài)常量存儲的區域可以考慮這種CRC方式。另外一點(diǎn)是軟件CRC算法可以更方便的進(jìn)行代碼評估,以滿(mǎn)足不同安全標準的要求。
另一種是MARCH檢測STL_MARCH_TEST_testRam,此功能直接對RAM進(jìn)行32bit的讀寫(xiě)測試,可以選擇進(jìn)行MarchC 13N或者M(jìn)archC-測試。由于此測試具有破壞性,因此也需要將要測試的RAM內容保存到單獨的RAM位置。
3. RAM在線(xiàn)檢測的實(shí)現
由于需要周期性的RAM檢測,以電機控制為例,可以將RAM檢測放到主中斷里面執行。同時(shí)關(guān)鍵是不能影響控制程序的運行和實(shí)時(shí)性,所以主要考慮兩點(diǎn):
第一是主中斷時(shí)間有限,要盡可能減小RAM檢測的時(shí)間,所以可以將RAM分成多個(gè)小段進(jìn)行檢測,每段RAM越小,占用中斷的時(shí)間越小,但是所有RAM檢測一遍的時(shí)間會(huì )變長(cháng),這個(gè)需要綜合考慮。
第二是不能破壞RAM中的變量值,所以在檢測是之前將RAM段中的內容保存到專(zhuān)門(mén)區域,戴檢測完成并且通過(guò)之后,再將保存好的數據恢復過(guò)來(lái),使用memCopy來(lái)提高效率。
具體實(shí)現方法如下:
首先定義好各個(gè)RAM區間的地址范圍,可以參考具體的數據手冊,如下所示:
然后定義好檢測的范圍和每次檢測的數據長(cháng)度:
注意由于STL_MARCH_TEST_testRam函數執行32位讀/寫(xiě)測試,而在測試RAM單元陣列時(shí),由于RAM單元的16位體系結構,所以要求起始地址為偶數,結束地址為奇數,可以測試的最大內存范圍限制為65535個(gè)32位字。所以要求測試長(cháng)度也需要為奇數。
在主中斷里面的RAM在線(xiàn)檢測函數里,首先將要檢測區域的RAM值保存下來(lái):
if ((gStructSTLMonitor.NowRamAddrStart >= MARCH_RAM_START)
&& (gStructSTLMonitor.NowRamAddrStart <= (MARCH_RAM_END-RAM_CHK_NUM)))
{
gStructSTLMonitor.NowRamAddrEnd = gStructSTLMonitor.NowRamAddrStart + RAM_CHK_NUM;
memCopy((uint16_t *)gStructSTLMonitor.NowRamAddrStart,(uint16_t *)
gStructSTLMonitor.NowRamAddrEnd,(uint16_t *)MARCH_RAM_BK);
}
然后進(jìn)行檢測:
gStructSTLMonitor.status = STL_MARCH_TEST_testRam((uint32_t *)
gStructSTLMonitor.NowRamAddrStart,(uint32_t *)gStructSTLMonitor.NowRamAddrEnd);
if(gStructSTLMonitor.status != SIG_RAM_MARCH_TEST)
{
STL_SetFail();
}
else
{
memCopy((uint16_t *)MARCH_RAM_BK,(uint16_t *)(MARCH_RAM_BK + RAM_CHK_NUM),
(uint16_t *)gStructSTLMonitor.NowRamAddrStart);
gStructSTLMonitor.NowRamAddrStart = gStructSTLMonitor.NowRamAddrEnd + 1;
gStructSTLMonitor.gTestStep++;
}
注意檢測成功之后馬上恢復當前區域的RAM值,并為下一次檢測做好準備。如果檢測發(fā)現故障,則進(jìn)入故障處理函數。
參考文檔:
1. IEC60730 Safety Library for TMS320F2806x USER’S GUIDE
2. Safety Manual for C2000™ MCUs in IEC60730 Safety Applications (SPRUHI3A)
推薦閱讀: