1. 引言
上一篇做了stm32系統啟動流程的整理分析,中間遇到stm32啟動模式的選擇和原理。中間也遇到一些不了解的地方,于是着手做了實驗,在這裡記錄一下。
2. 三種啟動模式
目前stm32支援3種啟動模式。
BOOT0 | BOOT1 | 啟動模式 | 啟動位址 |
---|---|---|---|
x | flash | 0x0800 0000 | |
1 | 系統存儲器 | 0x1FF00000 | |
1 | 1 | RAM | 0x2000 0000 |
從flash和系統存儲器啟動,系統都會做一個位址的映射。
STM32把從0x00000000到0x0005FFFF的區域作為啟動空間(boot space)的别名區。
比如從flash啟動,這種情況下,通路0x0 位址 和 0x0800 0000,是完全一樣的。
是以在啟動後,cotex-M3從0x0位址取MSP,從0x4取PC,就是從0x8000000和0x08000004取。是等價的。
但是,RAM啟動是個例外,
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9cnT5dGROl3ZU50MRpnYoJ1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL2IzMxAzMxIjM4ADNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
即使我們選擇了RAM啟動,我們也無法通過0x0來通路0x2000 0000。
那RAM究竟是怎麼啟動的?
3. RAM啟動
3.1 原理
首先,我們已知的,當boot0 = 1,boot1 = 1時,即RAM啟動時,cotex-m3一定是從0x0取msp,從0x4取pc,而且啟動之後0x2000 0000和 0x0是沒有映射在一起的。
是以,我們可以有兩種推測:
- 系統沒有做0x2000 0000到0x0的映射,而是通過系統的内部方式在啟動時把0x2000 0000和0x20000004的值賦給了SP和PC。
- 系統在上電時刻做了0x2000 0000到0x0的映射,啟動後(取完MSP和PC),斷開了這個映射,之後兩段空間獨立開。
這個我暫時沒有找到什麼資料說明,但是二者達到的效果是一樣的,我個人更傾向于第二種,好記一點。
截個實際的圖,可以看出二者确實是不一樣的。
3.2 實驗步驟
3.2.1 建立一個RAM的project Item
找一個簡單的,可以在flash上穩定運作的工程,建立一個RAM啟動使用的project Item。
建立這個Item的意義在于,在這裡修改的配置,全局宏等,不會影響到flash的那個配置,二者是獨立是,而且切換十分友善。
切換之後就會看到左邊的工程名不一樣了。
除了配置相關,所有添加的代碼檔案都是公用一套。
3.2.2 修改ROM和RAM位址
之前flash下載下傳的配置大家應該都很熟悉了,
這裡我們切換為RAM下載下傳。
先看一下編譯檔案的大小。
打開map檔案
可以看出
生成的bin檔案是5884位元組大小。
是以,我們給ROM配置設定的空間大于5884即可。
這裡還遇到一個坑,這個最後說。
3.2.3 debug頁籤設定
去掉Load Application at startup
加載一個CpuRam.ini,這個檔案我也是網上找的。
/*----------------------------------------------------------------------------
* Name: Dbg_RAM.ini
* Purpose: RAM Debug Initialization File
* Note(s):
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* This software is supplied "AS IS" without warranties of any kind.
*
* Copyright (c) 2008-2011 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Setup() configure PC & SP for RAM Debug
*----------------------------------------------------------------------------*/
FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // Setup Stack Pointer
PC = _RDWORD(0x20000004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}
FUNC void OnResetExec (void) { // executes upon software RESET
Setup(); // Setup for Running
}
load %L incremental
Setup(); // Setup for Running
g, main
3.2.4 添加全局宏VECT_TAB_SRAM
VECT_TAB_SRAM主要用于在systemInit的時候重設中斷向量表。
3.2.5 配置Utilies頁籤
3.2.6 修改硬體boot引腳電平
把Boot0和BOOT1接高電平。
3.2.7 debug模式運作
RAM啟動沒法load flash這樣燒寫進去,也沒法斷電重新開機。
主要就是在debug模式下運作。
進入debug後可以單步,可以全速,可以reset。
網上有些文章說他們沒法reset我倒是沒遇到,都是可以正常跑的。
跑起來有時候會不太穩定,報錯從debug模式退出,不過也能用。
看圖跑了挺久都在跑。
4. 遇到的坑
之前做RAM啟動的時候,每次一跑進SystemInit就進入硬體異常,弄得我十分郁悶,感覺就是一壓棧就異常,但是我跟蹤MSP又确實是按我想的變化,就很郁悶,找了大半天發現原因。
之前在 stm32中文手冊中看到這一段,
我測試用的stm32f103,我以為RAM都是64k,即0x2000 0000~0x20010000,是以ROM分的是0x2000 0000~0x2000 8000 ,ram分的是0x2000 8000 ~ 0x 2001 0000。
實際根本不是這樣,stm32f103c8t6 ram隻有20k,是以一對SP操作就異常,通路了非法位址。
改小之後就正常了。
5. 參考連結
- STM32啟動過程解讀與跟蹤驗證
- STM32 Debug in RAM 在RAM中調試STM32