IAR下的汇编/单片机启动代码汇编
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、清零数据初始
IAR汇编单片机启动代 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)