LPC2xxx启动代码分析
被映射在代码区之后
#-你可以把数据区房子内部的SRAM( -rw-base=0x40 or 0x34)中
#-或者放在外部的SRAM( -rw-base=0x2000000 )中。
#-注意:为了提高代码的密度,预先被初始化的数据必须尽可能的少。
#------------------------------------------------------------------------------
#该部分程序功能:先判断当前是在RAM中运行还是在FLASH中运行,如果在FLASH中运行,先把FLASH
#中的预先赋值的RW段数据和未赋值的ZI段数据都搬移到RAM区中,再把ZI段数据全部清零;如果程#序就是在RAM中运行,则直接把ZI段数据清零。
.extern Image_RO_Limit /* ROM区中数据段的起始地址*/
.extern Image_RW_Base /* RW段起始地址*/
.extern Image_ZI_Base /* ZI段的起始地址*/
.extern Image_ZI_Limit /* ZI段的结束地址加1 */
ldr r0, =Image_RO_Limit /*取ROM区中数据段的首地址*/
ldr r1, =Image_RW_Base/*取RAM区中RW段的目标首地址*/
ldr r3, =Image_ZI_Base/*取RAM区中ZI段的首地址*/
cmp r0, r1/*比较ROM区中数据段首地址和RAM区中RW段目标首地址*/
beq NoRW /*相等代表当前是在RAM中运行*/
LoopRw: cmp r1, r3 /*不相等则和RAM区中ZI段的目标地址比较*/
ldrcc r2, [r0], #4/*如果r1 strcc r2, [r1], #4/*如果r1 bcc LoopRw/*如果r1 NoRW: ldr r1, =Image_ZI_Limit /*取ZI段的结束地址*/ mov r2, #0 /*将r2赋0*/ LoopZI: cmp r3, r1/*将ZI段清零*/ strcc r2, [r3], #4/*如果r3 bcc LoopZI /*如果r3 .externMain /*声明外部变量*/ B Main /*t跳转到用户的主程序入口*/ #为每一种模式建立堆栈,ARM堆栈指针向下生长 InitStack: MOV R1, LR //把该子程序返回地址保留在R1中 LDR R0, =Top_Stack//取栈定地址到R0中 #进入未定义模式,并禁止FIQ中断和IRQ中断 MSR CPSR_c, #Mode_UND|I_Bit|F_Bit #设置未定义模式下堆栈的栈顶指针 MOV SP, R0 SUB R0, R0, #UND_Stack_Size#未定义模式下堆栈深度 #进入终止模式,并禁止禁止FIQ中断和IRQ中断 MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit #紧接着未定义模式下的堆栈,设置终止模式下栈顶指针 MOV SP, R0 SUB R0, R0, #ABT_Stack_Size#终止模式下堆栈深度 #进入FIQ模式,并禁止FIQ中断和IRQ中断 MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit #紧接着终止模式下的堆栈,设置下FIQ模式下栈顶指针 MOV SP, R0 SUB R0, R0, #FIQ_Stack_Size#FIQ模式下的堆栈深度 #进入IRQ模式,并禁止FIQ中断和IRQ中断 MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit #紧接着FIQ模式下的堆栈,设置IRQ模式下的栈顶指针 MOV SP, R0 SUB R0, R0, #IRQ_Stack_Size#IRQ模式下的堆栈深度 #进入超级用户模式,并禁止FIQ中断和IRQ中断 MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit #紧接着IRQ模式下的堆栈,设置超级用户下的栈顶指针 MOV SP, R0 SUB R0, R0, #SVC_Stack_Size#超级用户下的堆栈深度 #设置进入用户模式 MSR CPSR_c, #Mode_USR #紧接着超级用户模式下的堆栈,设置用户模式下的栈顶指针,剩余的空间都开辟为堆栈 MOV SP, R0 MOV PC, R1 #堆栈初始化子程序返回 #重映射SRAM区 RemapSRAM: MOV R0, #0x40000000 //RAM区首地址 LDR R1, =Vectors //向量表首地址 #下面一段程序是把从0x00000000开始的64个字节(FLASH中的中断向量表和地址表)搬移到以 #0x40000000为首地址的RAM区中 LDMIAR1!, {R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中 STMIAR0!, {R2-R9}//把R2-R9中的数据存入以[R0]为首地址的单元中 LDMIAR1!, {R2-R9}//把以[R1]为首地址的32个字节数据装载到R2-R9中 STMIAR0!, {R2-R9}////把R2-R9中的数据存入以[R0]为首地址的单元中 #下面几行代码设置存储器映射控制寄存器 LDR R0, =MEMMAP//取MEMMAP地址到R0 MOV R1, #0x02 STR R1, [R0]//给MEMMAP赋值为0x02,设置中断向量从RAM区从新映射 mov pc,lr //跳转到主程序 #下面一段程序代码是进入软中断来切换系统的工作模式,当希望从一种模式切换入另一种模式时,可以通 #过调用下面对应标号的程序段进入软中断。在软中断处理程序中会根据所给定的中断号处理,执行SWI #num后软中断号被存入R0中。 .globl disable_IRQ .globl restore_IRQ .globl ToSys .globl ToUser #禁止IRQ disable_IRQ: STMFD SP!, {LR} //把LR值压入堆栈 swi #0 //产生0号软中断,0 -〉R0 LDMFD SP!, {pc} //恢复PC值,返回 #恢复IRQ restore_IRQ: STMFD SP!, {LR} //把LR值压入堆栈 swi #1 //产生1号软中断,1 –〉R0 LDMFD SP!, {pc} //恢复PC值,返回 #进入系统
LPC2xxx启动代 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)