STM32 启动疑问

2019-07-21 01:30发布

看了很多资料,现有疑问如下(假设程序从flash启动):

1、第一条指令到底在什么位置?
  无论是网上的博客还是正点的教程,都是复位后从0x08000000取第一条指令,但是看内核编程手册,MSP和PC都是从0x00000000取指(0x08000000被映射到0x00000000),那么到底从什么地方取指?希望知道的大神给点资料解惑。


2、中断发生后,PC指针指向何处?是0x00000000还是0x08000000?


3、以上两个问题总结起来就是,启动的开始在哪里?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
zc123
1楼-- · 2019-07-21 05:32
首先你要理解映射的概念,当FLASH地址0x08000000映射到0x00000000后,也就是CPU访问0x00000000地址(可以理解为虚拟地址,不一定存在)时,实际上访问的是0x08000000(物理地址)。这部分是由CPU内核完成的,根据配置,当CPU访问0x00000000地址时,经过内部转换,在地址总线上加载的是0x08000000地址, 读取数据指令。从开发者角度,不需要理解CPU内部的操作,只需要知道外部行为,启动后可以理解为从0x08000000地址开始的。
yuzeyuan1
2楼-- · 2019-07-21 06:00
本帖最后由 yuzeyuan1 于 2019-5-9 17:20 编辑

首先,代码是从0x08000000开始,如果你需要固件升级,那这里一般会是bootloader程序,程序里面有升级用的东西,比如主程序运行在08010000,那你就在bootloader中读串口数据存到备份区0x0804 0000中,当取完所有数据就把08040000的东西都转存到08010000中,然后从08010000开始运行新程序。如果检查到读到的串口数据失败,就不把08040000转存到08010000,而是直接重新执行原来的程序,也就是0801 0000为起始的程序。

然后,你代码里会定义这个:
#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH           ((uint32_t)0x08000000)
如果有bootloader程序,bootloader程序里就如上定义,然后你的主程序里就应该是下面这样,从08010000起始:
#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH           ((uint32_t)0x08010000)

最后,要注意在keil的设置->target->IROM1中,要对应地把主程序代码设成0x8010000,后面的size也得相应减小0x10000,比如从0x80000减成0x70000


还有就是
#define NVIC_VectTab_RAM             ((uint32_t)0x20000000)
这里面的地址好像是叫中断向量表的起始地址,如果它定义的和代码里中断向量表实际起始位置不一样,那中断就不好用了。
这条我不确定,有问题请指正。以前看过网上应该是这么说的。

gangzilife
3楼-- · 2019-07-21 10:50
yuzeyuan1 发表于 2019-5-9 17:17
首先,代码是从0x08000000开始,如果你需要固件升级,那这里一般会是bootloader程序,程序里面有升级用的东 ...

答非所问
yuzeyuan1
4楼-- · 2019-07-21 11:32
 精彩回答 2  元偷偷看……
gangzilife
5楼-- · 2019-07-21 12:11
yuzeyuan1 发表于 2019-5-9 17:24
兄弟我没理解您的意思,我认为复位后起始在08000000,并且说明了如果有bootloader,启动也在08000000,并 ...

我之前也是这样认为,直到我看到了这个


gangzilife
6楼-- · 2019-07-21 15:25
 精彩回答 2  元偷偷看……

一周热门 更多>