ARM启动代码详解._第1页
ARM启动代码详解._第2页
免费预览已结束,剩余19页可下载查看

下载本文档

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

文档简介

1、PART1系统初始化流程如下:禁止看门狗-在中断控制器中屏蔽所有中断-系统 时钟设置-初始化端口 -DMA 设置-cashe 和总线设置-存储器设置, 初始化SDRAM-初始化堆栈-设置 IRQ 和 FIQ 的入口 -地址重映射。 必须由汇编来完成的任务有:异常中断向量表的设置、IRQ 向量表(向量模式或 ISR 初始化(非向量模式、二级 ISR 地址表的定义、Flash 和 SDRAM 的设置(否则系统 无法加载代码、堆栈设置和模式切换、拷贝RW 和 ZI 代码、设置系统时钟等。对于非向量模式,不使用 IRQ 中断向量表,但二级 ISR 地址表的设置是相同的。PART2理解启动代码(ADS所

2、谓启动代码,就是处理器在启动的时候执行的一段代码,主要任务是初始化处 理器模式,设置堆栈,初始化变量等等由于以上的操作均与处理器体系结构和系统配 置密切相关,所以一般由汇编来编写具体到 S64,启动代码分成两部分,一是与 ARM7TDMI 内核相关的部分,包括处 理器各异常向量的配置,各处理器模式的堆栈设置,如有必要,复制向量到 RAM,以便 remap之后处理器正确处理异常,初始化数据(包括 RW 与 ZI,最后跳转到 Main.二是 与处理器外部设备相关的部分,这和厂商的联系比较大.虽然都采用了 ARM7TDMI 的内核,但是不同的厂家 整合了不同的片上外设,需要不同的初始化,其中比较重要

3、的是初始化 WDT,初始化 各子系统时钟,有必要的话,进行 remap 这一部分与一般控制器的初始化类似,因此,本 文不作重点描述.在进行分析之前,请确认如下相关概念:S64 片上 FLASH 起始于 0 x100000,共 64kB,片上 RAM 起始于 0 x200000,共 16kB.S64 复位之后,程序会从 0 开始执行,此时 FLASH 被映射到 0 地址,因此,S64 可 以取得指令并执行显然,此时还是驻留在 0 x100000 地址.如果使用 remap 命令,将会 把RAM 映射到 0 地址,同样的这时 0 地址的内容也只是 RAM 的镜像.S64 的 FLASH 可以保证在

4、最差情况时以 30MHz 进行单周期访问,而 RAM 可以 保证在最大速度时的单周期访问.OK,以下开始分析启动代码.一,处理器异常S64 将异常向量至于 0 地址开始的几个直接,这些是必需要处理的.由于复位向 量位于 0,也需要一条跳转指令.具体代码如下:RESETB SYSINIT ; ResetB UDFHANDLER ; UNDEFINEDB SWIHANDLER ; SWIB PABTHANDLER ; PREFETCH ABORTB DABTHANDLER ; DATA ABORTB.;RESERVEDB VECTORED_IRQ_HANDLERB . ; ADD FIQ CODE

5、 HERE UDFHANDLERB . SWIHANDLERB.PABTHANDLERB . DABTHANDLERB .请注意,B 指令经汇编后会替换为当前 PC 值加上一个修正值(+/-,所以这条指令 是代码位置无关的,也就是不管这条指令是在 0 地址还是在 0 x100000 执行,都能跳转 到指定的位置,而 LDR PC,二??将向 PC 直接装载一个标号的值,请注意,标号在编译 过后将被替换为一个与 RO 相对应的值,也就是说,这样的指令无论在哪里执行,都只 会跳转到一个指定的位置.下面举一个具体的例子来说明两者的区别:假定有如下程 序:RESETB INIT 或者 LDR PC,=

6、INITINIT其中 RESET为起始时的代码,也就是这条代码的偏移为 0,设 INIT 的偏移量为 offset.如果将这段程序按照 R0=0 x1000000 编译,那么 B INIT 可理解为 ADD PC, PC, #offset,而 LDR PC,=INIT 可被理解为 MOV PC,#(RO+offset .显然当系统复位时,程序 从 0 开始运行,而 0 地址有 FLASH 的副本,执行 B INIT 将把 PC 指向位于 0 地址处 的镜像代码位置,也即 INIT;如果执行 LDR PC,=INIT 将会将 PC 直接指向位于 FLASH 中的原始代码.因此以上两者都能正确运行

7、.下面将 RO 设置为 0 x200000,编 译后生成代码,还是得烧写到 FLASH 中,也就是还是 0 x100000,系统复位后从 0 地址 执行还是 FLASH 的副本,此时执行 B INIT,将跳到副本中的 INIT 位置执行,此处有 对应的代码;但是如果执行 LDRPC,=INIT,将向 PC 加载 0 x200000+offset 这将使得 PC 跳到 RAM 中,而此时由于代码没有复制,RAM 中的指定位置并没有代码,程序无 法运行.,处理器模式ARM 的处理器可工作于多种模式,不同模式有不同的堆栈,以下设置各模式及其 堆栈预定义一些参数:MODUSR EQU 0 x10MOD

8、SYS EQU 0 x1FMODSVC EQU 0 x13MODABT EQU 0 x17MODUDF EQU 0 x1BMODIRQ EQU 0 x12MODFIQ EQU 0 x11IRQBIT EQU 0 x80FIQBIT EQU 0 x40RAMEND EQU 0 x00204000 ; S64 : 16KB RAMVECTSIZE EQU 0 x100 ;UsrStkSz EQU 8 ; size of USR stack SysStkSz EQU 128 ; size of SYS stackSvcStkSz EQU 8 ; size of SVC stack UdfStkSz

9、EQU 8 ; size of UDF stack AbtStkSzEQU 8 ; size of ABT stack IrqStkSz EQU 128 ; size of IRQ stack FiqStkSz EQU 16 ; sizeof FIQ stack修改这些值即可修改相应模式堆栈的尺寸以下为各模式代码:SYSINITJMRS RO,CPSRBIC R0,R0,#0 x1FMOV R2,#RAMENDORR R1,R0,#(MODSVC :OR: IRQBIT :OR: FIQBITMSR cpsr_cxsf,R1 ; ENTER SVC MODEMOV sp,R2SUB R2,R2

10、,#SvcStkSzORR R1,R0,#(MODFIQ :OR: IRQBIT :OR: FIQBITMSR CPSR_cxsf,R1 ; ENTER FIQ MODEMOV sp,R2SUB R2,R2,#FiqStkSzORR R1,R0,#(MODIRQ :OR: IRQBIT :OR: FIQBITMSR CPSR_cxsf,R1 ; ENTER IRQ MODEMOV sp,R2SUB R2,R2,#lrqStkSzORR R1,R0,#(MODUDF :OR: IRQBIT :OR: FIQBITLDR R0,=|lmage$RO$Limit|MSR CPSR_cxsf,R1 ;

11、 ENTER UDF MODEMOV sp,R2SUB R2,R2,#UdfStkSzORR R1,RO,#(MODABT :OR: IRQBIT :OR: FIQBITMSR CPSR_cxsf,R1 ; ENTER ABT MODEMOV sp,R2SUB R2,R2,#AbtStkSz;ORR R1,R0,#(MODUSR :OR: IRQBIT :OR: FIQBIT;MSR CPSR_cxsf,R1 ; ENTER USR MODE;MOV sp,R2;SUB R2,R2,#UsrStkSzORR R1,R0,#(MODSYS :OR: IRQBIT :OR: FIQBITMSR C

12、PSR_cxsf,R1 ; ENTER SYS MODEMOV sp,R2 ;三,初始化变量编译完成之后,连接器会生成三个基本的段,分别是 RO,RW,ZI,并会在 image 中 顺序摆放.显然,RW,ZI 在运行开始时并不位于指定的RW 位置,因此必须初始化IMPORT |Image$RW$Base|LDR R1,=|lmage$RW$Base|LDR R2,=|lmage$ZI$Base|1CMP R1,R2LDRLO R3,R0,#4STRLO R3,R1,#4BLO %B1MOV R3,#0LDR R1,=|lmage$ZI$Limit|2CMP R2,R1STRLO R3,R2,#

13、4BLO %B2四,复制异常向量由于代码于 RAM 运行时,有明显的速度优势,而且变量可以动态配置,因此可以通过 remap 将 RAM 映射到 0,使得出现异常时 ARM 从 RAM 中取得向量.IMPORT |lmage$RO$Base|IMPORT |lmage$RO$Limit|LDR R1,=RESET ; =|Image$RO$Base|IMPORT |lmage$RW$Limit|IMPORT |lmage$ZI$Base|IMPORT |Image$ZI$Limit|COPY_VECT_TO_RAMLDR RO,=|lmage$RO$Base|LDR R1,=SYSINITLD

14、R R2,=0 x200000 ; RAM STARTCMP R0,R1LDRLO R3,R0,#4STRLO R3,R2,#4BLO %B0这段程序将 SYSINIT 之前的代码,也就是异常处理函数,全部复制到 RAM 中, 这就意味着不能将 RW 设置为 0 x200000,这样会使得向量被冲掉.四,在 RAM 中运行如果有必要,且代码足够小,可以将代码置于 RAM 中运行,由于 RAM 中本身没有代码,就需要将代码复制到 RAM 中:COPY_BEGINLDR R0,=0 x200000CMP R1,R0 ;BLO COPY_END ;ADR R0,RESETADR R2,COPY_EN

15、DSUB R0,R2,R0ADD R1,R1,R0LDR R3,=|lmage$RO$Limit|3CMP R1,R3LDRLO R4,R2,#4STRLO R4,R1,#4BLO %B3LDR PC,=COPY_ENDCOPY_END程序首先取得 RESET 的连接地址,判断程序是否时是在 RAM 中运行,方法是与RAM 起始地址比较,如果小于,那么就跳过代码复制.在复制代码的时候需要注意,在这段程序结束之前的代码没有必要复制,因为这 些代码都已经执行过了,所以,先取得 COPY_END,作为复制起始地址,然后计算其相 对RESET 的偏移然后以 RO 的值加上这个偏移,就是复制目的地的起始

16、地址,然后 开始复制五,开始主程序以上步骤完成,就可以跳转到 main 运行IMPORT Mai nLDR PC,=Ma inB .六,器件初始化主程序首先要进行器件的初始化,对 S64 而言,应该先初始化 WDT,因为默认情 况下,WDT 是打开的,然后是各设备的时钟分配,最后应该 remap.以上是必要的启动步骤,实际应用中可以根据具体情况添加一些代码PART3ARM 启动程序分析字体:小中大|打印发布:2007-7-17 11:05 作者:网络转载来源:网络查看:4 次ARM 启动程序分析TIMER1 用来触发和 IRQ 中断代码在 FLASH 中运行这个例子有一下几个文件:1. 中断向

17、量表(ivt.s2. 汇编启动代码(init.s3. C 主函数文件中断向量表;代码必须链接在地址 0X0。这里提供了 ARM 内核的中断向量;汇编指令-;- AREAIVTCODE ;新代码段CODE32 ; ARM 指令IMPORT start ;在这段中没有定义En try ;定义程序进入点;- LDRPC-=startLDR PC, Un defi ned_AddrLDR PC,_AddrLDR PC, Prefetch_AddrLDR PC, Abort_Addr;在地址 0 x14 用户应该插入一个标记(校验和.;此标记让引导程序决定是否在 Flash 中有有效的用户代码,目前大多

18、数 FLASH 编程工具(debuggers and ISP utility;有这个内置的功能,因此用户不用考虑这个问题.假如开发工具没有提供这种 功能,那么这个值必须自己计算,并把计算得到的值写到地址 0 x14.计算校验和的细 节可以参考 LPC2104/5/6 用户指南的 FLASH 编程章节.DCD .LDR PC, PC, #-)xFFOLDR PC, FIQ_AddrUn defi ned_Addr DCD Undefin ed_Ha ndlerPrefetch_Addr DCD Prefetch_HandlerAbort_Addr DCD Abort_Ha ndlerFIQ_Ad

19、dr DCD FIQ_Ha ndler;-;异常处理JUn defi ned_Ha ndlerB Un defi ned_Ha ndlerB_Ha ndlerPrefetch_Ha ndlerB Prefetch_Ha ndlerAbort_Ha ndlerB Abort_Ha ndlerFIQ_Ha ndlerB FIQ_Ha ndlerEND系统复位后,第一条要执行的指令是:LDR PC,=start这条指令将跳转到汇编的起始代码(startup 他将中断使能,为 IRQ 和管理模式设置堆栈;比较重要的中断向量是 IRQ 中断.LDR PC, PC, #-)xFFO;这条指令将从中断向量控

20、制控制器(VIC 中的地址寄存器(OxFFFF F030 导入PC,并执行.;所有剩余的向量都有中断句柄启动程序汇编代码;-匚编语;- ARE-asm_code, CODE ;新代码段CODE32 ; ARM 指令IMPORT _main ; main 在这个程序段中没有定义EXPORT start ;全局变量;参考 ivt.s 文件start;中断使能MSR cpsr_c,#0 x13 ;在管理模式时设定堆栈指针 SPLDR SP,=0 x4 设置 IRQ 模式.设置 SP_irq 然后返回管理模式MRS R0, CPSRBIC R1, R0,#0 x1FORR R1, R1,#0 x12M

21、SR cpsr_c, R1 进入中断模式LDR SP, =0 x4MSR cpsr_c, R0 返回管理模式;跳转到 c 程序LDR lr, =_mai nMOV pc, lrEND这段代码在与 ivt.s 链接.假如设置堆栈指针失败将导致数据中止异常,因此堆栈 的初始化应该在跳转到 c mai n(函数之前。C 代码Timer1 的寄存器这么配置,当匹配的时候将中断内核,并且复位。 Timer1 运行在 60MHz.这段代码在一个评估板上运行,其外部始终使用 10 MHz 晶体,并且内部 PLL 设定好。时钟操作的具体细节请参考 LPC2106/5/4 中的相关章节。中断服务程 序为空,用户

22、可以根据需要添加。在 IRQHandler(函数中可以点亮一些 LED s 或触发一些引脚.rq 关键字编译器用来定义 IRQHandler (函数作为 IRQ 中断服务程序C main 函数在 init.s 文件后执行。LDR Ir, =_mai nMOV pc, IrC 代码如下:*IRQHa ndler(void;void feed(void;void In itialize(void;*#in clude“LPC210 x.h ”函数定义*/ _irq void头文件MAIN/*系统初始化*/In itialize(;/*启动时钟*/T1_TCR=0 x1;while(1/*In itialize(/*初始化 PLL 10MHzX6=60MHz*/*设置乘除数值*/PLLCFG=0 x25;feed(;/* 使能 PLL */PLLCON=0 x1;feed(;/*等待 PLL 锁定设定的频率*/while(!(PLLSTAT & PLOCK初始化*/ void/*连接 PLL 作为时钟源*/PLLCON=Ox3;feed(;/*使能存储器加速模块 MAM,设定访问 FLASH 的时钟*/M

温馨提示

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

评论

0/150

提交评论