硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6617|回复: 25
收起左侧

[STM32H7] 【不是问题的问题】为什么STM32的Flash地址要设置到0x08000000

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
发表于 2021-10-28 00:33:17 | 显示全部楼层 |阅读模式
我们言简意赅的普及下这个知识点,争取让大家不伤脑细胞

一、背景知识:

M3,M4内核芯片上电复位后,要固定从0x0000 0000地址读取中断向量表,获取复位中断服务程序的入口地址后,进入复位中断服务程序,其中0x0000 0000是栈顶地址,0x0000 0004存的是复位中断服务程序地址。

QQ截图20211027232815.png

2.png

ARM官方回复:
https://developer.arm.com/documentation/ka001328/latest

QQ截图20211028125337.png

二、引出问题:

既然ARM规定了M3,M4内核要从地址0x0000 0000读取中断向量表,而STM32设置Flash地址到0x0800 0000怎么办?

STM32支持了个内存重映射功能,将地址0x0800 0000开始的内容重映射到首地址0x0000 0000中,这样就解决了从0x0000 0000读取中断向量表的问题。

图示,以STM32F407IGT6为例,0x0000 0000和0x0800 0000开始的程序对比:




那么新的问题来:

(1) 你怎么保证0x08000 0000首地址存的就是中断向量表,我们不可以随意设置吗?

保证中断向量表存到0x0800 0000,这个涉及到分散加载的一个小知识,以MDK为例,如果大家看xxx.S启动文件,里面通过AREA定义了一个名叫RESET的段,这段存的就是中断向量表。

  1. ; Vector Table Mapped to Address 0 at Reset
  2.                 AREA    RESET, DATA, READONLY
  3.                 EXPORT  __Vectors
  4.                 EXPORT  __Vectors_End
  5.                 EXPORT  __Vectors_Size
复制代码


这个名字很重要,MDK对应的xxx.sct分散加载里面通过下面这句将这个RESET段放在了0x0800 0000优先存储。

  1. ; *************************************************************
  2. ; *** Scatter-Loading Description File generated by uVision ***
  3. ; *************************************************************

  4. LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  5.   ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
  6.    *.o (RESET, +First)
  7.    *(InRoot$Sections)
  8.    .ANY (+RO)
  9.    .ANY (+XO)
  10.   }
  11.   RW_IRAM2 0x24000000 0x00080000  {  ; RW data
  12.    .ANY (+RW +ZI)
  13.   }
  14. }
复制代码


这样我们就解决了0x0800 0000首地址存储中断向量表,一旦程序开始运行后,我们就可以随意设置中断向量表的位置了。比如想将中断向量表存到内部SRAM,我们就可以操作寄存器SCB->VTOR 重新安排,然后将0x0800 0000的内容复制到设置的地址内即可。

(2) 既然设置到0x0800 0000这么麻烦,为什么不直接使用0x0000 0000?

这是因为STM32不仅可以从内部Flash启动,还可以从系统存储器(可以实现串口ISP,USB DFU等程序下载方式,这个程序是ST固化好的程序代码)和从内部SRAM启动,

我们将内部Flash安排到0x0000 0000显然是不行的。这样会导致系统存储器或者内部SRAM无法重映射到0x0000 0000了。

QQ截图20211028002623.png


三、了解了M3和M4,M7是怎么个执行情况呢?

M7内核芯片比较灵活了,改变了固定从0x0000 0000地址读取中断向量表的问题,以STM32H7为例,可以从 0x0000 0000 到 0x3FFF 0000 所有地址进行启动。

专门安排了个选项字节来配置。

QQ截图20211028003238.png

H7里面没有重映射了,它的首地址0x0000 0000安排给ITCM RAM空间使用了。

评分

参与人数 1金币 +19 收起 理由
wizard + 19 很给力!

查看全部评分

回复

使用道具 举报

38

主题

194

回帖

318

积分

高级会员

积分
318
发表于 2021-10-28 08:39:42 | 显示全部楼层
赞一个👍
回复

使用道具 举报

0

主题

101

回帖

101

积分

初级会员

积分
101
发表于 2021-10-28 08:55:35 | 显示全部楼层
学习了
谢谢
回复

使用道具 举报

73

主题

1192

回帖

1411

积分

至尊会员

积分
1411
发表于 2021-10-28 09:00:48 | 显示全部楼层
谢谢硬汉哥
回复

使用道具 举报

0

主题

23

回帖

23

积分

新手上路

积分
23
发表于 2021-10-28 09:18:50 | 显示全部楼层
这个疑惑终于解开了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
 楼主| 发表于 2021-10-28 09:40:15 | 显示全部楼层
已经补图。
回复

使用道具 举报

334

主题

2032

回帖

3039

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3039
发表于 2021-10-28 10:11:46 | 显示全部楼层
我感觉ST里面设计这个芯片的工程师是个华裔,觉得8比较吉利,所以优选8开头的地址作为启动地址。。。RAM的地址是2开头,因为中国也是比较喜欢双数。
回复

使用道具 举报

0

主题

29

回帖

29

积分

新手上路

积分
29
发表于 2021-10-28 10:47:39 | 显示全部楼层
我也觉得8比较吉利, 哈哈
回复

使用道具 举报

12

主题

26

回帖

62

积分

初级会员

积分
62
发表于 2021-10-28 11:22:03 | 显示全部楼层
可以解决好多小伙伴的疑惑了。
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2021-10-28 11:43:15 | 显示全部楼层
这个解释靠谱。
回复

使用道具 举报

23

主题

1403

回帖

1472

积分

至尊会员

积分
1472
发表于 2021-10-28 11:46:18 | 显示全部楼层
测试了下内部系统BootLoader重映射到0x00000000,STM32不让读取。

而内部Flash重映射和楼主描述的一致。
代码不规范,亲人两行泪!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
 楼主| 发表于 2021-10-28 11:52:35 | 显示全部楼层
missfox 发表于 2021-10-28 11:46
测试了下内部系统BootLoader重映射到0x00000000,STM32不让读取。

而内部Flash重映射和楼主描述的一致。

系统存储器的BootLoader代码禁止用户读取了。之前我也尝试将其搞出来自己玩,发现不行。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
 楼主| 发表于 2021-10-28 12:57:22 | 显示全部楼层
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2021-10-28 21:31:23 | 显示全部楼层
非常详细的文档,点赞硬汉大哥
回复

使用道具 举报

36

主题

2039

回帖

2147

积分

至尊会员

积分
2147
发表于 2021-10-29 12:58:49 | 显示全部楼层
辛苦,感谢普及
Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better.
回复

使用道具 举报

13

主题

156

回帖

215

积分

高级会员

积分
215
发表于 2021-10-29 17:31:54 | 显示全部楼层
mcu响应中断基本上都是查表,所以只要在触发异常之前设置好异常处理服务函数就行。本着这个原则其实只要在上电之前,在0x8000 0004设置好复位中断服务函数的入口地址即可(这个可以通过链接文件绝对指定),其他向量表可以不用管,等程序启动后再设置,因为你骗子一上电便会触发复位异常。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2021-11-4 09:48:35 | 显示全部楼层
谢谢指导!有用的知识增加了!
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2022-11-9 15:54:03 | 显示全部楼层
非常有用,多谢指导
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2023-7-20 16:07:46 | 显示全部楼层
caicaptain2 发表于 2021-10-28 10:11
我感觉ST里面设计这个芯片的工程师是个华裔,觉得8比较吉利,所以优选8开头的地址作为启动地址。。。RAM的 ...

6不吉利吗?
回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2023-11-12 22:51:08 | 显示全部楼层
讲的很详细,学习了
回复

使用道具 举报

3

主题

24

回帖

33

积分

新手上路

积分
33
发表于 2023-11-14 16:40:33 | 显示全部楼层
可我还是没有看懂,为什么还要映射,是不是多了一步。我水平比较次。。。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
 楼主| 发表于 2023-11-14 16:56:54 | 显示全部楼层
仰望星期五 发表于 2023-11-14 16:40
可我还是没有看懂,为什么还要映射,是不是多了一步。我水平比较次。。。

你得意思是直接把Flash空间设置到0x0000 0000
也可以的,只是这样不方便从RAM或者系统boot启动的重映射了。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2023-11-26 11:36:06 | 显示全部楼层
eric2013 发表于 2023-11-14 16:56
你得意思是直接把Flash空间设置到0x0000 0000
也可以的,只是这样不方便从RAM或者系统boot启动的重映射 ...

那么,在M23内核中是什么规则呢?

相应的最近出了那么多内核,除了M23/M33,还有M55,M85,M52这些内核

我们如何通过第一手信息知道他们的运行方式呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
 楼主| 发表于 2023-11-27 08:01:26 | 显示全部楼层
wsr2580 发表于 2023-11-26 11:36
那么,在M23内核中是什么规则呢?

相应的最近出了那么多内核,除了M23/M33,还有M55,M85,M52这些内 ...

看对应的芯片手册,像STM32的都有说明,看下就明白了。
回复

使用道具 举报

5

主题

43

回帖

58

积分

初级会员

stay hungry, stay foolish

积分
58
发表于 7 天前 | 显示全部楼层
caicaptain2 发表于 2021-10-28 10:11
我感觉ST里面设计这个芯片的工程师是个华裔,觉得8比较吉利,所以优选8开头的地址作为启动地址。。。RAM的 ...

有道理
回复

使用道具 举报

5

主题

43

回帖

58

积分

初级会员

stay hungry, stay foolish

积分
58
发表于 7 天前 | 显示全部楼层
硬汉大哥讲的很明白,讲得真好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 05:38 , Processed in 0.261302 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表