你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32经验分享——内存分布详解(1)

[复制链接]
STMCU小助手 发布时间:2022-8-28 21:55
STM32具有和PC机类似的结构组成。那么我们平时听到的RAM和ROM就相当于PC的内存条和硬盘,当然了PC的硬盘和单片机的ROM也并不是所谓的只读,只不过以前的技术原因很难做到多次读写,因为最初的存储器是纸带、熔丝或者其他一次性存储器,因此只能读取,也就是ROM,当然那时候也不需要持续的修改。随着技术的革新,这些最初的ROM慢慢的增大内存、增加写功能、提高读写速度。而ROM的叫法也一直延续下来。

        扩展一下,为什么ROM也可以写,不用ROM当RAM呢?因为ROM还是太慢了,读取可还行(比如F7、H7就支持QSPI运行程序),写就是肉眼可见级别的延迟了。所以RAM这种需要高速读写的还是让SRAM、SDRAM、DDR等等来干吧。

        那这两大块内存在单片机上是怎么分布的呢?以F103C8T6为例。
`{M0{1UYCQDWW@]5XKGMB8U.png


ROM&RAM声明

        这里就勾选使能了两块内存,一个是ROM,一个是RAM,当然也有的支持两块ROM或者ROM,这里先不管,ROM的起始地址是0x0800 0000,大小是0x2400。RAM的地址是0x2000 0000,大小是0x5000。(为什么ROM比RAM还小,因为这是个Bootloader,要占用尽可能小的空间,不然的结果就是你买的64G手机,什么都没装就还有56G)。

        或者看一下默认的分散加载文件,也可以得到ROM和RAM的地址和大小。

AR0J4_@V7H)LT9)NN~1YP.png


分散加载内容

        关于ROM和RAM做什么用的你应该很清楚了,不清楚我们就再叙述一下。RAM是随机存取存储器,可读可写,并且想怎么读怎么读,想怎么取怎么取,还很快。正是这种特点RAM才适合做CPU和ROM的中介,上可速度对等CPU,下可衔接ROM永久存储数据。但是呢?一断电它就清零了,就跟你敲了半天的word崩了打开就空了一样。而ROM就不会,并且ROM的空间大小可以做到很大很大。而ROM的缺点就是写比较慢,如果是串行的传输方式那么会更慢。

        CPU就非常快了,上到GHz级别,因此如果需要进行数据的读写,显然ROM速度完全跟不上,但是RAM一断电就没了,所以完美的结构是先从ROM读取到RAM,然后再运行。这就是为什么同时需要ROM和RAM。

        ROM保存着需要固化的内容,比如函数到底存储着哪些寄存器操作指令,程序到底定义了哪些全局变量,程序使用了哪些字库、图片或者数组(比如使用查表加速计算)。你下载的程序就存储在这里,比如你使用fromelf --bin !L -o .\BIN\Firmware_F4.bin指令生成了bin文件。(bin文件名称:Firmware_F4.bin 可以自定义)那么这些数据就会固化在0x0800 0000这里,就像这样。

FA60_X[8}8R0)FTXOPKBJ.png


BIN文件数据

        而你定义的数组则会存在0x2000 0000这块区域,具体是哪里可以使用取址指令得到地址,例如value数组的地址是:0x20000898。

0XP59$R%L74`K`ULNS5$N@C.png


数组地址打印

        或者你也可以直接看变量窗口的地址,如下。

2I[Z]6E221VRBJP1Z5~MN)W.png


变量地址查看

        当你写了数据,相应的就可以看到RAM的数值变化。比如执行到60行的时候,第59行的赋值就有了效果。

7{FA`4UTM~[4MY(~[IYCD_T.png


变量地址&数据查看

        相对应的内存处也产生了变化。

CYAU)A`2HTMU7J3AJJ{OUGW.png


数组数据变化

        随着数组内容的写入可以看到数据的变化过程。

{_WD7Y0A_LF3IT1WF_][KC4.png


数组数据变化

        甚至你还可以看到main函数存在了哪里。

(Z7STT7_Q3MDE8MPD8Z~5PC.png


主函数存储地址

        又或者你直接查看Map文件。

_}4SGJL%_Q(315[E5)C5.png


map文件main函数存储地址

        这是你定义的字库的地址:0x08007B96,或者你也可以用同样的方式把它打印出来。

64F4ISOGRGP14%ZVE[XIAOY.png


字库存储地址

        同样是数组,一个在RAM,一个在ROM,因为字库不需要更改,所以使用const关键字定义在常量区,也就是ROM。而变量数组需要更改,这里没有赋0以外的值,所以你需要多大的空间,编译器到时候给你去RAM分配就是了,然后编译器再把这些分配地址的指令写进BIN,然后你下载存储到0x0800 0000的单片机的硬盘里,到时候单片机的Cortex-M内核就知道0x2000 0000的那一块地址是属于你的数组了。

        如果赋值不是0呢?可以看到,地址还是0x2000 0000这块区域。而main函数的局部变量就需要分配了,有初始非0值相当于预定了,而局部变量只有运行的时候才有会给分配地址。

DFH003)VA78{}FI1A[P~F00.png


全局非0初始化存储地址

        就好像有初始值相当于交了押金,会给你预定包间,虽然你还没住但是已经有了房间号,而你不初始化只有到了再订包间,所以在这之前你完全不知道你的房间号。并且如果你来晚了还有可能没有包间可用,已经被别人包完了,对应到单片机就是堆栈溢出了。那如果你预定都预定不到的话,就是内存不够了。

作者:mymymind


收藏 评论0 发布时间:2022-8-28 21:55

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版