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