Scatterfile(分散加载描述文件)用于armlink的输入参数,他指定映像文件内部各区域的download与运行时位置。Armlink将会根据scatterfile生成一些区域相关的符号,他们是全局的供用户建立运行时环境时使用。注意:当使用了scatterfile时将不会生成以下符号:Image$$RW$$Base,Image$$RW$$Limit,Image$$RO$$Base,Image$$RO$$Limit,Image$$ZI$$Base,Image$$ZI$$Limit分散加载(Scatlerloading),即工程里的.scf文件。在scatterfile中可以为每一个代码或数据区在装载和执行时指定不同的存储区域地址,Scatlertoading的存储区块可以分成二种类型:装载区:当系统启动或加载时应用程序的存放区。执行区:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行块。映像中所有的代码和数据都有一个装载地址和运行地址(二者可能相同也可能不同,视具体情况而定)。一、scatter文件语法:scatter文件是一个简单的文本文件,包含一些简单的语法。MyRegion0x00000x1000{;thecontextofregion}标题:每个块由一个头标题开始定义,头中至少包含块的名字(自己定义)和起始地址,如0x0000,另外还有最大长度等其他一些属性选项(注:这些属性是可选的,如0x1000)内容:块定义的内容包括在紧接的一对花括号内,依赖于具体的系统情况。一个加载块(加载时域)必须至少含有一个执行块(运行时域);实践中通常有多个执行块。一个执行块必须至少含有一个代码或数据段;这些通常来自源文件或库函数等的目标文件;通配符号*可以匹配指定属性项中所有没有在文件中定义的余下部分。一个映像文件由域(region)、输出段(outputsections)和输入段(inputsections)组成。不要想得太复杂,其实他们之间就是包含与被包好的关系。具体关系是这样的:映像文件域输出段输入段输入段:输入段就是我们写的代码+初始化的数据+应该被初始化为0的数据+没有初始化的数据,用英文表示一下就是:RO(ReadOnly),RW(ReadWrite),ZI(ZeroInitialized),NOINIT(NotInitialized)。ARM连接器根据各个输入段不同的属性把相同的拿再一起组合一下就成为了输出段。请看看平时写的东东:AREARESET,CODE,READONLYAREADSEG1,DATA,READWRITEAREAHEAP,NOINIT,READWRITE看出其属性没?输出段:为了简化编译过程和更容易取得各种段的地址,那么把多个同属性的输入段按照一定的规律组合在一起,当然这个输出段的属性就和它包含的输入段的属性一样咯。输入段的排放规律就是:最先排放RO属性的输入段,然后是RW属性段,最后是ZI或NOINIT段。域:为什么还要加一层域,我的理解是由于代码的功能不同,那么我们有必要把不同功能的代码分类放。我们可以把需要高速执行的代码放在一起、把对速度要求不高的放在一起、把执行频率高的放在一起,把执行频率低的放在一起...那么按照这种方式放的代码就可以根据其具体需要放在不同的存储器中了。这样可以提高程序执行速度。一个域中包含1~3个输出段。映像文件:我暂时把映像文件理解成烧到存储器中的文件,由N个域组成。这些域其实可以看做是独立的模块,只是他们按照一定的顺序(这个顺序还是:RO+RW+ZI)被捆绑在一起,这样才方便烧写到非易失存储器中去。好了,了解了映像文件的组成,那么来看看映像文件是怎么跑起来的。映像文件就是有N节车厢的火车,车厢(域)里装着要送到不同站(不同类型的存储器)的货物。到相应的站了,那么就把相应的车厢拿下来。指挥拿这个的就是scatter文件。拿下货物车厢后,我们就解开它,把里面的品牌为RO的货物提取出来,按照scatter的指示发给某个地址,然后再先后把品牌为RW和ZI的货物发到scatter指定的地址。二、什么时候使用scatterfile当然首要的条件是你在利用ADS进行项目开发,下面我们看看更具体的一些情况。1存在复杂的地址映射:例如代码和数据需要分开放在在多个区域。2存在多种存储器类型:例如包含Flash,ROM,SDRAM,快速SRAM。我们根据代码与数据的特性把他们放在不同的存储器中,比如中断处理部分放在快速SRAM内部来提高响应速度,而把不常用到的代码放到速度比较慢的Flash内。3函数的地址固定定位:可以利用Scatterfile实现把某个函数放在固定地址,而不管其应用程序是否已经改变或重新编译。4利用符号确定堆与堆栈:5内存映射的IO:采用scatterfile可以实现把某个数据段放在精确的地指处。因此对于嵌入式系统来说scatterfile是必不可少的,因为嵌入式系统采用了ROM,RAM,和内存映射的IO。三、scatterfile实例1简单的内存映射LOAD_ROM0x00000x8000{EXEC_ROM0x00000x8000{*(+RO)}RAM0x100000x6000{*(+RW,+ZI)}}详解:LOAD_ROM(下载区域名称)0x0000(下载区域起始地址)0x8000(下载区域最大字节数){EXEC_ROM(第一执行区域名称)0x0000(第一执行区域起始地址)0x8000(第一执行区域最大字节数){*(+RO(代码与只读数据))}RAM(第二执行区域名称)0x10000(第二执行区域起始地址)0x6000(第二执行区域最大字节数){*(+RW(读写变量),+ZI(未初始化变量))}}2复杂内存映射LOAD_ROM_10x0000{EXEC_ROM_10x0000{program1.o(+RO)}DRAM0x180000x8000{program1.o(+RW,+ZI)}}LOAD_ROM_20x4000{EXEC_ROM_20x4000{program2.o(+RO)}SRAM0x80000x8000{program2.o(+RW,+ZI)}}详解:LOAD_ROM_10x0000(下载区域一起始地址){EXEC_ROM_10x0000(第一执行区域开始地址){program1.o(+RO)(program1.o内的Code与ROdata放在第一执行区域)}DRAM0x18000(第二执行区域开始地址)0x8000(第二执行区域最大字节数){program1.o(+RW,+ZI)(program1.o内的RWdata与ZIdata放在第二执行区域)}}LOAD_ROM_20x4000(下载区域二起始地址){EXEC_ROM_20x4000{program2.o(+RO)(program2.o内的Code与ROdata放在第一执行区域)}SRAM0x80000x8000{program2.o(+RW,+ZI)(program2.o内的RWdata与ZIdata放在第二执行区域)}}2.1BNF符号与语法:由引号赖标示的符号保持其字面原意,如A”+”B标示A+B。A::=B:定义A为B。[A]:标示可选部分,如A[B]C用来标示ABC或AC。A+:用来标示A可以重复任意次,如A+可标示A,AA,AAA,…A*:同A+。A|B:用来标示选择其一,不能全选。如A|B用来标示A或者B。(AB):标示一个整体,当和|符号或复杂符号的多次重复一起使用时尤其强大,如(AB)+(C|D)标示ABC,ABD,ABABC,ABABD,…2.2分散加载文件各部分描述(2.1)如图2.1所示为一个完整的分散加载脚本描述结构图。下面我们对图示中各个部分进行讲述。2.2.1加载区描述每个加载区有:名称:供连接器确定不同下载区域基地址:相对或绝对地址属性:可选最大字节数:可选执行区域列:确定执行时各执行区域的类型与位置load_region_name(base_address|(+offset))[attribute_list][max_size]{execution_region_description+}load_region_name:下载区域名称,最大有效字符数31。(并不像执行区域段名用于Load$$region_name,而是仅仅用于标示下载区域)。base_address:本区域内部目标被连接到的地址(按字对齐)。+offset:相对前一个下载区域的偏移量(4的整数倍,如果为第一个区域)。2.2.2执行区描述每个执行区有:名称:供连接器确定不同下载区域基地址:相对或绝对地址属性:确定执行区域的属性最大字节数:可选输入段:确定放在该执行区域的模块exec_region_name(base_address|+offset)[attribute_list][max_size]{input_sec_desc+}exec_region_name:执行区域名称,最大有效字符数31。base_address:本执行区域目标要被联接到的位置,按字对齐。+offset:相对于前一个执行区域结束地址的偏移量,4的整数倍;如果没有前继之能够行区域(本执行区域为该下载区域的第一个执行区域),则该偏移量是相对于该下载区域的基址偏移量。attribute_list:PI,OVERLAY,ABSOLUTE,FIXED,UNINIT。PI:位置独立。OVERLAY:覆盖。ABSOLUTE:绝对地址。FIXED:固定地址,下载地址与执行地址具有该地址指示确定。UNINIT:未初始化数据。RELOC:无法明确指定执行区域具有该属性,而只能通过继承前一个执行区或父区域获得。对于PI,OVERLAY,ABSOLUTE,FIXED,我们只能选择一个,缺省属性为ABSOLUTE。一个执行区域要么直接继承其前面的执行区域的属性或者具有属性为ABSOLUTE。具有PI,OVERLAY,RELOC属性的执行区域允许其地址空间重叠,对于BSOLUTE,FIXED属性执行区域地址空间重叠Armlink会报错。max_size:可选,他用于指使Armlink在实际分配空间大于指定值时报错。input_sec_desc:指示输入段的内容。2.2.3输入段描述输入段:模块名:目标文件名,库成员名,库文件名。名称可以使用通配符。输入段名,或输入段属性(READ-ONLY,CODE)。module_select_pattern[((+input_section_attr|input_section_pattern)([,]+input_section_attr|,input_section_pattern))*)]2.2.3.1module_select_pattern:选择的模块名称(目标文件,库文件成员,库文件),模块名可以使用通配符(*匹配任意多个字符,?匹配任意一个字符),名称不区分字母大小写,它是供选择的样本。例1:*libtx.a(+RO)libtx.a为threadX库文件。例2:tx_ill.o(INIT)tx_ill.o为threadX中断向量目标文件。2.2.3.2input_section_attr:输入段属性选择子,每个选择子以”+”开头,选择子不区分大小写字符。选择子可选:RO-CODE,RO-DATA,RO(selectsbothRO-CODEandRO-DATA),RW-DATA,RW-CODE,RW(selectsbothRW-CODEandRW-DATA),ZI,ENTRY(thatisasectioncontaininganENTRYpoint)。以下同义词可以选择:CODE(forRO-CODE),CONST(forRO-DATA),TEXT(forRO),DATA(forRW),BSS(forZI)。还有两个伪属性:FIRST,LAST。如果各段的先后顺序比较重要时,可以使用FIRST,LAST标示一个执行区域的第一个和最后一个段