微處理器:LPC2114
編譯環境:Keil MDK V4.10
思路:
常把單片機系統的複位分為冷啟動和暖開機。所謂冷啟動,也就是一般所說的上電複位,冷啟動後片內外RAM的內容是隨機的,通常是0x00或0xFF;單片機的暖開機是通過外部電路給運行中的單片機的複位端一複位電平而實現的,也就是所說的按鍵複位或看門狗複位。複位後,RAM的內容都沒有改變。在某些場合,必須區分出裝置的重啟是熱重啟還是冷重啟。常用的方法是:確定某記憶體單位為標誌位(如0x40003FF4~0x40003FF7
RAM單元),啟動時首先讀該記憶體單元的內容,如果它等於一個特定的值(例如為0xAA55AA55),就認為是暖開機,否則就是冷啟動。
根據以上的設計思路思路定義一個變數:
uint32 unStartFlag;
在程式啟動時判斷:
if(unStartFlag==0xAA55AA55)
{
//暖開機處理
}
else
{
//冷啟動處理
unStartFlag=0xAA55AA55;
}
然而實際調試中發現,無論是暖開機還是冷啟動,開機後所有記憶體單元的值都被複位為0,當然也實現不了暖開機的要求。通過看keil MDK內建的啟動代碼Startup.s,在這個啟動代碼中也並沒有發現將整個RAM地區清零的語句。反組譯工具,發現從啟動代碼執行結束到跳轉到main函數過程中,編譯器還執行了很多庫函數,其中__scatterload_zeroinit函數將所有W/R RAM都初始化為0(預設設定下)。為了判斷冷、暖開機,必須人為控制某些特定RAM在複位時不被編譯器初始化為0。通過尋找編譯器手冊,在為處理器的RAM中分出一塊小片RAM,設定為NoInit格式(不對其初始化為0),如:
然後使用__at關鍵字將冷、暖開機標誌位定位到這個NoInit地區:
uint32 unStartFlag __at (0x40003FF4);
這樣,當暖開機時,變數unStartFlag所在的記憶體地區就不會被初始化為0,也實現了冷暖開機的判斷。
定義鐵電0xFF7~0xFF8地區儲存冷啟動次數
0xFF9~0xFFA地區儲存暖開機次數
0xFFB~0xFFC地區儲存總啟動次數