微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > IAR下的汇编/单片机启动代码汇编

IAR下的汇编/单片机启动代码汇编

时间:11-25 来源:互联网 点击:

ENTER FIQ MODE MOV sp,R2 SUB R2,R2,#FiqStkSz ORR R1,R0,#(MODIRQ :OR: IRQBIT :OR: FIQBIT) MSR CPSR_cxsf,R1 ; ENTER IRQ MODE MOV sp,R2 SUB R2,R2,#IrqStkSz ORR R1,R0,#(MODUDF :OR: IRQBIT :OR: FIQBIT) MSR CPSR_cxsf,R1 ; ENTER UDF MODE MOV sp,R2 SUB R2,R2,#UdfStkSz ORR R1,R0,#(MODABT :OR: IRQBIT :OR: FIQBIT) MSR CPSR_cxsf,R1 ; ENTER ABT MODE MOV sp,R2 SUB R2,R2,#AbtStkSz ;ORR R1,R0,#(MODUSR :OR: IRQBIT :OR: FIQBIT) ;MSR CPSR_cxsf,R1 ; ENTER USR MODE ;MOV sp,R2 ;SUB R2,R2,#UsrStkSz ORR R1,R0,#(MODSYS :OR: IRQBIT :OR: FIQBIT) MSR CPSR_cxsf,R1 ; ENTER SYS MODE MOV sp,R2 ; 三,初始化变量 编译完成之后,连接器会生成三个基本的段,分别是RO,RW,ZI,并会在image中顺序摆放.显然,RW,ZI在运行开始时并不位于指定的RW位置,因此必须初始化 LDR R0,=|Image$$RO$$Limit| LDR R1,=|Image$$RW$$Base| LDR R2,=|Image$$ZI$$Base| 1 CMP R1,R2 LDRLO R3,[R0],#4 STRLO R3,[R1],#4 BLO ? MOV R3,#0 LDR R1,=|Image$$ZI$$Limit| 2 CMP R2,R1 STRLO R3,[R2],#4 BLO ? 四,复制异常向量 由于代码于RAM运行时,有明显的速度优势,而且变量可以动态配置,因此可以通过remap将RAM映射到0,使得出现异常时ARM从RAM中取得向量. IMPORT |Image$$RO$$Base| IMPORT |Image$$RO$$Limit| IMPORT |Image$$RW$$Base| IMPORT |Image$$RW$$Limit| IMPORT |Image$$ZI$$Base| IMPORT |Image$$ZI$$Limit| COPY_VECT_TO_RAM LDR R0,=|Image$$RO$$Base| LDR R1,=SYSINIT LDR R2,=0x200000 ; RAM START 0 CMP R0,R1 LDRLO R3,[R0],#4 STRLO R3,[R2],#4 BLO ? 这段程序将SYSINIT之前的代码,也就是异常处理函数,全部复制到RAM中, 这就意味着不能将RW设置为0x200000,这样会使得向量被冲掉. 四,在RAM中运行 如果有必要,且代码足够小,可以将代码置于RAM中运行,由于RAM中本身没有代码,就需要将代码复制到RAM中: COPY_BEGIN LDR R0,=0x200000 LDR R1,=RESET ; =|Image$$RO$$Base| CMP R1,R0 ; BLO COPY_END ; ADR R0,RESET ADR R2,COPY_END SUB R0,R2,R0 ADD R1,R1,R0 LDR R3,=|Image$$RO$$Limit| 3 CMP R1,R3 LDRLO R4,[R2],#4 STRLO R4,[R1],#4 BLO ? LDR PC,=COPY_END COPY_END 程序首先取得RESET的连接地址,判断程序是否时是在RAM中运行,方法是与RAM起始地址比较,如果小于,那么就跳过代码复制. 在复制代码的时候需要注意,在这段程序结束之前的代码没有必要复制,因为这些代码都已经执行过了,所以,先取得COPY_END,作为复制起始地址,然后计算其相对RESET的偏移,然后以RO的值加上这个偏移,就是复制目的地的起始地址,然后开始复制. 五,开始主程序 以上步骤完成,就可以跳转到main运行 IMPORT Main LDR PC,=Main B . 六,器件初始化 主程序首先要进行器件的初始化,对S64而言,应该先初始化WDT,因为默认情况下,WDT是打开的,然后是各设备的时钟分配,最后应该remap

--------------------------------------------------------------------------------

RemapSRAM:

MOV R0, #0x40000000 //RAM 区首地址

LDR R1, =Vectors //向量表首地址

#下面一段程序是把从0x00000000 开始的64 个字节(FLASH 中的中断向量表和地址表)搬移到以

#0x40000000 为首地址的RAM 区中

LDMIA R1!, {R2-R9} //把以[R1]为首地址的32 个字节数据装载到R2-R9 中

STMIA R0!, {R2-R9} //把R2-R9 中的数据存入以[R0]为首地址的单元中

LDMIA R1!, {R2-R9} //把以[R1]为首地址的32 个字节数据装载到R2-R9 中

STMIA R0!, {R2-R9} ////把R2-R9 中的数据存入以[R0]为首地址的单元中

--------------------------------------------------------------------------------

ARM的启动代码分析

相信使用过MDK的朋友都会发现,在新建任意一个ARM芯片的工程时,MDK开发环境都会自动的在代码中加入一个Startup.s的文件。

大家不能小看这个代码的功能了,这个代码中就是对应芯片的启动代码了。

本文就以在MDK开发环境下对于LPC2103的启动代码分析了。

在MDK开发环境下,系统复位后,都是会将ARM芯片切换到系统模式下工作。启动代码会在系统复位后立即执行,其功能如下:

1、定义中断和异常向量。

2、配置CPU时钟源(对于一些设备来说)。

3、使用内存重映射命令拷贝ROM中的异常向量到RAM中(例如:Atmel)。

4、初始化外部总线控制器和执行内存重映射(如果有必要)。

5、如果有必要,初始化其它外设。

6、为所有的模式预留和初始化堆栈。

7、清零数据初始

上一篇:MSP430汇编指令
下一篇:写MSP430片内flash

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top