内存检测方法
1.電路的制作工藝錯誤:在焊接電路的時候,可能會出現焊錫飛濺的情況,使得兩個引腳短路,這樣的后果是,當你對存儲器進行操作的時候,就會數據重疊,甚至于說,出現無法讀取的數據;焊接操作不當或者銅板刻制出錯,出現開路的情況,可能會出現對存儲器無法操作或者數據操作不成功的情況。
2.電路的電容性:假設使用的芯片頻率足夠快,你進行一個寫操作,為了檢驗,你再進行一個讀操作,那么問題來了,如果電容性,雖然你可能檢測到的數據是你想要的,但是這時這個數據是由于讀寫操作太快,而來不及反翻轉,那么這樣的芯片實際上是不能存儲你檢測到的那么多的數據的。
3.存儲芯片錯誤放置,其實這樣的情況很容易避免的,這樣的問題,進行檢測的時候,都會自動的檢測出來。
現在介紹三種檢測方法,數據總線檢測,地址總線檢測,設備檢測。
數據存取正常是在控制總線(地址總線)正常的情況下進行的,而設備檢測需要確定地址總線和數據總線已經正常工作了。
1.數據總線檢測,通常采用的方法使用0~1對存儲的每一個bit位進行遍歷,
每次的讀寫操作,每個數據位之間都是獨立的。如圖所示,好像“1”從右邊走到了左邊,所以這種方法也叫作“walking 1”.
typedef unsigned char datum; /* 設置數據總線寬度為8bit */ /********************************************************************** * * 函數名: memTestDataBus * * 函數內容: 在指定的地址下,用walking 1的方法對數據總線進行檢測 * 地址通過函數參數指定。 * * 輸入參數: address 需要檢測的內存地址 * * 返回值: 返回'0',則沒有問題,如果返回其他值, * 則說明檢測失敗有數據位操作有問題 * **********************************************************************/ datum memTestDataBus(volatile datum * address) { datum pattern; /* * 在指定的地址下執行對數據線進行walking 1檢測 */ for (pattern = 1; pattern != 0; pattern <<= 1) { /* * 寫入檢測數據 */ *address = pattern; /* * 讀回數據 */ if (*address != pattern) { return (pattern); } } return (0); } /* memTestDataBus() */2.地址總線檢測:對芯片的每一個地址進行寫0和1,同時確定引腳之間相互獨立。
這個和數據總線檢測的walking 1的方法是類似(對一個16bit的總線來說,地址可以是0000H,0001H,0002H,0004H,0008H,0010H,0020H,0080H等等),并且在你寫入的同時,你需要檢測其他的地址沒有被重寫。
但是不是所有的地址線可以通過這樣的方法檢測,比如你的地址總線寬度是32bit,尋址空間是4GB,如果你要測試128K的內存塊,那么其實只有17根總線用到了, 仍有15根總線沒有用到。
確定兩個存儲之間沒有重疊
/********************************************************************** * * 函數名: memTestAddressBus() * * 函數描述: 這個測試可以找出某個bit位上的錯誤,比如,卡高,卡低 * 短路。基礎地址和區域大小可以由函數參數指定。 * 輸入參數: 基礎地址, * * 返回值 : 如果地址總線沒有,返回空值。 * 返回的非零的結果,是函數執行時遇見的第一個出現地址 * 重疊的。通過檢查存儲的內容,可以知道關于這個存儲問 * 題是卡高,卡低,短路。 * **********************************************************************/ datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes) {unsigned long addressMask = (nBytes/sizeof(datum) - 1);unsigned long offset;unsigned long testOffset;datum pattern = (datum) 0xAAAAAAAA;datum antipattern = (datum) 0x55555555;/** 在每一個偏置電源下,對每一個地址位寫初值操作*/for (offset = 1; (offset & addressMask) != 0; offset <<= 1){baseAddress[offset] = pattern;}/** 檢查地址位卡低*/testOffset = 0;baseAddress[testOffset] = antipattern;for (offset = 1; (offset & addressMask) != 0; offset <<= 1){if (baseAddress[offset] != pattern){return ((datum *) &baseAddress[offset]);}}baseAddress[testOffset] = pattern;/** 檢查地址位卡高*/for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1){baseAddress[testOffset] = antipattern;if (baseAddress[0] != pattern){return ((datum *) &baseAddress[testOffset]);}for (offset = 1; (offset & addressMask) != 0; offset <<= 1){if ((baseAddress[offset] != pattern) && (offset != testOffset)){return ((datum *) &baseAddress[testOffset]);}}baseAddress[testOffset] = pattern;}return (NULL); } /* memTestAddressBus() */3.設備檢測,存儲器中每一位都可以存儲0或1,雖然這句話很簡單,很粗暴,但是所花的時間比前面兩個多了不少。
在設備檢測過程中,你需要對所有的內存空間進行兩次讀寫操作,第一次將一個隨機數寫讀該地址,第二次將這個隨機數取反再次寫讀。在檢測中常用的方法是,隨著地址的變化,存儲的值逐漸增加。
如下圖所示:
第一列和第二列是地址和數據的變化,第三列是數據取反之后的變化。取數值的方式有很多種,但是這種順序變化的方式更加的容易計算。
/********************************************************************** * * 函數名: memTestDevice() * * 函數描述: 用數據遞增/遞減的方式檢測整個物理存儲區域。 * 在這個過程中設備里的每一個存儲位用bit1或者bit0進行 * 檢測。通過形參傳遞基礎地址和檢測區域大小。 *輸入參數: 基礎地址 baseAddress,檢測區域大小 * * 返回值: 如果檢測成功,則返回空值。 * 如果檢測失敗,會返回一個第一次檢測失敗的內存地址。同時 * 檢測內存內容,可以得到這個問題更多詳細信息。 * **********************************************************************/ datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes) {unsigned long offset;unsigned long nWords = nBytes / sizeof(datum);datum pattern;datum antipattern;/** 用已知的數據*/for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++){baseAddress[offset] = pattern;}/** 檢測每一個存儲位置,并進行每個bit位進行翻轉*/for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++){if (baseAddress[offset] != pattern){return ((datum *) &baseAddress[offset]);}antipattern = ~pattern;baseAddress[offset] = antipattern;}/** 檢測存儲器中每個已經翻轉的bit位,同時將所有內存置零*/for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++){antipattern = ~pattern;if (baseAddress[offset] != antipattern){return ((datum *) &baseAddress[offset]);}}return (NULL); } /* memTestDevice() */好吧,到了三劍合一的時候了
說了那么多,我們現在來講點實際的。假設現在我們需要檢測一個地址00000000H,大小是64K的內存塊。我們現在以我們剛剛說的順序對三個函數進行調用。對我們的內存進行檢測,得到的代碼如下。
int memTest(void) { #define BASE_ADDRESS (volatile datum *) 0x00000000 #define NUM_BYTES (64 * 1024)if ((memTestDataBus(BASE_ADDRESS) != 0) ||(memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL) ||(memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL)){return (-1);}else{return (0);}} /* memTest() */在檢測中,你可以用一個LED的亮滅來表示內存的檢測的結果,如果返回值不為空,則亮起紅燈。如果返回值為空,則亮起綠燈。
?
總結
- 上一篇: Python学习 数据结构列表字典元组
- 下一篇: python封装vba_VBA类模块封装