ScatterFile分散加载文件及其应用
分散加载文件浅释
销售:
电话:(020)22644249 22644399 22644372 22644261 28872524 28872342 28872349 28872569 28872573 38601786
维修:
电话:(020)22644245
产品应用笔记
在 Keil/ADS/IAR 等编译工具中,可通过分散加载机制实现。分散加载通过配置文件实 现,这样的文件称为分散加载文件。本文重点介绍 Keil 的分散加载文件配置。
工程技术笔记
©2008 Guangzhou ZHIYUAN Electronics CO., LTD. 1
广州周立功单片机发展有限公司
2.2
变量完成初始化的地方........................................................................................... 2
2.3
ZI-Data 变量初始化方式......................................................................................... 3
日期 2011/10/24
分散加载文件浅释
ARM 嵌入式开发
原因 创建文档
产品应用笔记
©2008 Guangzhou ZLGMCU Development Co., LTD. i
广州周立功单片机发展有限公司
分散加载文件浅释
ARM 嵌入式开发
销售与服务网络(一)
广州周立功单片机发展有限公司
地址:广州市天河北路 689 号光大银行大厦 12 楼 F4 邮编:510630 电话:(020)38730916 38730917 38730972 38730976 38730977 传真:(020)38730925 网址:
MDK使用心得1—建立工程文件小结
MDK是目前最常见的ARM的开发工具. 在此本人首先就建立工程文件中的几个步骤中的相应参数如何设定做一小结。
1.创建文件夹在创建新工程文件之前,首先建立一个工程文件夹,工程文件夹中建立两个子文件夹,便于阅读,调试和查找。
双击µVision 3图标,进入开发工具的标准窗口,单击Project ->New µVision Project菜单项,µVision 3将打开一个标准对话框,输入希望新建工程的名字即可创建一个新的工程,输入新建工程的名字Project1,µVision将会创建一个以Project1.UV2为名字的新工程文件,它包含了一个缺省的目标(target)和文件组名。
这些内容在Project Workspace->Files中可以看到,然后选择NewProject文件夹作为新建工程的目录.2.选择设备在创建一个新的工程时,µVision要求为这个工程选择一款CPU。
选择设备对话框显示了µVision的设备数据库,只需要选择用户所需的微控制器即可。
例如,选择 Philips LPC2292微控制器,这个选择设置了LPC2292设备的必要工具选项、简化了工具的配置。
3.选择工具集在开发ARM工程时,对于µVision工程来说,必须在Project - Components, Environment, and Books对话框中选择工具集。
4.创建新的源文件通过File ->New...菜单项可创建一个新的源文件。
这时将打开一个空文件编辑窗口,在这里可以输入源文件代码。
当通过File->Save As 对话框以扩展名.C的形式保存了这个源文件,推荐将工程的源文件保存在工程文件夹中的一个子文件夹,如我们前面建立的SrcFiles子文件夹中。
创建源文件以后,就可以将这个文件添加到工程中。
µVision提供了几种方法将源文件添加到工程中。
编译程序中RO-RW-ZI的含义
RO段、RW段和ZI段--Image$$??$$Limit 含义(zz)IMPORT |Image$$RO$$Limit|IMPORT |Image$$RW$$Base|IMPORT |Image$$ZI$$Base|IMPORT |Image$$ZI$$Limit|IMPORT |Image$$RW$$Limit|从ADS1.2的帮助文档可以看出以下几个symbol的定义应该是:|Image$$RO$$Base|表示RO输出段运行时起始地址,也可以说是程序代码存放的起始地址,由-ro-base这个参数指定;|Image$$RO$$Limit|表示RO输出段运行时存储区域界限,其值可通过|Image$$RO$$Base|+Code sizes+RO Data sizes+4计算得出;|Image$$RW$$Base|表示RW输出段运行时起始地址,记得是运行时的地址,而不一定是加载时的存放地址,因为RW输出段在加载时可能是在ROM中并紧跟着RO输出段存放的,当程序运行时才移动(在有些书中说是移动,个人觉得应该只是复制,希望大家能帮我解释一下,谢谢!)到RAM起始地址为|Image$$RW$$Base|的区域,由-rw-base这个参数指定;未指定的话,默认紧跟RO输出段,那么|Image$$RW$$Base|=|Image$$RO$$Limit|;|Image$$RW$$Limit|表示RW输出段运行时存储区域界限,其值可通过|Image$$RW$$Base|+RW Data sizes+4计算得出;|Image$$ZI$$Base|表示ZI输出段运行时起始地址,它是运行时在RAM中生成的,紧跟着RW输出段存放,其值和|Image$$RW$$Limit|一样;|Image$$ZI$$Limit|表示ZI输出段运行时存储区域界限,其值可通过|Image$$ZI$$Base|+ZI Data sizes+4计算得出。
试图搞懂MDK程序下载到flash(五)--使用MDK中的download直接下载到nor flash
试图搞懂MDK程序下载到flash(五)--使用MDK中的download直接下载到nor flash也不知道怎么弄的,今天突然可以使用MDK中的Flash/Download将程序下载到Nor Flash 了,像开发51一样方便。
现在重新整理一下,将使用MDK中的download功能,将裸机程序下载到nor flash中的步骤写出来。
1、新建一个工程文档,并命名为test2、编写并添加,源文件main.c uart.c uart.h这三个文件可以自行下载,我已经传到了网站:点击打开链接三个文件存放在src文件夹里3、编写分散加载文件RuninFlash.sct,内容如下:将该分散加载文件存放在工程目录中4、修改S3C2440.s中一处代码,初始化时钟,因为我这个test工程使用了UART。
将CLOCK_SETUP EQU 0 修改为CLOCK_SETUP EQU 1,如下图5、配置选项Linker选项,配置如下图在Scatter File一栏中,加入自己刚才编写的分散加载文件Utilities选项,配置如下图点击上图的Settings按钮,弹出下图点击上图的Add按钮,弹出下图因为我的mini2440板的nor flash是2M的,所以选择AM29F160DB Flash Ext.Flash 16-bit 2M,然后点击Add按钮,弹出下图可以看到咱们的Nor Flash的下载算法已经添加了,然后点击OK,关于所有的配置选项已经完成,其他的配置选项使用默认就行了,下面我也贴出来自己其他的配置选项内容Target选项Output选项User选项Debug选项,我这里没有使用Jlink调试,而是直接下载到flash中去,所以这一选项也使用默认值6、保存,编译7、使用Jlink 连接好开发板,从Nor Flash启动,打开串口调试工具8、点击keil中的download按钮,或者Flash/Download,咱们的程序就下载到Nor Flash中了9、可以看到程序运行起来了,已经下载到nor flash中了,关闭电源再打开程序任然可以运行,记得把Jlink从开发板上拔掉。
scatter file--ARM中的RO、RW和ZI DATA说明
一直以来对于ARM体系中所描述的RO,RW和ZI数据存在似是而非的理解,这段时间对其仔细了解了一番,发现了一些规律,理解了一些以前书本上有的但是不理解的东西,我想应该有不少人也有和我同样的困惑,因此将我的一些关于RO,RW和ZI的理解写出来,希望能对大家有所帮助。
要了解RO,RW和ZI需要首先了解以下知识:ARM程序的组成此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别。
一个ARM程序包含3部分:RO,RW和ZIRO是程序中的指令和常量RW是程序中的已初始化变量ZI是程序中的未初始化的变量由以上3点说明可以理解为:RO就是readonly,RW就是read/write,ZI就是zeroARM映像文件的组成所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。
以下用Image文件来称呼它。
Image文件包含了RO和RW数据。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。
包含进去反而浪费存储空间。
Q:为什么Image中必须包含RO和RW?A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。
ARM程序的执行过程从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM 程序之间并不是完全一样的。
因此就有必要了解ARM程序是如何从ROM 中的image到达实际运行状态的。
实际上,RO中的指令至少应该有这样的功能:1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。
ZI中也是变量,同理:变量不能存在ROM中在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。
STM32 分散加载文件
STM32 分散加载文件 IAP —MDK(2011-07-25 14:42:30); *************************************************************; *** Scatter-Loading Description File generated by uVision ***; *************************************************************LR_IROM1 0x08000000 0x00004000 ; load region size_region 第一个加载域,起始地址0x08000000,{ 大小0x00004000ER_IROM1 0x08000000 0x00004000 ; load address = execution address 第一个运行时域, { 起始0x08000000,大小0x00004000*.o (RESET, +First) IAP第一阶段还是在FLASH中运行*(InRoot$$Sections)startup_stm32f10x_md.o}ER_IROM2 0x20008000 0x00004000 ; load address = execution address第二个运行时域, { 起始0x20008000,大小0x00004000.ANY (+RO) IAP第二阶段加载到SDRAM中运行}RW_IRAM1 0x20000000 0x00008000 ; RW data 把可读写的数据和初始化为0的数据放在内存SDRAM的开头{.ANY (+RW +ZI)}}做个比喻:就像一列火车在起始地址0x08000000装上大小0x00004000的货物,然后把特定的货物送到指定的地方拿下来运行或者存放。
上面这辆火车就停了3个地方。
编译时出现一下警告:warning: L6314W: No section matches pattern address(RO).在Target中的Linker中有一栏Misc controls,键入--diag_suppress=L6314即可,如下--diag_suppress taglist禁用所有具有指定标签的诊断消息。
试图搞懂MDK程序下载到flash(三)--MDK配置选项Linker、Target、Debug的理解分析
试图搞懂MDK程序下载到flash(三)--MDK配置选项Linker、Target、Debug的理解分析在写这一节时,我还是想再重复一下自己写这文章的目的,我的目的就是为了实现将MDK 编写的裸机程序可不可以脱机运行,也就是不用调试的方法,因为调试的话程序默认是在SRAM中运行的,掉电丢失。
而要脱机运行,就得将程序编译后的文件下载到flash中,最好能是nand flash。
如果要下载到nand flash,那么就要编译生成一个bin文件,而不是用axf文件。
那么剩下的问题就是,怎么生成一个完整、正确的bin文件?所以我现在就需要看能否通过编写一个分散加载文件,解决bin文件的地址问题。
生成了bin文件,那么我就可以利用韦东山的方法,利用supervivi的v选项,配合DNW将程序下载到nand flash中并运行!现在咱们就分析一下MDK配置选项,首先解释一下MDK中三种linker之间的区别:1、采用Target对话框中的RAM和ROM地址。
采用此方式,需在Linker选项卡中勾选Use Memory Layout from Target Dialog选项(选中这一项实际上是默认在Target中对Flash和RAM的地址配置,编译链接时会产生一个默认的脚本文件),并且在Target中设置好RAM、ROM地址,图2所示。
MDK会根据Target选项中设定的RAM和ROM地址自动加载生成一个加载文件。
最后链接器会根据此文件中的信息对目标文件进行链接,生成axf镜像文件。
至于ROM和RAM是片内还是片外、容量(Size)多大,就需要根据芯片和开发板来决定了。
2、直接通过Linker选项卡中的R/O Base和R/W Base来设定链接信息。
链接器最后可根据此处指定的地址信息进行链接,链接的文件应该是顺序存放了,最多RO和RW分开。
此时需要注意的是应将Use Memory Layout from Target Diaglog前的勾去掉,且保证Scatter File一栏中未包含分散加载文件,并且要在Misc controls中设定镜像文件的入口点,如:--first 2440init.o(Init) 对于这个括号内的填写依据,我暂时还不懂。
Scatter Loading讲义
Scatter Loading讲义修改纪录Revision Date Reviser Comments1.0 2006-06-15杨国民Initial version1.12006-12-13傅航宇Integrated other doc2.0 2006-12-14傅航宇Revise and complement目录1.概述 (4)2. 目的 (4)3. 参考资料 (4)4. ARM Image (4)5. Scatter loading的介绍 (6)6. Scatter loading应用举例 (9)7. 应用机制 (11)7. 工程应用 (14)附录 (18)1.概述该文档说明Scatter Loading的意义以及在系统中的实际应用。
2. 目的通过例子代码,让开发者了解Scatter Loading在ARM Linker中存在的意义,结合具体的应用和工程实例,详细说明了其作用和使用方法。
3. 参考资料1、ARM公司的技术文档DAI0048A_scatterload.pdf,它是QualComm SR833973回复中的推荐读物。
它放在/pdfs/DAI0048A_scatterload.pdf。
2、《Scatter File介绍》杨彬3、80-V5842-1.pdf4、80-V6306-1_Rev_C_MSM6250_BSP.pdf4. ARM ImageARM中的源文件经过编译器编译生成的目标文件(Object file)和相应的C/C++运行时库(Runtime Library)经过连接器的处理后,生成ELF格式的映像文件(image)——它可以被写入目标设备的ROM中直接运行或加载后运行。
它的组成如图所示:一个映像文件由一个或多个域(region)组成;一个域包含一个或多个输出段(output section);一个输出段包含一个或多个输入段(input section);一个输入段包含了目标文件中的代码或数据;输入段通常有以下三类:R O:代码和常量数据;R W:带初始值的数据;Z I: 无初始值的数据;ARM映像文件各组成部分在存储系统中的地址有两种:z装载区域程序在装载之后,运行之前所占有的存储区域能够被分成多个装载区域,每个装载区域就是一个连续的字节块。
arm scatter loading的剖析及应用
ARM Scatter-Loading 的应用版本:Rev1.0 2008-04Team MCUZone更新记录2008.04.12文档创建。
ARM Scatter-Loading的应用-基于A T91SAM7S64与keilTeam MCUZone 本文简述如何在AT91SAM7S64(以下简称为S64)上使用ARM scatter-loading将代码加载到RAM中运行,完成对片上flash的编程。
相关代码使用realviewMDK中所带的realview工具链进行编译,重点在scatter loader。
一,准备工作1.安装软件对于S64之类的基于ARM的MCU,选用Realview MDK (keil)是个不错的选择,其所带的realview工具链比较强大。
遗憾的是,新版本的keil(到2008年4月)不支持RDI接口,只能使用ulink进行调试。
如果确实需要使用RDI工具调试,可以安装realview2.2。
使用RV Debugger调试keil生成的axf文件。
下面是realview MDK 3.20的版本说明:工具链是realview 3.1的版本。
2.安装调试器及相关软件根据使用的仿真器,安装好仿真器的驱动,以及对应的软件。
比如使用ulink,那么接上PC就会自动安装驱动,因为在安装keil的时候就有驱动。
如果使用jlink这类仿真器,那么就要安装对应的软件。
具体可以参考相关产品的使用说明。
3.获取ARM scatter loader的相关文档RealView® Compilation Tools Linker and Utilities Guide (ARM DUI 0206H)ARM Application Note 48 – Scatter Loading (ARM DAI 0048A)二,ARM Scatter-Loading简介1.ARM linkerARM linker将编译生成的.o文件与必要的库函数连接成一个可执行的image,也就是最终在目标板上运行的文件。
分散加载简介
1
什么是分散加载
分散加载是指定ARM连接器在生成映像文 件时如何分配RO,RW,ZI等数据的存放地址。 如果不分散加载,ARM连接器会按照默认的方 式来生成映像,一般情况下不用编写分散加载。 但是某些场合我希望把某些数据存放在指 定的地址处,那么分散加载就发挥了非常大的作 用。
2
如何分散加载
想要实现分散加载就需要编写分散加载文件 在keil中分散加载文件时.sct . 在IAR中是.icf文件 在ads中是.scf Scatter file实际是一个具有简单语法规则的文本文件,可以用来描述ARM连接器生成映像文件时 所需要的信息。 各个加载时域的加载地址、最大尺寸和属性; 从每个加载时域中分割出的运行时域; 各个运行时域的起始地址、最大尺寸和属性; 各个运行时域存储访问特性; 各个运行时域中包含的输入段;
3
分散加载文件语法
• LR_IROM1 0x08000000 0x00002000 第一个加载域,名字为LR_IROM1,起始地址为0x0,大小为0x80000 { ER_IROM1 0x08000000 0x00002000 加载域中的运行时域,名字为ER_IROM1,起始地址为0x08000000 ,大小为0x00002000 { *.o (RESET, +First) 将编译后生成的文件.o中的代码放在第一个起始地址。 *(InRoot$$Sections) .ANY (+RO) 以及所有编译生成的RO属性的代码全部存放在
ARM分散加载描述文件.scf的设置
片内16K RAM的顶端,存放不需要被"C libr ary"初始化的段。 注2
"+0"表示接着上一段"ERAM"的结尾,继续安 排存储区。 注3
在"Edit -> DebugRel Settings...->ARM Linker"中选中"Image map"。编译后在Error & Warnings窗口会显示出详细 的内存分配情况。如果在"List file name"中指定一个输出文件名,该祥单会直接存在制定文件中以供多次研究。
关于JTAG接口:
".scf"文件中的"+RW"对应".s"源文件中的"READWRITE". ".scf"文件中的"+ZI"对应".s"源文件中的"NOINIT". ".scf"文件中的"+RO"对应".s"源文件中的"READONLY".
在".s"源文件中有: AREA area_name CODE/DATA,READONLY/NOINIT/READWRITE END
注2: 在"Stack.o"里面会生成名为"Stacks"的段,段的属性为"NOINIT",该属性对应scf 文件中的"+ZI". 该段不需要初始化或者可以被初始化为"0".
mtk scatter编写规则
mtk scatter编写规则MTK Scatter编写规则MTK Scatter是一种用于编写手机ROM开发工具的规则文件,它是由MTK(联发科技)提供的一种用于分区和分散加载的配置文件。
本文将介绍MTK Scatter编写规则的相关内容,以帮助读者更好地理解和使用这一工具。
一、什么是MTK ScatterMTK Scatter是一种文本文件,用于描述Android手机的分区和分散加载信息。
在MTK平台上,手机的存储空间被分为不同的分区,每个分区都有自己的起始地址和大小。
MTK Scatter文件提供了这些分区的详细信息,包括分区名称、起始地址、大小等,以及用于加载ROM的相关信息。
二、MTK Scatter文件的基本结构MTK Scatter文件以XML格式编写,包含了一系列的标签和属性。
下面是一个简单的示例:```<?xml version="1.0" encoding="UTF-8"?><MTK_Scatter><Header></Header><Body><BootConfig></BootConfig><Partition></Partition><Download></Download></Body></MTK_Scatter>```MTK Scatter文件由三个主要部分组成:Header、Body和Partition。
Header部分用于描述文件的版本和作者等信息,Body 部分包含了BootConfig、Partition和Download等子标签,用于描述分区和加载信息。
三、分区信息的描述在MTK Scatter文件中,每个分区都用Partition标签来描述。
Partition标签包含了一系列的属性,如名称、文件名、起始地址、大小等。
mdk 使用分散加载文件定位函数
在Keil MDK(Microcontroller Development Kit)中,分散加载文件(Scatter-Loading File)是一种用于配置和定位在嵌入式系统中加载到存储器的程序和数据的文件。
分散加载文件通常使用链接脚本(Linker Script)进行配置,以指定程序和数据在存储器中的位置。
您可以使用分散加载文件和链接脚本来定位函数、变量以及其他程序元素。
以下是在Keil MDK中使用分散加载文件和链接脚本来定位函数的一般步骤:1. **创建分散加载文件**:- 在Keil MDK中,您可以通过选择“Project” > “Options for Target” > “Linker”来配置链接器设置。
- 在链接器选项中,您可以指定分散加载文件的名称和路径。
2. **编辑链接脚本**:- 创建或编辑链接脚本,以便定义程序和数据的存储器布局。
- 在链接脚本中,您可以使用关键字(如`CODE`, `DATA`, `RODATA` 等)来指定不同类型的存储器区域,并在这些区域中定位函数和变量。
- 通过将函数所属的源文件分配给特定存储器区域,您可以将函数定位到相应的存储器位置。
3. **分配函数到存储器区域**:- 在链接脚本中,通过使用`__attribute__` 或`#pragma` 指令(具体语法取决于您的目标芯片和编译器),将函数分配到所需的存储器区域。
- 例如,您可以使用以下方式将函数`myFunction` 分配到FLASH 存储器区域:```cvoid myFunction(void) __attribute__((section(".text")));```或```c#pragma location=".text"void myFunction(void);```4. **编译和链接**:- 编译和链接您的项目,确保分散加载文件和链接脚本配置正确。
KEIL下分散加载文件的使用
KEIL下分散加载文件的使用在KEIL下进行分散加载文件的使用可以通过在工程设置中进行配置来实现。
KEIL是一种嵌入式开发工具,可用于开发各种微控制器架构的应用程序。
分散加载(Scatter Loading)是一种在嵌入式系统中进行内存映射的技术,它通过将不同的代码段和数据段分散加载到不同的物理地址上,实现有效的内存管理和资源分配。
要在KEIL下使用分散加载文件,可以按照以下步骤进行配置:1. 打开KEIL软件,选择要进行配置的项目工程,在菜单栏中选择Project -> Options for Target。
2. 在弹出的对话框中,选择"Output"选项卡,然后点击"Manage"按钮。
3. 在下方的列表中,点击"Add"按钮,然后选择要进行分散加载的文件。
4.在弹出的对话框中,选择要添加的文件,并设置加载地址和加载大小,然后点击"OK"。
5.重复步骤3和4,将所有要进行分散加载的文件都添加到列表中。
6.设置每个分散加载文件的加载地址和加载大小,以确保它们不会重叠或冲突。
7.在列表中选择每个分散加载文件,并使用上下箭头按钮来调整它们的加载顺序。
8.最后,点击"OK"保存配置信息。
通过上述步骤,我们可以实现对不同代码段和数据段的分散加载,从而实现对内存资源的有效管理和分配。
在KEIL中,配置完成后,编译和生成可执行文件时将按照配置的分散加载文件进行内存映射和分配。
使用分散加载文件可以帮助我们更好地管理内存资源,提高系统性能和效率。
需要注意的是,在进行分散加载文件配置时,需要确保分散加载文件之间不会出现重叠或冲突。
同时,还需要根据硬件平台和应用程序的需求,合理设定加载地址和加载大小。
KEIL作为一款功能强大的嵌入式开发工具,支持分散加载文件的配置,可以帮助开发人员更好地进行内存管理和资源分配,使嵌入式应用程序更加高效和可靠。
MTK Scatter文件学习
MTK Scatter文件学习概述:分散加载(scatter loading)是ARM 连接接器提供的一个机制,该机制可以把一个可执行映像文件(即Bin文件)分割放置到内存中不同的独立段。
映像(Image)文件有两个视图:加载视图(Load view) 和执行视图(execution view)。
在下载的时候Image regions被放置在memory map当中,而在执行Image前,或许你需要将一些regions放置在它们执行时的地址上,并建立起ZI regions。
例如,你初始化的RW数据需要从它在下载时的在ROM中的地址处移动到执行时RAM的地址处。
在scatter 文件中可以为每一个代码或数据段在装载和执行时指定不同的存储区域地址,Scatlertoading的存储区块可以分成二种类型:装载区:当系统启动或加载时应用程序的存放区。
执行区:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行区。
映像中所有的代码和数据都有一个装载地址和运行地址(二者可能相同也可能不同,视具体情况而定)。
在系统启动时,C函数库中的__main初始化代码会执行必要的复制及清零操作,使应用程序的相应代码和数据段从装载状态转入执行状态。
为什么需要Scatter文件:制定存储器映射(memory map)的方法基本上有二种,一是在link时使用命令行选项,并在程序执行前利用linker pre-define symbol使用汇编语言制定section的段初始化,二是使用scatter file,即采用“分散加载机制”。
以上二种方法依应用程序的复杂度而定,一针对简单的情况,二针对复杂的情况。
手机属于复杂的情况,必须使用scatter file。
Scatter文件语法:scatter文件是一个简单的文本文件,包含一些简单的语法(分号后面的内容是注释):My_Region 0x0000 0x1000 ;区域名称区起始地址区长度{the context of region ;区内容}每个区由一个头标题开始定义,头中至少包含区的名字和起始地址,另外还有最大长度和其他一些属性选项。
scatter文件的写法
码和数据段的放置位置。这可以通过在 scatter 文件中对单个目标文件进行定义实现,而不是只简单地依
靠通配符。
为了覆盖标准的连接器布局规则,我们可以使用+FIRST 和+LAST 分散加载指令。典型的例子
是在执行块的开始处放置中断向量表格:
LOAD_ROM 0x0000 0x4000
{
EXEC_ROM 0x0000 0x4000
base_designator 用来表示本输出段的起始地址,它可以有两种格式:起始地址值或偏移量。
ห้องสมุดไป่ตู้ttribute
表示本输出段的属性,其可能的取值如下所示:
o PI
位置无关属性
o RELOC
重定位
o ABSOLUTE
绝对地址
o FIXED
固定地址
o UNINIT
未初始化的数据
Scatter文件编写
Scatter文件编写一个映像文件中可以包含多个域(region),在加载和运行映像文件时,每个域可以有不同的地址。
每个域可以包括多达3个输出段,每个输出段是由若干个具有相同属性的输入段组成。
这样在生成映像文件时,ARM链接器就需要知道下述两个信息。
∙分组信息决定各域中的输出段是由哪些输入段组织而成;∙定位信息决定各域在存储空间中的起始地址。
根据映像文件中地址映射的复杂程度,有两种方法来告诉ARM链接器这些相关的信息。
对于映像文件中地址映射关系比较简单的情况,可以使用命令行选项;对于映像文件中地址映射关系比较复杂的情况,可以使用一个scatter配置文件。
Scatter文件又称为分散加载文件,将重点讲解如何编写scatter文件。
1、Scatter文件结构Scatter文件是一个文本文件,使用BNF语法来描述ARM链接器生成映像文件时所需要的信息。
具体来说,在scatter文件中可以指定下列信息:∙各个加载时域的加载时起始地址、最大尺寸和属性;∙每个加载时域包含的输出段;∙各个输出段的运行时起始地址、最大尺寸、存储访问特性和属性;∙各个输出段中包含的输入段。
一个Scatter文件包含若干个加载域,一个加载域包含若干个输出段,一个输出段由若干个具有相同属性的输入段组成,其结构如图1所示。
图1 Scatter文件结构示意图①加载时域的描述加载时域包括名称、起始地址、属性、最大尺寸和一个运行时域的列表。
使用BNF语法描述,加载时域的格式如下所示:Load_name base_designator attribute max_size{……}∙Load_name 运行时域名称,它除了唯一地标识一个运行时域外,还用来构成链接器生成的链接符号;∙base_designator 用来表示本加载时域的起始地址,它可以有两种格式表示:起始地址或偏移量;∙attribute 本加载时域的属性,其可能的取值为下面之一,默认的取值为ABSOLUTE:∙PI 位置无关属性;∙RELOC 重定位;∙ABSOLUTE 绝对地址;<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml"/> <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />图2 程序运行时地址映射关系的地址进行分配。
Keil环境下分散加载的使用技巧
对于分散加载的概念,在《ARM体系结构与编程》书中第11章有明确介绍。
分散加载文件(即scatter file 后缀为.scf)是一个文本文件,通过编写一个分散加载文件来指定ARM连接器在生成映像文件时如何分配RO,RW,ZI等数据的存放地址。
如果不用SCATTER文件指定,那么ARM连接器会按照默认的方式来生成映像文件,一般情况下我们是不需要使用分散加载文件的。
但在某些场合,我们希望把某些数据放在指定的地址处,那么这时候SCATTER文件就发挥了非常大的作用。
而且SCATTER文件用起来非常简单好用。
举个例子:比如像LPC2378芯片具有多个不连续的SRAM,通用的RAM是32KB,可是32KB不够用,我想把某个.C中的RW数据放在USB的SRAM中,那么就可以通过SCATTER文件来完成这个功能。
下面是就这个例子作的说明:这是一个标准的常用的分散加载文件,现在加注释于后,方便以后查阅:;******************************************************************************;; SCATTER LOADING DESCRIPTION; ARM; KEIL's uVision3; (RealView Microprocessor Developer Kit);; Filename : LPC2378_Flash.scat;******************************************************************************LR_IROM1 0x00000000 0x00080000 ;; 第一个加载域,名字为LR_IROM1,起始地址为0x0,大小为0x80000 {ER_IROM1 0x00000000 0x00080000 ;; 加载域中的运行时域,名字为ER_IROM1,起始地址为0x0,大小为0x80000 {vectors.o (VECT, +First) ;; 将vectors.c编译后生成的文件vectors.o中的代码init.o (INIT) ;; 以及init.o中的代码* (+RO) ;; 以及所有编译生成的RO属性的代码全部存放在} ;; 运行时域ER_IROM1指定的地址范围内,存放方式:顺序存放RW_IRAM1 0x40000000 0x0000e800 ;; 这是第二个运行时域,功能同上{ ;; 其中*是代表具有()里面指定的属性的全部数据*(+RW,+ZI) ;; 与*功能相似的有.ANY,后面说明} ;; The following declarations select the "two region model" ;;; A default __user_initial_stackheap() will be used;ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {} ;;指定堆栈地址ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}}下面是针对LPC2378的USB SRAM作数据RAM使用的配置:;******************************************************************************;; SCATTER LOADING DESCRIPTION; ARM; KEIL's uVision3; (RealView Microprocessor Developer Kit);; Filename : LPC2378_Flash.scat;******************************************************************************LR_IROM1 0x00000000 0x00080000 ;; 第一个加载域,名字为LR_IROM1,起始地址为0x0,大小为0x80000 {ER_IROM1 0x00000000 0x00080000 ;; 加载域中的运行时域,名字为ER_IROM1{ ;; 起始地址为0x0,大小为0x80000vectors.o (VECT, +First)init.o (INIT)* (+RO)}RW_IRAM1 0x40000000 0x0000e800{.ANY(+RW,+ZI)} ;; The following declarations select the "two region model" ; ;; 此处.ANY替换原来的*,是因为下面的一个执行域对指定的模块中的RW,ZI数据指定了存放地址,;; 用.ANY就可以把已经被指定的具有RW,ZI属性的数据排除WEBRPGRADE 0x7fd00000 0x1fff{webupgrade.o(+RW,+ZI) ;; webupgrade.o文件中所有变量都存在USB SRAM中};; A default __user_initial_stackheap() will be used;ARM_LIB_HEAP 0x40007000 EMPTY 0x00000100 {}ARM_LIB_STACK 0x40008000 EMPTY -0x00000E00 {}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
分散加载文件及其应用分散加载能够将加载和运行时存储器中的代码和数据描述在被称为分散加载描述文件的一个文本描述文件中,以供连接时使用。
(1)分散加载区分散加载区域分为两类:• 加载区,包含应用程序复位和加载时的代码和数据。
• 执行区,包含应用程序执行时的代码和数据。
应用程序启动过程中,从每个加载区可创建一个或多个执行区。
映象中所有的代码和数据准确地分为一个加载区和一个执行区。
(2)分散加载文件示例ROM_LOAD 0x0000 0x4000{ROM_EXEC 0x0000 0x4000; Root region{* (+RO); All code and constant data}RAM 0x10000 0x8000{* (+RW, +ZI); All non-constant data}}(3)分散加载文件语法load_region_name start_address | "+"offset [attributes] [max_size]{execution_region_name start_address | "+"offset [attributes][max_size] {module_select_pattern ["("("+" input_section_attr | input_section_pattern)([","] "+" input_section_attr | ","input_section_pattern)) *")"]}}load_region:加载区,用来保存永久性数据(程序和只读变量)的区域;execution_region:执行区,程序执行时,从加载区域将数据复制到相应执行区后才能被正确执行;load_region_name:加载区域名,用于“Linker”区别不同的加载区域,最多31个字符;start_address:起始地址,指示区域的首地址;+offset:前一个加载区域尾地址+offset 做为当前的起始地址,且“offset”应为“0”或“4”的倍数;attributes:区域属性,可设置如下属性:PI 与地址无关方式存放;RELOC 重新部署,保留定位信息,以便重新定位该段到新的执行区;OVERLAY 覆盖,允许多个可执行区域在同一个地址,ADS不支持;ABSOLUTE 绝对地址(默认);max_size:该区域的大小;execution_region_name:执行区域名;start_address:该执行区的首地址,必须字对齐;+offset:同上;attributes:同上;PI 与地址无关,该区域的代码可任意移动后执行;OVERLAY 覆盖;ABSOLUTE 绝对地址(默认);FIXED 固定地址;UNINIT 不用初始化该区域的ZI段;module_select_pattern:目标文件滤波器,支持通配符“*”和“?”;*.o匹配所有目标,* (或“.ANY”)匹配所有目标文件和库。
input_section_attr:每个input_section_attr必须跟随在“+”后;且大小写不敏感;RO-CODE 或CODERO-DATA 或CONSTRO或TEXT, selects both RO-CODE and RO-DATARW-DATARW-CODERW 或DATA, selects both RW-CODE and RW-DATAZI 或BSSENTRY, that is a section containing an ENTRY point.FIRST,用于指定存放在一个执行区域的第一个或最后一个区域;LAST,同上;input_section_pattern:段名;汇编中指定段:AREA vectors, CODE, READONLYC中指定段:#pragma arm section [sort_type[[=]"name"]] [,sort_type="name"]*sort_type: code、rwdata、rodata、zidata如果“sort_type”指定了但没有指定“name”,那么之前的修改的段名将被恢复成默认值。
#pragma arm section // 恢复所有段名为默认设置。
应用:#pragma arm section rwdata = "SRAM",zidata = "SRAM"static OS_STK SecondTaskStk[256]; // “rwdata”“zidata”将定位在“sram”段中。
#pragma arm section // 恢复默认设置(4)程序中对区域地址引用的方法Load$$region_name$$Base Load address of the region.Image$$region_name$$Base Execution address of the region.Image$$region_name$$Length Execution region length in bytes (multiple of 4).Image$$region_name$$Limit Address of the byte beyond the end of the execution region.Image$$region_name$$ZI$$Base Execution address of the ZI output section in this region.Image$$region_name$$ZI$$Length Length of the ZI output section in bytes (multiple of 4).Image$$region_name$$ZI$$Limit Address of the byte beyond the end of the ZI output sectionin the execution region.SectionName$$Base Input Address of the start of the consolidated section called SectionName.SectionName$$Limit Input Address of the byte beyond the end of the consolidated section called SectionName.Load:加载区,即存放地址;Image:执行区,即运行地址;Base:区首地址;Limit:区尾地址;Length:区长度;region_name:RO、RW、ZI、load_region_name、execution_region_name;例如:“RAM1”区域的首地址:Image$$RAM1$$Base上例中“sram”段首地址:sram$$Base汇编引用示例:IMPORT |Load$$Exec_RAM1$$Base| // Exec_RAM1 为“RW”段IMPORT |Image$$Exec_RAM1$$Base|IMPORT |Image$$Exec_RAM1$$Length|IMPORT |Image$$Exec_RAM1$$Limit|LDR R0, =|Load$$Exec_RAM1$$Base|LDR R1, =|Image$$Exec_RAM1$$Base|LDR R2, =|Image$$Exec_RAM1$$Limit|CMP R1, R2LDRCC R3, [R0], #4STRCC R3, [R1], #4BCC %b0C 引用:extern unsigned char Load$$Exec_RAM1$$Base;extern unsigned char Image$$Exec_RAM1$$Base;extern unsigned char Image$$Exec_RAM1$$Length;void MoveRO(void){unsigned char * psrc, *pdst;unsigned int count;count = (unsigned int) &Image$$Exec_RAM1$$Length;psrc = (unsigned char *)&Load$$Exec_RAM1$$Base;pdst = (unsigned char *)&Image$$Exec_RAM1$$Base;while (count--) {*pdst++ = *psrc++;}}二.分散加载应用前面提到过,从NAND Flash启动,对于S3C2410而言,由于片内具有4K的称作"SteppingStone"的SRAM,NAND FLASH的最低4K代码可以自动复制到"SteppingStone",因此可以将初始化等代码放在NAND FLASH的低4K区域内,其他的代码放置在4K以外,在初始化代码内将这些代码复制到外部SDRAM,从而这些代码可以在外部SDRAM内运行。
1.应用实例描述先完成初始化操作,并且在初始化代码中将NAND FLASH的4K范围以外的代码(简单起见,这部分代码可以操作LED灯)复制到外部SDRAM中。
主要目的是使用分散加载文件以及将NAND FLASH中的数据代码复制到SDRAM中。
2.分散加载文件NAND_FLASH_LOAD 0x0 0x1000{RAM_EXEC +0 0x1000{;参见前面的加载文件语法}}NAND_FLASH_LOAD2 0x1000{SDRAM_EXEC 0x30000000{;参见前面的加载文件语法}}(1)将一些初始化代码放在第一个加载区(根区:加载地址和执行地址相同的区域,每一个分散加载描述文件必须至少要有一个根区。
),地址范围为:0x0000~0x0fff的4K,其执行区的地址范围也是0x0000~0x0fff的4K,这正好是NAND FLASH启动时自动复制的地址范围。
(2)其他代码放在第2个加载区,从地址0x1000开始,由于这一部分不能自动复制,因此在初始化代码中应该将这一部分复制到外部SDRAM中,其执行区的起始地址为外部SRDAM的地址。
3. 二进制文件烧录由于有2个加载区,因此生成的二进制文件有2个,文件名对应于相应的执行区名,分别是RAM_EXEC和SDRAM_EXEC,需要注意的是,应该将存放初始化代码的加载区对应的二进制文件RAM_EXEC烧录NAND FLASH的低4K区域,第二个加载区对应的二进制文件SDRAM_EXEC烧录到4K以后的区域。