赞
踩
上一篇做了stm32系统启动流程的整理分析,中间遇到stm32启动模式的选择和原理。中间也遇到一些不理解的地方,于是着手做了实验,在这里记录一下。
目前stm32支持3种启动模式。
| BOOT0 | BOOT1 | 启动模式 | 启动地址 |
|---|---|---|---|
| 0 | x | flash | 0x0800 0000 |
| 1 | 0 | 系统存储器 | 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启动是个例外,

即使我们选择了RAM启动,我们也无法通过0x0来访问0x2000 0000。
那RAM究竟是怎么启动的?
首先,我们已知的,当boot0 = 1,boot1 = 1时,即RAM启动时,cotex-m3一定是从0x0取msp,从0x4取pc,而且启动之后0x2000 0000和 0x0是没有映射在一起的。
所以,我们可以有两种推测:
这个我暂时没有找到什么资料说明,但是二者达到的效果是一样的,我个人更倾向于第二种,好记一点。
截个实际的图,可以看出二者确实是不一样的。

找一个简单的,可以在flash上稳定运行的工程,新建一个RAM启动使用的project Item。

建立这个Item的意义在于,在这里修改的配置,全局宏等,不会影响到flash的那个配置,二者是独立是,而且切换十分方便。

切换之后就会看到左边的工程名不一样了。


除了配置相关,所有添加的代码文件都是公用一套。
之前flash下载的配置大家应该都很熟悉了,

这里我们切换为RAM下载。
先看一下编译文件的大小。

打开map文件

可以看出
生成的bin文件是5884字节大小。
所以,我们给ROM分配的空间大于5884即可。

这里还遇到一个坑,这个最后说。

去掉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

VECT_TAB_SRAM主要用于在systemInit的时候重设中断向量表。


把Boot0和BOOT1接高电平。
RAM启动没法load flash这样烧写进去,也没法断电重启。
主要就是在debug模式下运行。

进入debug后可以单步,可以全速,可以reset。
网上有些帖子说他们没法reset我倒是没遇到,都是可以正常跑的。
跑起来有时候会不太稳定,报错从debug模式退出,不过也能用。

看图跑了挺久都在跑。
之前做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操作就异常,访问了非法地址。
改小之后就正常了。

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。