嵌入式软件开发之: 复位和初始化_第1页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式软件开发之: 复位和初始化 13.5 复位和初始化 任何运行在实际硬件上的应用程序,都必需在启动时实现一些基本的系统初始化。本节将对此予以具体研究。13.5.1 初始化序列图13.14显示了一个适用于嵌入式系统的初始化序列。图13.14 arm嵌入式系统的初始化序列系统启动时立刻执行复位处理程序,然后进入$sub$main()的代码执行。复位处理程序是用汇编语言编写的代码块,它在系统复位时执行,完成系统初始化操作。对于具有局部存储器的内核,如caches、紧密藕荷存储器(tcm)、存储管理单元(mmu)和存储器庇护单元(mpu)等,在初始化过程这一阶段完成须要的配置。复位处理程序在执行之

2、后,通常跳转到_main以开头c库的初始化序列。13.5.2 向量表全部的arm系统都有一个向量表(vector table)。向量表不是初始化序列的一部分,但是对每个要处理的异样,它必需存在。这些地址通常包含以下形式的跳转命令。· b:该条命令实现了相对于pc的跳转· ldr pc,pc,offset:这条命令将异样处理程序的入口地址从存储器装载到pc。该地址是一个32位的肯定地址。因为有额外的存储器拜访,装载跳转地址会使分支跳转到特定处理程序,给系统执行带来延时。不过,可以用法这种办法跳转到存储空间内的随意地址。· mov pc,immediate:将一个立刻

3、数复制到pc。用法该命令可以跨越囫囵地址空间,但是受到地址对齐问题的限制。这个地址必需由8位立刻数循环右移偶数次得到。另外,也可以在向量表中用法其他类型的命令。例如,fiq处理程序可以从地址0x1c处开头执行。由于它位于向量表的最后,这样fiq处理程序就可以不用跳转,立刻从fiq向量地址处开头执行。下面的例子显示了一个用法ldr命令的向量表装载过程。;*;* vector table *;*area vectors, codeentry; 定义标准的arm向量表int_vectorsldr pc, int_reset_addrldr pc, int_undef_addrldr pc, int_

4、software_addrldr pc, int_prefetch_addrldr pc, int_data_addrldr pc, int_reserved_addrldr pc, int_irq_addrldr pc, int_fiq_addr在向量表的入口处要有entry标识。该标识通知链接程序该代码是一个可能的入口点,因而在链接时,不能被清除。13.5.3 rom/ram重映射启动时,0x0处必需要有一条有效命令,因此,复位时0x0000地址必需为非易失性存储器,如rom或flash。注重有些系统是从0xffff0000处开头执行的,对于这样的系统,地址0xffff0000处必需为非易

5、失性存储器。可以将rom定位在0x0处。但是,这样配置有几个缺点。首先rom存取速度通常较ram要慢,当跳转到异样处理程序时,系统性能可能会大受影响。第二,将向量表放于rom中,运行时不能修改。存储器地址重映射(memory remap)是当前无数先进控制器所具有的功能。所谓地址重映射就是可以通过软件配置来转变存储器物理地址的一种机制或办法。当一段程序对运行自己得存储器举行重映射时,需要特殊注重保证程序执行流程在重映射前后的承接关系。实现重映射的关键就是要使程序指针在remap以后能继续往下得到正确的命令。本书中介绍两种实现重映射的机制,不同的系统可能会有多种灵便的remap计划,用户在详细实

6、现时要详细分析。1.先搬移后映射(remap after copy)图13.15显示一种典型的存储器地址重映射状况。图13.15 rom/ram重映射(1)本来ram和rom各有自己的地址,举行重映射以后ram和rom的地址都发生了变幻。这种状况下,可以采纳以下计划。 上电后,从0x0地址的rom开头往下执行。 按照映射前的地址,对ram举行须要的代码和数据拷贝。 拷贝完后,举行remap操作。 由于ram在remap前预备好了内容,使得pc指针能继续在ram里取到正确的命令。2.先映射后搬移(copy after remap)系统上电后的缺省状态是0x0地址上放有rom。这块rom有两个地址

7、:从0起始和从0x10000起始,里面存储了初始化代码。当举行地址remap以后,从0x0起始的地址被定向到ram上,rom则只保留有惟一的从0x10000起始的地址。假如存储在rom里的复位异样处理程序(reset-handler)向来在0x00x4000的地址上运行,则当执行完remap以后,下面的命令将从ram里预取,这必定会导致程序执行流程的中断。按照系统特点,可以用下面的方法来解决这个问题。 上电后系统从0x0地址开头自动执行,设计跳转命令在remap发生前使pc指针指向0x10000开头的rom地址中去,由于不同地址指向的是同一块rom,全部程序能够顺当执行。 这时候0x00x40

8、00的地址空间空闲,不被程序引用,执行remap后把ram引进。由于程序向来在0x10000起始的rom空间里运行,remap对运行流程没有任何影响。 通过在rom里运行的程序,对ram举行相应的代码和数据拷贝,完成应用程序运行的初始化。图13.16显示了rom和ram重映射的其次种解决计划。图13.16 rom/ram重映射(2)该rom与ram地址重映射的办法可以应用于任何具有rom/ram重映射机制的平台,但是内存重映射的地址按照详细平台的不同而不同。图13.16显示的地址重映射例子中,第一条命令实现从rom暂时地址(0x0地址)到实际rom的跳转。然后,控制寄存器的重映射位,清除rom

9、的暂时地址设置。该代码通常在系统复位后立刻执行。重新映射必需在执行c库初始化代码前完成。在具有mmu的系统中,可通过在系统启动时配置mmu来实现重映射。下面的例子显示了在arm的integrator开发板上实现的rom/ram重映射过程。; - integrator cm control regcm_ctl_reg equ 0x1000000c ;定义cm控制寄存器地址remap_bit equ 0x04 ;cm控制寄存器重映射掩码entry;复位异样处理程序开头; 执行跳转命令,转到实际的rom执行ldr pc, =instruct_2instruct_2; 设置cm控制寄存器的重映射位ld

10、r r1, =cm_ctl_regldr r0, r1orr r0, r0, remap_bitstr r0, r1; 重映射后,ram在0x0地址; 将向量表从rom拷贝到 ram (由 _main函数完成)13.5.3 局部存储器设置有关的考虑事项许多arm处理器内核具有片上存储器系统,如mmu或mpu。这些设备通常是在系统启动过程中举行设置并启用的。因此,带有局部存储器系统的内核的初始化序列需要特殊地考虑。在前面所述的代码启动的过程中,_main中c库初始化代码负责建立代码执行时的内存映像,在跳转到_main前,必需建立处理器内核的运行时存储器视图。这就是说,在复位处理程序中必需设置并启

11、用mmu或mpu。另外,在跳转到_main前(通常在mmu/mpu设置前),必需启用紧耦合存储器tcm(tightly coupled memory),由于在通常状况下都是采纳簇拥加载办法将代码和数据装入tcm。当tcm启用后,用户不必存取由tcm屏蔽的存储器。在跳转到_main前,假如启用了cache,可能还会碰到cache全都性的问题,_main中的函数将程序代码从其加载域拷贝到执行域,在此过程中将命令作为数据举行处理。这样,一些命令可能被放入数据cache中,在执行这些命令时,因为找不到地址路径而产生错误。为了避开cache全都性的问题,在c库初始化序列执行完成后再启用cache。13.

12、5.4 栈指针初始化在程序的初始化代码中,用户必需要为处理器用到的各种模式设置堆栈,也就是说,复位处理程序必需为应用程序所用法的任何执行模式的栈指针分配初始值。下面的例子显示了如何在初始化代码中启用不同模式下的堆栈。; 启用系统模式堆栈ldr r2,int_system_stack ;将系统堆栈的全局变量放到r2中str sp,r2 ;将系统堆栈指针存储到系统模式下的sp; 启用系统堆栈限制 (为arm编译器的堆栈检测做预备)sub r1,sp,system_stack_size ;跳转堆栈指针bic r1,r1,0x03 ;4字节对齐mov r10,r1 ;将堆栈的限制放入r10寄存器(aa

13、pcs规章)ldr r2,int_system_limit ;得到堆栈限制全局变量地址str r1,r2 ;将堆栈限制存入全局变量; 切换到irq模式mrs r0,cpsr ;得到当前的cpsr值bic r0,r0,mode_mask ;清除模式位orr r1,r0,irq_mode ;设为irq模式msr cpsr_cxsf,r1 ;切换到irq模式;启用irq模式堆栈ldr sp,=int_irq_sp ;将irq模式堆栈指针放入sp_irq; 切换到fiqorr r1,r0,fiq_mode ;设置fiq模式位msr cpsr_cxsf,r1 ;切换到fiq模式; set-up fiq

14、stackldr sp,=int_fiq_sp ;得到fiq模式指针; 切换到abort模式orr r1,r0,abt_mode ;设置abort模式位msr cpsr_cxsf,r1 ;切换到abt模式; 启用abort堆栈ldr sp,=int_abort_sp; 切换到未定义异样模式orr r1,r0,undef_modemsr cpsr_cxsf,r1;启用未定义命令模式堆栈ldr sp,=int_undefined_sp; 启用系统/用户堆栈为了设置栈指针,进入每种模式(中断禁用)并为栈指针分配适合的值。要利用软件栈检查,也必需在此设置栈限制。复位处理程序中设置的栈指针和栈限制值由c

15、库初始化代码作为参数自动传递给_user_initial_stackheap()。因此,不允许_user_initial_stackheap()更改这些值。下面的例子显示了如何实现_user_initial_stackheap(),该段代码可以和上面的堆栈指针设置程序协作用法。import heap_baseexport _user_initial_stackheap()_user_initial_stackheap(); 程序中指定栈基地址或在描述文件中指定该地址ldr r0,=heap_base; r1 contains sb valuemov pc,lr13.5.5 硬件初始化普通状况下

16、,系统初始化代码和主应用程序是分开的。系统初始化要在主应用程序启动前完成。但部分与硬件相关的系统初始化过程,如启用cache和中断,必需在c库初始化代码执行完成后才干执行。为了在进入主应用程序之前,完成系统初始化,可以用法$sub和$super函数标识符在进入主程序之前插入一个例程。这一机制可以在不转变源代码的状况下扩展函数的功能。下面的例子解释了如何用法$sub和$super函数标识。链接程序通过调用$sub$main()函数取代对main()的调用。所以用户可以在自己编写的$sub$main()例程中启用cache或使能中断。extern void $super$main(void);void $sub$main(void)cache_enable(); / 使能cachesint_enable();

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论