0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是分散加载文件?何时进行分散加载

工程师邓生 来源:wenzi嵌入式软件 作者:wenzid 2022-09-14 10:38 次阅读

什么是分散加载文件

分散加载文件(scatter file)是一个文本文件,它的作用是可以用于描述 ARM 链接器生成映像文件所需要的信息

如果不使用 scatter file 文件来指定,那么 ARM 链接器会按照默认的方式来生成映像文件,但是对于某些应用场景来说,我们希望能够将一些数据放在指定的位置,这个时候,分散加载文件就发挥其作用了。

何时进行分散加载

在之前的一篇文章MCU 是如何从上电复位运行到 main 函数的?中详细叙述了MCU运行到 main 函数之前所做的操作。简而言之,主要做了如下三个工作:

堆栈以及堆的初始化

定位中断向量表

调用 Reset Handler

下图列出了ARM Cortex M4系列芯片的一个启动流程,厂商不一样,会存在细微的差别。

8195e6be-3371-11ed-ba43-dac502259ad0.png

由上述启动流程可以看到,分散加载操作是在 __main() 函数内部完成的,紧接着,就运行 C 语言运行环境初始化 & C Library 的初始化。

分散加载的原理

在理解分散加载的原理之前,需要明白以下几个概念:

Code: 为程序代码部分

RO-Data: 表示程序定义的常量及const型数据

RW-Data:表示已经初始化的静态变量,变量有初值

ZI-Data: 表示未初始化的静态变量,变量无初值

除此之外,因为分散加载的机制是将不同代码放在不同的存储空间,因此还需要了解代码的映像文件的基本概念。ARM 映像文件其实就是源文件经编译器生成的目标文件 .obj(object file)和相应的 C/C++ 运行时库( Runtime Library )经过连接器的处理后,生成的 axf 格式的映像文件,它可以直接烧录到目标设备的 ROM 中直接运行或加载后运行。映像文件的组成如下所示:

82163daa-3371-11ed-ba43-dac502259ad0.png

映像文件的组成

由上图可以知道,映像文件由域(区)、输出段(节)和输入段(节)的层次结构组成:

输入段:输入段包含代码、初始化数据,或描述未初始化的或在映像执行之前必须设定为 0 的内存片段。这些特性通过 RO 、 RW 和 ZI 这样的属性来表示。

输出段:一个输出段由若干个具有相同 RO 、 RW 或 ZI 属性的相邻输入段组成。输出段的属性与组成它的输入段的属性相同 。

域:一个域由一个、两个或者三个相邻的输出段组成。区中的输出段根据其属性排序。首先是 RO 输出段,然后是 RW 输出段,最后是 ZI 输出段。域通常映射到物理内存设备,如 ROM 、 RAM 或外围设备。

ARM 映像文件各组成部分在存储系统中的地址有两种:

装载域

运行域

在一个简单的嵌入式计算机系统中,存储器一般分为ROM和RAM。链接器生成的映像被分为“Read-Only”段和“Read-Write”段(包含已初始化数据和未初始化数据)。通常来说,在程序下载的时候,他们会被下载到ROM上,而在程序开始执行的时候,Read-Write段会从ROM被Copy到RAM,下面就是这个加载过程的示意图。

823334b4-3371-11ed-ba43-dac502259ad0.png

装载域和运行域示意图

以上只是一个简单的例子,但是在比较复杂的嵌入式系统中,其存储器往往还包括ROM,SRAM,DRAM,FLASH等等,这个时候就需要分散加载文件了。

分散加载的语法

分散加载文件主要由一个加载时域(区)和多个运行时域(区)组成,其大致结构如下图所示:

825a0b70-3371-11ed-ba43-dac502259ad0.png

本次先介绍一种简单的情况,一个Cortex M3系列的微控制器有Flash和RAM资源如下所示:

Flash基址:0x00000000,大小256KB;

RAM基址:0x10000000,大小32KB

那么分散加载文件可以这么写:

LR_IROM10x000000000x00040000;定义一个加载域,域基址为0x00000000,大小为0x00040000
{;对应着实际的Flash的大小
ER_IROM10x000000000x00040000;定义一个运行域,第一个运行域必须和加载域起始地址相同
{
*.o(RESER,+First);将RESET最先加载到本域的起始地址,即RESET的起始地址为0
 .ANY(+RO);加载所有匹配目标文件的只读属性数据,包含:Code,RW-Data
}

RW_IRAM10x100000000x00008000;定义一个运行时域,域基址为0x10000000,域大小为0x00008000
{
*(+RW+ZI);加载所有匹配目标文件的RW-Data,ZI-Data
}
}




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16978

    浏览量

    350215
  • ARM
    ARM
    +关注

    关注

    134

    文章

    9040

    浏览量

    366731
  • ROM
    ROM
    +关注

    关注

    4

    文章

    562

    浏览量

    85662
  • Cortex-M4
    +关注

    关注

    6

    文章

    89

    浏览量

    46510
  • 上电复位
    +关注

    关注

    1

    文章

    39

    浏览量

    15774

原文标题:keil分散加载文件浅析

文章出处:【微信号:wenzi嵌入式软件,微信公众号:wenzi嵌入式软件】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何优化EPS文件以提高加载速度

    在图形设计和排版领域,EPS文件因其高兼容性和高质量输出而广受欢迎。然而,EPS文件往往体积较大,加载速度慢,这在处理大型项目或需要快速迭代时成为了一个瓶颈。 一、了解EPS文件 EP
    的头像 发表于 10-30 14:32 168次阅读

    AG32 下的分散加载

    配置,达成这样的目的。 分散加载在gcc 下的限制: 不能插入到代码段,只能放到正常编译的 bin 后边(参后详述)。 在默认情况下,AG32编译时使用的连接配置文件
    发表于 09-20 15:26

    AWR294x主引导加载程序和辅助引导加载程序

    电子发烧友网站提供《AWR294x主引导加载程序和辅助引导加载程序.pdf》资料免费下载
    发表于 09-06 09:47 0次下载
    AWR294x主引导<b class='flag-5'>加载</b>程序和辅助引导<b class='flag-5'>加载</b>程序

    【GD32 MCU 入门教程】七、分散加载说明

    分散加载说明以GD32F103ZE为例,分别用Keil、IAR和Embedded Builder工具实现:将函数放置某个地址、将常量放置某个地址、将函数放在RAM中运行的三种效果。 1、将
    的头像 发表于 08-27 09:19 399次阅读
    【GD32 MCU 入门教程】七、<b class='flag-5'>分散</b><b class='flag-5'>加载</b>说明

    labview实现DBC在界面加载配置

    labview实现DBC在界面加载配置
    发表于 08-19 14:27 27次下载

    如何使用Tensorflow保存或加载模型

    TensorFlow是一个广泛使用的开源机器学习库,它提供了丰富的API来构建和训练各种深度学习模型。在模型训练完成后,保存模型以便将来使用或部署是一项常见的需求。同样,加载已保存的模型进行预测或
    的头像 发表于 07-04 13:07 1282次阅读

    如何用加载分散法将软件中部分变量从内部RAM转移到外部RAM?

    如何用加载分散法将软件中部分变量从内部RAM转移到外部RAM, 加载分散文件怎么设置?堆和栈需要设置吗?
    发表于 05-10 07:52

    深入分析一下MDK的分散加载文件

    ARM C 库提供了函数 __user_setup_stackheap() 的多个实现,并且可以根据分散文件中提供的信息自动选择正确的一种。
    发表于 04-28 14:21 721次阅读
    深入分析一下MDK的<b class='flag-5'>分散</b><b class='flag-5'>加载文件</b>

    stm32分散加载文件导致程序死机怎么解决?

    单片机 stm32f401ccu6 flash大小 16kb+16kb+16kb+16kb+64kb+128kb = 256kb 为了使用留出参数空间,将代码空间分为三段,其中第二段留空供参数使用 当使用以下配置时可以正常运行,使用FAL命令擦写参数段是可以的 LR_IROM1 0x08000000 0x000040000 { ; load region size_region ER_IROM1 0x08000000 0x00010000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } ER_IROM2 0x08020000 FIXED 0x00040000 { ; load address = execution address .ANY (+RO) } RW_IRAM1 0x20000000 0x00010000 { ; RW data .ANY (+RW +ZI) } } 但是将第二段空间改为0x00020000时程序编译正常,但是烧录死机 ER_IROM2 0x08020000 FIXED 0x00020000 { ; load address = execution address 以下是错误代码 \\ | / - RT -Thread Operating System / | \\5.0.2 build Mar 12 2024 19:24:05 2006 - 2022 Copyright by RT-Thread team psr: 0x80000000 r00: 0x0803f330 r01: 0x0803f11c r02: 0x00000400 r03: 0x00000000 r04: 0xdeadbeef r05: 0xdeadbeef r06: 0xdeadbeef r07: 0xdeadbeef r08: 0xdeadbeef r09: 0xdeadbeef r10: 0xdeadbeef r11: 0xdeadbeef r12: 0x20001fd0 lr: 0x0802cdeb pc: 0x0803f330 hard fault on thread: main rt_thread_ threadpristatusspstack size max used left tickerror ---------- -------- ---------- ---------- -------------------------- --- 0x20001f78 ulog_asy30ready0x00000044 0x00000400 06%0x00000014 OK 0x20000ae8 tidle0 31ready0x00000044 0x00000100 26%0x00000020 OK 0x200016b8 main10running 0x00000044 0x00000800 18%0x00000013 OK usage fault: SCB_CFSR_UFSR:0x02 INVSTATEml
    发表于 03-26 06:31

    STM32L552VET6配置SDMMCH和文件系统,加载文件系统挂载存储卡会返回FR_NOT_READY如何解决?

    STM32L552VET6配置SDMMCH和文件系统,不加载文件系统可以正常操作存储卡,但是加载文件系统挂载存储卡返回FR_NOT_READY,该如何解决。
    发表于 03-08 07:30

    使用分散加载将部分程序放到RAM,RAM掉电后数据就没有了,如何复原?

    我使用分散加载将部分程序放到RAM,RAM掉电后数据就没有了,重新上电后,芯片是如何将RAM区程序复原的呢。
    发表于 03-06 07:01

    怎么在rtthread studio中使用分散加载功能,工程里也找不到sct文件

    怎么在rtthread studio中使用分散加载功能,工程里也找不到sct文件
    发表于 02-23 08:28

    STM32H750IBK6如何将指定代码存放在外部QSPI FLASH里?

    如题,使用的STM32H750IBK6,内部只有128KB的FLASH,太小了。MDK使用的是分散加载文件来指定代码存放内存。同理我尝试修改了studio中的链接脚本,可无论如何都无法将指定代码存放在外部QSPI FLASH里,是我链接脚本问题吗?
    发表于 02-23 06:02

    如何加载ELF烧录文件

    请问在如下的界面中,如何加载ELF烧录文件
    发表于 02-01 08:25

    如何在LabVIEW中清晰加载图片呢?

    有开发者提出,在使用LabVIEW开发图片加载显示程序时,为什么明明看着很清晰的图片,LabVIEW加载显示后就变得粗糙,线条不流畅。
    的头像 发表于 12-20 09:08 1612次阅读
    如何在LabVIEW中清晰<b class='flag-5'>加载</b>图片呢?