arm处理器的分散加载及特殊应用研究

上传人:wt****50 文档编号:32820613 上传时间:2018-02-12 格式:DOC 页数:6 大小:567KB
返回 下载 相关 举报
arm处理器的分散加载及特殊应用研究_第1页
第1页 / 共6页
arm处理器的分散加载及特殊应用研究_第2页
第2页 / 共6页
arm处理器的分散加载及特殊应用研究_第3页
第3页 / 共6页
arm处理器的分散加载及特殊应用研究_第4页
第4页 / 共6页
arm处理器的分散加载及特殊应用研究_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《arm处理器的分散加载及特殊应用研究》由会员分享,可在线阅读,更多相关《arm处理器的分散加载及特殊应用研究(6页珍藏版)》请在金锄头文库上搜索。

1、ARM处理器的分散加载及特殊应用研究时间:2009-05-08 10:45:03 来源:单片机与嵌入式系统应用 作者:桂林长海发展有限责任公司 夏爽摘要 从 ARM ELF 目标文件主要构成出发,详细介绍了分散加载的基本原理、分散加载文件的语法、分散加载时连接器生成的预定义符号及要重新实现的函数等;以定位目标外设和定义超大型结构体数组两项应用来加以说明,并给出完整的工程实例和Bootloader 代码。这些都已经在实际工程中多次应用和验证,是笔者实际工程项目的萃取。关键词 分散加载 嵌入式系统 Scatter Loading Bootloader ARM ELF引 言在当今的嵌入式系统设计中,

2、ARM 处理器以价格便宜、功耗低、集成度高、外设资源丰富和易于使用的特点而得到广泛的应用;在速度和性能方面已达到或超过部分 PC104 嵌入式计算机的性能,而成本却比相应的 PC104 计算机低很多,广泛应用于手机、GPS 接收机、地图导航、路由器、以太网交换机及其他民用和工业电子设备。在一个采用 ARM 处理器的实时嵌入式系统中,目标硬件常常由Flash、SRAM、SDRAM 和 NVRAM(非易失性 RAM)等存储器组成,并定位于不同的物理地址范围,那么,怎样通过软件更好地访问和利用这些不同的存储器并让系统高效地运行?分散加载(scatter loading)就提供了这样一种机制。它可以将

3、内存变量定位于不同的物理地址上的存储器或端口,通过访问内存变量即可达到访问外部存储器或外设的目的;同时通过分散加载,让大多数程序代码在高速的内部 RAM 中运行,从而使得系统的实时性大大增强。1 ARM ELF 目标文件的主要构成ARM ELF(Executable and Linking Format)目标文件主要由Text 段、Data 段、BSS 段构成,其他段如debug 段、comment 段等与本文关系不大,不作介绍。 Text 段由可执行代码组成,段类型为 Code,属性为 RO; Data 段由已初始化数据组成,段类型为 Data,属性为 RO; BSS 段由未初始化数据组成,

4、段类型为 Zero,属性为 RW,在应用程序启动时对该段的数据初始化为零。如果在分散加载文件中指定了 UNINIT 属性,则在应用程序启动时不初始化该段。2 分散加载的基本原理假设一个采用 ARM 处理器的实时嵌入式系统目标硬件的存储器由 ROM 存储器和 RAM存储器组成。当一个嵌入式系统在仿真环境下调试完毕,需要脱机运行的时候,就需要将源程序编译连接成可执行目标代码并烧写到 ROM 存储器中。由于 ROM 存储器存取数据的速率比 RAM 存储器慢,因此,让程序在 ROM 存储器中运行。CPU 每次取指令和取数据操作都要访问 ROM 存储器,这样需要在 CPU 的总线周期中插入等待周期,通过

5、降低总线的速率来满足访问慢速的 ROM 存储器,这样势必会降低 CPU 的运行速率和效率,因此,分散加载就显得非常必要。ARM 的连接器提供了一种分散加载机制,在连接时可以根据分散加载文件(scf 文件)中指定的存储器分配方案,将可执行镜像文件分成指定的分区并定位于指定的存储器物理地址。这样,当嵌入式系统在复位或重新上电时,在对 CPU 相应寄存器进行初始化后,首先执行 ROM 存储器的 Bootloader(自举)代码,根据连接时的存储器分配方案,将相应代码和数据由加载地址拷贝到运行地址,这样,定位在 RAM 存储器的代码和数据就在 RAM存储器中运行,而不再从 ROM 存储器中取数据或取指

6、令,从而大大提高了 CPU 的运行速率和效率。分散加载的基本原理如图 1 所示。3 分散加载文件语法在一个实时嵌入式系统中,分散加载文件是对目标硬件中的多个存储器块的分块描述,它直接对应目标硬件存储器的起始地址和范围。同时,它在应用程序连接时用于告诉连接器用户程序代码和数据的加载地址和运行地址,在连接时由连接器产生相应的加载地址和运行地址符号,包括代码和数据的加载起始地址、运行地址和长度等。这些符号用于上电后执行启动代码的数据拷贝工作,启动代码根据这些符号,将指定代码和数据由 ROM 中的加载地址拷贝到 RAM 中的运行地址中,从而实现代码在高速 RAM 存储器中的脱机运行。其语法格式如下:

7、注意:每一个分散加载文件必须至少包含一个根区,每个根区的加载地址等于执行地址。每一个引导区必须至少包含一个执行区,每一个执行区必须至少包含一个代码段或数据段;一个引导区可以包含几个执行区,每一个执行区只能属于一个引导区。4 分散加载时连接器生成的预定义符号在编译连接时如果指定了分散加载文件(scf 文件),在连接后会自动生成如下变量: 5 重新实现_user_initial_stEickheap()函数分散加载机制提供了一种指定代码和静态数据布局的方法。使用分散加载时,必须重新放置堆栈和堆。应用程序的堆栈(stack)和堆(heap)是在 C 库函数初始化过程中建立起来的,在ADSl2 或更新

8、版本中,在缺省状态下 C 库函数初始化代码会将连接器生成的符号Image$ZI$Limit 地址作为堆的基地址。在分散加载时,连接器会将用户的_user_initidl_stackheap()函数代替 C 库函数默认的堆栈和堆初始化函数,并将其连接到用户的镜像文件中,用户可通过重新实现_user_initial_stackheap()函数来改变堆栈和堆的位置,从而适合自己的目标硬件。_user_initial_stackheap()可以用 C 或汇编语言来实现。它必须返回如下参数:r0堆基地址;r1堆栈基地址;r2堆长度限制值(需要的话);r3堆栈长度限制值(需要的话)。当用户使用分散加载功能

9、的时候,必须重新实现一 user_initial_staacklaeap(),否则连接器会报错:Error:L6218E:Undefined symbol Imager$ZI$一 Limit(referred from sys_stackheapo)。注: Image$ZI$Limit 变量为零初始化段(ZI 段)的末地址。未使用分散加载时,堆默认就定位在 ZI 段的末地址,如图 2 所示。_user_initial_stackheap()函数的实现有两种方法。(1)共用一个存储区汇编语言如下:这种方式定义的堆栈和堆共用一个存储区,采用相向的增长方向,如图 3 所示。(2)使用两个存储区汇编语

10、言如下:这种方式定义的堆栈和堆分别采用两个不同存储区。堆栈采用向下增长,从地址Ox40000 到地址 Ox20000;堆采用向上增长,从地址 0x28000000 到地址0x28080000,如图 4 所示。6 特殊应用6. 1 定位目标外设使用分散加载,可以将用户定义的结构体或代码定位到指定物理地址上的外设,这种外设可以是定时器、实时时钟、静态 SRAM 或者是两个处理器间用于数据和指令通信的双端口存储器等。在程序中不必直接访问相应外设,只需访问相应的内存变量即可实现对指定外设的操作,因为相应的内存变量定位在指定的外设上。这样,对外设的访问看不到相应的指针操作,对结构体成员的访问即可实现对外

11、设相应存储单元的访问,让程序员感觉到仿佛没有外设,只有内存。例如,一个带有两个 32 位寄存器的定时器外设,在系统中的物理地址为Ox04000000,其 C 语言结构描述如下: 要使用分散加载将上述结构体定位到 Ox04000000 的物理地址,可以将上述结构体放在一个文件名为 timer_regsc 中,并在分散加载文件中指定即可,如下:属性 UNINIT 是避免在应用程序启动时对该执行段的 ZI 数据段初始化为零。在程序连接后,通过 Image map 文件可查看该 ZI 数据段的存储器分配情况:Execution Region TIMER(Base:Ox04000000,Size:0x0

12、0000008,Max:0xffffffff,ABSOLUTE,UNINIT)Base Addr Size Type Attr Idx E Section Name 0bi ectOx04000000 0x00000008 Zero RW 32bss tlmer_regso 从 Image map 文件可以看出,该 TIMER 执行区定位在物理地址 0x04000000,即结构体 timer_regs 定位在 Ox04000000,因此,在程序中对结构体的操作即是对定时器的操作。62 定义超大型结构体数组分散加载机制在提供将指定代码和数据定位在指定物理地址的能力的同时,也提供了一种代码分割机制

13、可以将指定的零初始化段(ZI 段)从可执行代码中分离出来。这样最终生成的烧入 ROM 或 Flash 中的镜像文件就不包括那部分分割了的零初始化段,即使该零初始化段再大,也不影响最终生成的镜像文件的大小。但不采用分散加载机制,零初始化段在编译连接后是直接生成到镜像文件中的。它的大小直接影响最终要烧写的文件的大小,且零初始化段的大小还取决于内存的大小,它不能大到超过内存的大小;而采用分散加载机制,可以将某个零初始化段定位到非内存地址的一个存储器外设上,如 NVRAM(非易失性随机存储器)。笔者曾在一个实际工程中采用这种分散加载机制,将一个 2MB 的结构体数组定位到外部 NVRAM 中,用于记录

14、设备在工作过程中采集到的数据;而在本系统中,ARM 处理器的内存只有 256 KB,Flash 存储器也只有 2 MB。如果不采用分散加载,程序根本无法运行,也不能烧写到 Flash 中。采用分散加载,把对复杂外设的访问变成对结构体数组的访问,使程序代码精简易懂。对程序员来说,对结构体数组的操作还是和内存变量的操作一样的。编者注:本文为期刊缩略版,全文见本刊网站 wwwmesnetcomcn。结 语分散加载是嵌入式系统应用中不可或缺的一种加载方式,ARM、DSP、PowerPC 和MIPS 等嵌入式处理器,都离不开分散加载。这种分散加载的思想是通用的,只是不同处理器的实现方式不同。本文详细阐述了基于 ARM 处理器的分散加载方法及其特殊应用,并以实际工程为例来说明怎样实现分散加载及使用分散加载的好处。它是笔者在实际工程应用中的心得体会,同时也是笔者工作经验的总结,希望本文对从事嵌入式系统设计和应用的工程技术人员能有所帮助

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 机械/制造/汽车 > 机械理论及资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号