STM32從Flash啟動的過程,主要是從上電復位到main函數的過程,主要有以下步驟:
1.初始化堆棧指針 SP=_initial_sp,初始化 PC 指針=Reset_Handler
2.初始化中斷向量表
3.配置系統時鐘
4.調用 C 庫函數_main 初始化用戶堆棧,然後進入 main 函數。
以上部分在啟動文件中實現,啟動文件通常是命名為"*.s"的文件,該文件通常會放置在工程文件目錄下。
通常實際的操作會比理論知識更好理解,下面,我們用ST的官方Demo板“NUCLEO-F072RB“舉例來描述STM32F072RBT6啟動過程以及如何利用反匯編來定位問題。
參考代碼:Projects\STM32F072RB-Nucleo\Examples\GPIO\GPIO_IOToggle\MDK-ARM
啟動文件:Projects\STM32F072RB-Nucleo\Examples\GPIO\GPIO_IOToggle\MDK-ARM\startup_stm32f072xb.s
編譯工具:MDK5.23(keil)
啟動文件該段代碼主要定義堆棧大小,如下定義:堆大小為0x400, 棧大小為0x200;
從啟動文件67行到128行定義中斷向量表,下圖只是截取部分:
接下來我們用STM32CubeProgram(版本V2.15)讀取Nucleo板Flash的內容,如下:
從以上讀出來的數據我們可以看到
0x08000000:該位置值為0x20000420,系統會把該值送給棧指針SP;
0x08000004:該位置值為0x080000D5,系統會把該值送給PC指針;通過Keil Debug模式,打開Disassembly,我們可以看到該值對應SystemInit初始化,用Stepinto的方式我們可以進到SystemInit()函數,然後進入_main(),初始化棧區,最後進入C語言的Main()函數;從硬體復位到進入main函數就到此為止。
Disassembly:反匯編,將機械代碼還原成匯編代碼,以此了解程序在幹什麼;
從Flash讀出來的數據我們可以看到,0x0800084B,0x08000849分別對應NMI,HardFault中斷,中間地址保留,為0,0x0800084F對應SVCall中斷…… 以此類推。
這部分從Disassembly也可以找到。下圖是參考手冊中的中斷向量表,只截取了部分。
以上主要描述了STM32的啟動過程及如果使用反匯編,下面我們舉例一個如何用STM32Cubeprogram和反匯編來Debug問題。
當Device出現問題,可以嘗試使用Cubeprogram 讀PC指針的值,再用Disassembly去看看程序在什麼地方:
評論
jackice2013
2 個月前