keil分散加载文件浅析

4caa4b273e1399de1c4a4211d3db1cda.jpeg

什么是分散加载文件

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

何时进行分散加载

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

  • 堆栈以及堆的初始化

  • 定位中断向量表

  • 调用 Reset Handler

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

2e963662ae1aa97810f6bd565f3f55d9.png
在这里插入图片描述


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

分散加载的原理

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

  • Code: 为程序代码部分

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

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

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

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

c4f3258571456bd1c6818e30a93f386b.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,下面就是这个加载过程的示意图。

8176077cb5d0ce0eb8d0e2803ec9c134.png
装载域和运行域示意图


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

分散加载的语法

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

2807a9cac1bc771d968d080d5cb7a7f6.png
在这里插入图片描述


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

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

  • RAM基址:0x10000000,大小32KB

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

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

总结

上述就是关于分散加载的叙述,所举的例子比较简单,在后续的文章中,将针对于其较为复杂的应用进行阐述,欢迎关注wenzi嵌入式软件公众号~

ae9d911b534c3ad070bffdfd9b2e7237.jpeg

cc372fe09c197a507be4744460c7b823.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

socket buffer套接字缓存

最近公司在开发机器人与服务器调度端的通信时需要使用socket,因此找到了该文章作为深刻理解socket内部运作。 Linux网络核心数据结构是套接字缓存(socket buffer),简称skb。它代表一个要发送或处理的报文,并贯穿于整个协议栈。 1、 套接字…

LAMP 系统性能调优,第 3 部分: MySQL 服务器调优(转)

关于 MySQL 调优 有 3 种方法可以加快 MySQL 服务器的运行速度,效率从低到高依次为: 替换有问题的硬件。对 MySQL 进程的设置进行调优。对查询进行优化。迁移到 DB2? 您正在寻找一种干净利落、无成本的方法用来从 MySQL 迁移到 IBM? DB2? 吗&#xf…

圆梦,手写了个操作系统

大家好,我是发哥。我不止一次在公众号上强调学习操作系统的重要性。至于学习的方法,无外乎看书、看视频、看源码等等。也有推荐过跟着老师一起手写操作系统,但很少有学习方法能同时兼顾以下三点:1、Linux内核2、Windows内核3、自己…

安卓打包apk

打apk包的环境依赖 1.jdk 2.sdk 3.ndk 打apk包的工具 gradle mkdir /usr/local/Android cd /usr/local/Android mkdir sdk gradle ndk 1.jdk安装 略 2.sdk安装 https://www.androiddevtools.cn/下载地址 cd /usr/local/Android/sdk wget https://dl.google.com/android/andro…

你知道怎么衡量硬件设备的算力吗?

前几天在知乎上看到有知友提问,什么是 GPU 算力。当时简单回答了一下,今天有空,在这里详细谈谈算力。算力也是做高性能计算的核心概念和指标。设备算力分为两部分,其一是设备,其二是算力。设备主要是指 CPU、GPU、DSP、…

Python爬虫入门教程 22-100 CSDN学院课程数据抓取

1. CSDN学院课程数据-写在前面 今天又要抓取一个网站了,选择恐惧症使得我不知道该拿谁下手,找来找去,算了,还是抓取CSDN学院吧,CSDN学院的网站为 https://edu.csdn.net/courses 我看了一下这个网址,课程数量…

UML类图解义 (来自《大话设计模式》)

为什么80%的码农都做不了架构师?>>> 小菜:“对了,我时常在一些技术书中看到这些类图表示,简单的还看得懂,有些标记我很容易混淆。要不你给我讲讲吧。” 大鸟:“这个其实多看多用就熟悉了。我给…

易写易库(EXEK)玩“花”儿之三:命令有图标支持库,附图

释题:如果您认为这个“花”儿,属于之前第一个“花”儿的变种,易语言写支持库也能玩出“花”儿来(易写易库(EXEK)进展5),我也不反对。 在开始正文之前,我要首先回答我之前提出的两个问题&#xf…

您好,有什么嵌入式书籍推荐的?

回答下这个后台的留言-----比较推荐下面这个仓库里面的内容!https://github.com/ZhongYi-LinuxDriverDev/CS-EmbeddedLinux-Book#%E5%85%A8%E9%83%A8%E6%B1%87%E6%80%BB

VS2017打开低版本的VS MVC架构的项目的时候需要修改的地方

1、需要修改的是.sln文件,即将里面的 Version改为12,其中的VS的版本改为2017 2、项目中后缀名为 .csproj中的代码改一下: 转载于:https://www.cnblogs.com/zhijianhao/p/10253572.html

从外部的js文件中获取ASPX页面的控件ClientID(get control reference from external javascript)...

前言 当使用MasterPage、UserControl等容器时,为了避免控件的重复命名,asp.net会自动将容器中的控件生成一个ClientID(Control Tree中的可生成,否则不会生成)。 例如:ContentPlaceHolder1中的Button1默认情…

可怕!CPU暗藏了这些未公开的指令!

我们平时编程写的高级语言,都是经过编译器编译以后,变成了CPU可以执行的机器指令:而CPU能支持的指令,都在它的指令集里面了。很久以来,我都在思考一个问题:CPU有没有未公开的指令?或者说&#x…

A star算法优化二

本文目的是对A*寻路算法所生成的路径进行一些人性化的调整,使其看起来不至于太机械化。关于A*算法的原理与实现,读者可以阅读其他资料,这里不再详细阐述。 如何写估价函数A*寻路算法本质上是一个有方向性的广度优先搜索算法,它使用…

CentOS下python-mysqldb安装

CentOS下python-mysqldb安装日期:2011-04-17 | 来源:未知 | 作者:redice | 869 人围观 | 1 人鼓掌了!鲲鹏Web数据抓取 - 专业Web数据采集服务提供者(1)py…

I2C总线接上拉电阻的原因

I2C为什么要接上拉电阻?因为它是开漏输出。为什么是开漏输出?I2C协议支持多个主设备与多个从设备在一条总线上,如果不用开漏输出,而用推挽输出,会出现主设备之间短路的情况。所以总线一般会使用开漏输出。为什么要接上…

解决循环引用--弱引用weak_ptr

循环引用&#xff1a; 引用计数是一种便利的内存管理机制&#xff0c;但它有一个很大的缺点&#xff0c;那就是不能管理循环引用的对象。一个简单的例子如下&#xff1a; class parent; class children;typedef shared_ptr<parent> parent_ptr; typedef shared_ptr<ch…

第九章 虚拟内存

物理地址和虚拟地址&#xff1a; 计算机的主存被组织成一个由M个连续的字节大小的单元组成的数组。每个字节都有一个唯一的物理地址&#xff08;PA&#xff09;。第一个字节地址为0&#xff0c;接下来为1&#xff0c;再接下来为2&#xff0c;依次类推。CPU访问内存的最自然方式…

Android HandlerThread 总结使用

Android HandlerThread 总结使用转载请标明出处&#xff1a;http://www.cnblogs.com/zhaoyanjun/p/6062880.html本文出自【赵彦军的博客】前言以前我在 【Android Handler、Loop 的简单使用】 介绍了子线程和子线程之间的通信。很明显的一点就是&#xff0c;我们要在子线程中调…

python 文件操作练习

1. 文件a.txt内容&#xff1a;每一行内容分别为商品名字&#xff0c;价钱&#xff0c;个数。 apple 10 3 tesla 100000 1 mac 3000 2 lenovo 30000 3 chicken 10 3 通过代码&#xff0c;将其构建成这种数据类型&#xff1a;[{name:apple,price:10,amount:3},{name:tesla,price:…

微软发布Enterprise Library 4.1和Unity 1.2

说明 微软模式与实践团队今天发布了Enterprise Library 4.1和Unity 1.2版本&#xff0c;这次发布的主要新特性如下&#xff1a; 1. 支持Visual Studio 2008 SP1 2. Unity应用程序块中加入了拦截机制 3. 性能提升 4. 配置工具的可用性提升 5. Bugs修复。 在Unity 1.2中有如下几点…