本文轉(zhuǎn)自公眾號(hào),歡迎關(guān)注
嵌入式系統(tǒng)存儲(chǔ)正確性和壓力測(cè)試方案 (qq.com)
前言
在嵌入式系統(tǒng)開(kāi)發(fā)測(cè)試階段通常需要對(duì)存儲(chǔ)進(jìn)行正確性和壓力測(cè)試,比如SRAM,DDR等,通常的做法是進(jìn)行遍歷讀寫(xiě),比如寫(xiě)0x55,0xAA,0x00,0xFF,遞增值等這些特殊值然后再回讀判斷是否正確等,這些測(cè)試用例是根據(jù)存儲(chǔ)的原理和經(jīng)驗(yàn)等進(jìn)行總結(jié)的。實(shí)際上已經(jīng)有人整理了相應(yīng)的測(cè)試用例https://pyropus.ca./software/memtester/就是一個(gè)比較常用的測(cè)試代碼。
這個(gè)代碼最新版本是4.6.0,其為Unix類(lèi)系統(tǒng)上使用設(shè)計(jì),這些系統(tǒng)上可以直接安裝或者源碼編譯使用。
為了方便在MCU等環(huán)境使用,我將其進(jìn)行了一些修改,方便移植使用。
https://github.com/qinyunti/memtester_mcu.git
memtester_mcu使用
clone以下倉(cāng)庫(kù)https://github.com/qinyunti/memtester_mcu.git,添加代碼到自己的目錄即可。
參考README.md
實(shí)現(xiàn)以下依賴即可:
l:memset
l:rand
l:ULONG_MAX
lmemtester_types.h中需要
l定義幾個(gè)數(shù)據(jù)類(lèi)型,ull位使用,ul為無(wú)符號(hào)基本數(shù)據(jù)類(lèi)型。
typedef unsigned long ul;
typedef unsigned long long ull;
typedef unsigned long volatile ulv;
typedef unsigned char volatile u8v;
typedef unsigned short volatile u16v;
l需實(shí)現(xiàn)memtester_printf
然后
#include "memtester.h"
按照如下調(diào)用即可
memtester_main((ulv *)0x20004000, 0, 0x2000, 10);
其中0x20004000為待測(cè)試存儲(chǔ)開(kāi)始地址,要ul對(duì)齊;
第二個(gè)參數(shù)表示測(cè)試用例mask,0表示所有用例都測(cè)試;
0x2000為待測(cè)試存儲(chǔ)區(qū)域大小,要ul對(duì)齊;
最后10為測(cè)試10個(gè)循環(huán),壓力測(cè)試可以將該值寫(xiě)的很大,一直反復(fù)測(cè)試。
測(cè)試用例介紹
memtester_tests.c中一共提供了17個(gè)測(cè)試用例,下面一一介紹。
有一些輔助函數(shù)
compare_regions: 比較兩個(gè)區(qū)域是否一致,按照ulv類(lèi)型比較
test_stuck_address
測(cè)試前先調(diào)用該函數(shù)遍歷測(cè)試一下,該函數(shù)依次寫(xiě)對(duì)應(yīng)地址的內(nèi)容為該地址,該地址的內(nèi)容為該地址的取反,然后下一遍時(shí)反過(guò)來(lái)先寫(xiě)該地址的內(nèi)容為該地址的取反,然后寫(xiě)對(duì)應(yīng)地址的內(nèi)容為該地址,然后再回讀。
測(cè)試第一遍時(shí)
比如開(kāi)始地址為0x20000000基本類(lèi)型為32位,則0x20000000處的值為0x20000000
0x20000004處的值為0xDFFFFFFB;
測(cè)試第二遍時(shí)
比如開(kāi)始地址為0x20000000基本類(lèi)型為32位,則0x20000000處的值為0xDFFFFFFF
0x20000004處的值為0x20000004;
依此類(lèi)推共測(cè)試16遍。
test_random_value :隨機(jī)測(cè)試
先隨機(jī)寫(xiě)待測(cè)試區(qū)域的前面一半和后面一半為同樣的值,然后再回讀前面一半和后面一半是否一樣。
test_xor_comparison :異或隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都和同一個(gè)隨機(jī)值異或,然后再回讀比較。
test_sub_comparison :減隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都減同一個(gè)隨機(jī)值,然后再回讀比較。
test_mul_comparison :乘以隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都乘以同一個(gè)隨機(jī)值,然后再回讀比較。
test_div_comparison:除以隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都除以同一個(gè)隨機(jī)值,然后再回讀比較。
test_or_comparison :或隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都或上同一個(gè)隨機(jī)值,然后再回讀比較。
test_and_comparison :與隨機(jī)值測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都與上同一個(gè)隨機(jī)值,然后再回讀比較。
test_seqinc_comparison:遞增測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容(上一個(gè)測(cè)試的遺留值)都從同一個(gè)隨機(jī)值開(kāi)始遞增,遞增到待測(cè)試基本數(shù)據(jù)的個(gè)數(shù),然后再回讀比較。
test_solidbits_comparison :固定位測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)0xFFFFFFFF和0x00000000然后再回讀比較。
Cesium64輪。
test_checkerboard_comparison :交錯(cuò)位測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)0x55555555和0xAAAAAAAA然后回讀測(cè)試。
測(cè)試64輪。
test_blockseq_comparison :字節(jié)遞增測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)0x00000000-0x01010101~0x02020202...0xFFFFFFFF這中字節(jié)遞增,然后回讀測(cè)試。
test_walkbits0_comparison :1滑動(dòng)測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)如下值然后回讀測(cè)試:
共64輪
前面32輪的值
第一輪寫(xiě)0x00000001
第二輪寫(xiě)0x00000002
1往左滑動(dòng)
后面32輪反向滑動(dòng)
第32輪寫(xiě)0x80000000
第33輪寫(xiě)0x40000000
test_walkbits1_comparison :0滑動(dòng)測(cè)試
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)如下值然后回讀測(cè)試:
共64輪
前面32輪的值
第一輪寫(xiě)0xFFFFFFFE
第二輪寫(xiě)0xFFFFFFFD
0往左滑動(dòng)
后面32輪反向滑動(dòng)
第32輪寫(xiě)0x7FFFFFFF
第33輪寫(xiě)0xBFFFFFFF
test_bitspread_comparison :間隔1,0滑動(dòng)測(cè)試
與1滑動(dòng)類(lèi)似,只是使用間隔1位的兩個(gè)1進(jìn)行滑動(dòng)
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容依次寫(xiě)如下值然后回讀測(cè)試:
共64輪
前面32輪的值
第一輪寫(xiě)
(1<<0) | (1<<2) ~
0xFFFFFFFF ^ (1<<0) | (1<<2)~ 取反
(1<<0) | (1<<2)~ 后面重復(fù)
0xFFFFFFFF ^ (1<<0) | (1<<2)
第二輪寫(xiě) 在第一輪基礎(chǔ)上滑動(dòng)
(1<<1) | (1<<3) ~
0xFFFFFFFF ^ (1<<1) | (1<<3)~ 取反
(1<<1) | (1<<3) ~ 后面重復(fù)
0xFFFFFFFF ^ (1<<1) | (1<<3)
后面32輪反向滑動(dòng)
第32輪寫(xiě)
(1<<31) | (1<<33) ~
0xFFFFFFFF ^ (1<<31) | (1<<33)~ 取反
(1<<31) | (1<<33)~ 后面重復(fù)
0xFFFFFFFF ^ (1<<31) | (1<<33)
第33輪寫(xiě) 在第一輪基礎(chǔ)上滑動(dòng)
(1<<30) | (1<<32) ~ 取反
0xFFFFFFFF ^ (1<<30) | (1<<32)~ 后面重復(fù)
(1<<30) | (1<<32) ~
0xFFFFFFFF ^ (1<<30) | (1<<32)
test_bitflip_comparison :位翻轉(zhuǎn)
32輪
第一輪
重復(fù)8次
1<<0,0xFFFFFFFF^(1<<0) 重復(fù)到寫(xiě)完緩沖區(qū)
第2輪
重復(fù)8次
1<<1,0xFFFFFFFF^(1<<1) 重復(fù)到寫(xiě)完緩沖區(qū)
...
第32輪
重復(fù)8次
1<<31,0xFFFFFFFF^(1<<31) 重復(fù)到寫(xiě)完緩沖區(qū)
test_8bit_wide_random :字節(jié)寫(xiě)
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容分別按照基本類(lèi)型操作和字節(jié)操作方式寫(xiě)入隨機(jī)值然后回讀對(duì)比
test_16bit_wide_random :16位寫(xiě)
將待測(cè)試區(qū)域前面一半和后面一半的內(nèi)容分別按照基本類(lèi)型操作和16位操作方式寫(xiě)入隨機(jī)值然后回讀對(duì)比
實(shí)測(cè)
移植比較簡(jiǎn)單,參考README.md即可,在某個(gè)CORTEX-M3的MCU上測(cè)試如下
總結(jié)
以上測(cè)試可以看出
1.盡可能的隨機(jī),以避免每次測(cè)試都一樣,rand還可以先srand一下使得每次測(cè)試都不一樣。
2.測(cè)試相鄰位的影響,0x55,0xAA, 全0全0等,比如1和0的滑動(dòng),間隔1,0的滑動(dòng),位翻轉(zhuǎn)等。
3.遍歷到所有的值,比如遞增,隨機(jī)值等。
我們還可以添加總結(jié)自己的用例進(jìn)行完善,實(shí)際測(cè)試時(shí)也可減少一些循環(huán)次數(shù)加快測(cè)試。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19104瀏覽量
304797 -
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3587瀏覽量
129435 -
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4296瀏覽量
85798 -
sram
+關(guān)注
關(guān)注
6文章
767瀏覽量
114675 -
移植
+關(guān)注
關(guān)注
1文章
379瀏覽量
28124
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論