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
    +关注

    关注

    145

    文章

    15900

    浏览量

    342793
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8615

    浏览量

    361323
  • ROM
    ROM
    +关注

    关注

    4

    文章

    519

    浏览量

    84636
  • Cortex-M4
    +关注

    关注

    6

    文章

    89

    浏览量

    46204
  • 上电复位
    +关注

    关注

    1

    文章

    38

    浏览量

    15616

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

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

收藏 人收藏

    评论

    相关推荐

    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

    Keil分散加载文件浅析

    ARM 映像文件其实就是源文件经编译器生成的目标文件,一般是bin文件或者hex文件,可以直接烧录到ROM中执行(一般是内部FLASH),这
    的头像 发表于 11-17 10:00 1031次阅读
    Keil<b class='flag-5'>分散</b><b class='flag-5'>加载文件</b>浅析

    在MATLAB中如何保存和加载消息

    到MAT文件中。 save ( 'posedata.mat' , 'posedata' ) 在将文件加载回工作空间之前,清除posedata变量。 clear posedata 现在可以通过调用load
    的头像 发表于 11-15 15:17 140次阅读

    RT1052 分散加载问题

    我在分散加载中是这样配置的: 目的是把代码拆开,存储在flash的不同扇区。 但我发现上电后函数RunPro的代码没有从nor flash成功加载到SDRAM,所以单片机运行到函数RunPro就死机
    发表于 11-08 18:40

    求助,关于mdk5分散加载文件的问题

    有没有人能解释一下,分散加载文件应该怎么写
    发表于 11-02 07:23

    如何把文件系统烧到EMMC并从EMMC加载

    如何下载并从SD卡加载文件系统,提到过可以从EMMC引导系统,本篇将为您介绍如何把文件系统烧到EMMC,并从EMMC加载
    的头像 发表于 10-30 16:06 1252次阅读
    如何把<b class='flag-5'>文件</b>系统烧到EMMC并从EMMC<b class='flag-5'>加载</b>

    车规MCU的启动加载程序是什么

    启动加载程序(bootloader) 车规MCU的启动加载程序(bootloader)是一种用于在汽车电子控制单元(ECU)上加载和更新应用程序的软件。它具有以下主要功能和实现要点: 引导加载
    的头像 发表于 10-27 17:26 1040次阅读

    FAQ0086 Eclipse中实现分散加载的方法

    Eclipse中实现分散加载的方法如何在Eclipse 中实现分散加载
    发表于 10-20 06:05

    类隔离实现之自定义类加载器的扩展

    1、前言 JVM内部架构包含类加载器、内存区域、执行引擎等。日常开发中,我们编写的java文件被编译成class文件后,jvm会进行加载并运
    的头像 发表于 10-08 15:17 224次阅读

    ARM分散加载介绍

    分散加载是ARM链接器提供的一种机制,它允许您将可执行映像分区为可在内存中独立定位的区域。 在一个简单的嵌入式计算机系统中,存储器分为只读存储器和随机存储器。 链接器产生的镜像被分为“只读”段
    发表于 08-24 08:23

    ESP8266从Littlefs加载文件时它崩溃了的原因?

    在我的 ESP8266 中获得了一个带有大量 javascript 的网络服务器的程序。 当我尝试从 Littlefs 加载文件时它崩溃了。这可能不是原因,但是,我遇到了内存不足的 OOM。 所以
    发表于 05-10 09:24