浅析keil的scf分散加载文件-基于STM32的例程
关于分散加载文件
keil编译器在链接的时候,是根据分散加载(.scf后缀的文件)来确定程序的加载域和运行域的。加载域就是程序运行前在flash中具体分区情况,执行域就是程序运行后,程序在flash和ram中的分区情况。这里引用野火关于加载视图和执行视图的对比图:
可以看到,左边是加载视图,RW段和RO段对应的存储空间我们称为加载域。当程序运行后,RW段中的数据会被复制到RAM中,同时还会初始化一个ZI段用来存放没有初始化和被初始化为零的相关变量。因此右边的相关储存空间我们称为执行域。
分散加载文件.sct
那么怎么确定程序运行前、运行后的代码、数据等相应的地址和空间的呢?让我们找一个分散加载文件看看。打开一个STM32的工程,找到工程配置的入口,选择Target
再选择Linker
原本左上角的勾是打着的,也就是默认情况下,编译器根据Target中的配置去生成程序的分散加载文件。我们去掉第一个勾,看到Scatter File那一行可以修改和编辑,通过Edit或者白色框中的目录都可以找到默认生成的分散加载文件,以下是分散加载文件的具体内容:
分号后面是注释。我们将代码复制出来,再加点注释:
LR_IROM1 0x08000000 0x00040000 {
这是代码的加载域,从Target的配置看,ROM的起始地址和范围分别就是0x08000000 0x00040000,而LR_IROM1为加载域名称,代表这块存储区域
ER_IROM1 0x08000000 0x00040000 { ; load address = execution address
加载域括起来的,为执行域。本文件有两个执行域:ER_IROM1和RW_IRAM1。类似的,0x08000000和0x00040000为ER_IROM1的起始地址和大小
*.o (RESET, +First)
*.o表示选择所有的.o文件,均放在这里,RESET为节区名,+First表示将RESET节区放在最前面。RESET在启动文件.s文件可以看到,后续有时间写一篇关于启动文件的聊一下
(InRoot$$Sections)
这是将标准库里,有使用到的相关文件或节区,放到这里,挨着上面的*.o
.ANY (+RO)
}
表示将剩下的,所有的RO(readeonly,只读的)属性的节区放这里
RW_IRAM1 0x20000000 0x0000C000 { ; RW data
0x20000000 和0x0000C000 为RW_IRAM1 的起始地址和大小
.ANY (+RW +ZI)
}
}
表示剩下的,所有的RW、ZI属性的节区
以上是关于STM32的一个简单例程的分散加载文件的简单介绍。欢迎批评指正