#stm32重啟調試筆記
本文章主要解決在使用stm32+ucos進行嵌入式軟件開發中遇到的系統重啟現象查找與解決。
1 、重啟原因
系統重啟又多種可能:1、看門狗中斷;2、內存泄漏;3、軟件重啟。
首先看一下stm32的手冊關于系統重啟的狀態寄存器,其中詳細的記錄了幾個系統重啟的原因(低功耗復位標志、窗口看門狗復位標志、)
寄存器詳細信息:
查看寄存器值
a:通過debug查看,在代碼進入main函數時加入斷電,通過查看RCC寄存器值可以明了的查看相關狀態
b:在查看之后應該清除中斷信息,這樣下次重啟時才能知道重啟原因。加入下面一條語句。
/*打印中斷標志字*/
void print_reboot_flag(void)
{
printf("reboot flag :0x%04Xrn",RCC->CSR); //
/*判斷并打印重啟原因*/
if(RCC->CSR & 1<<31){
printf("reboot error:Low-power!rn"); //低功耗管理
}else if(RCC->CSR & 1<<30){
printf("reboot error:Window watchdog!rn"); //窗口看門狗
}else if(RCC->CSR & 1<<29){
printf("reboot error:Independent watchdog!rn"); //獨立看門狗
}else if(RCC->CSR & 1<<28){
printf("reboot error:Software!rn"); //軟件復位
}else if(RCC->CSR & 1<<27){
printf("reboot error:POR/PDR!rn"); //por/pdr復位
}else if(RCC->CSR & 1<<26){
printf("reboot error:PIN!rn"); //NRST引腳復位
}else if(RCC->CSR & 1<<25){
printf("reboot error:BOR!rn"); //軟件寫入RMVF位清零
}
}
/*清除中斷標志字*/
void clear_reboot_flag(void)
{
RCC->CSR |= 1<<24; //清除
}
/*printf()函數位相應的打印輸出定向函數*/
2、重啟問題解決
重啟原因找到了,下面就是解決重啟問題,上面標識的重啟原因基本是比較容易解決的。
看門狗重啟
出現看門狗異常可能性比較多,程序運行正常軟件喂狗超時,這種情況最好解決,查看喂狗時間可軟甲是否有超時的。
還有一種情況是內存溢出這種問題是作為C/C++程序員來說是最為頭痛的問題。下面單獨講一講出現這種現象是應該向哪個方向去查找。
內存溢出越界訪問
內存溢出也就是會出現程序跑飛,在stm32中常常會出現HardFault_Handler中斷,這種異常也是有兩種可能。
a 有規律的異常HardFault_Handler中斷,這種相對而言是比較容易發現的。比如下面一段代碼
int main(void)
{
uint8_t *str;
while(1)
{
*str++ = 1;
}
}
在代碼中我們對位分配內存的指針進行了操作,程序運行我們將斷電放在HardFault_Handler中斷中,
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1) //在此處加斷電
{
}
}
程序會卡死在斷點處。
1)
通過下面圖片顯示的,在Call Stack中查看在什么地方出現了異常。使用"Show Caller Code"查看相關代碼,同時通過查看此處的相關的數據。
2)
通過查看芯片寄存器來手動查找出現異常的代碼位置
首先查看R14(LR)寄存器
0xFFFFFFF9對應的是要看MSP寄存器
0xFFFFFFFD對應的是要看PSP寄存器
然后對應的通過 MSP或者PSP的寄存器值,在Memory中查到運行地址,然后在Disassembly中查找地址位置。
b
在出現不規律的重啟現象是就比較讓人捉急了,此處記錄一下個人在開發中遇到的幾個重啟問題。
重啟的情況
1、函數內部變量過多使棧內存溢出,這種情況需要增加棧大小heap,在startup_xxx.s文件中。
Heap_Size EQU 0x00000200
1
2、帶任務的工程項目中也可能是出現了堆棧溢出,這種情況可以通過打印free堆棧來進行查看是否已經溢出。
結束
上一篇:STM32開發筆記57: 復位電路設計
下一篇:STM32程序軟件復位
推薦閱讀
史海拾趣