ARM启动代码分析-philips的LPC2xxx系列

发布者:hylh2008最新更新时间:2016-07-20 来源: eefocus关键字:ARM  启动代码  LPC2xxx系列 手机看文章 扫描二维码
随时随地手机看文章
**********************************************************************************************
*File:                  startup.s
*Author:         Embest w.h.xie         2005.02.21
*Desc:         lpc22xx\lpc212x\lpc211x\lpc210x startup code
*History:   
* note modify: cui jian jie           2006-4-25
*comment:
**********************************************************************************************/
# 处理器的七种工作方式的常量定义
.EQU         Mode_USR,            0x10                   #用户模式
.EQU         Mode_FIQ,             0x11                   #FIQ模式
.EQU         Mode_IRQ,             0x12                   #IRQ模式
.EQU         Mode_SVC,            0x13                   #超级用户模式
.EQU         Mode_ABT,             0x17                   #终止模式
.EQU         Mode_UND,            0x1B                            #未定义模式
.EQU         Mode_SYS,             0x1F          #系统模式
 
# 中断屏蔽位
.EQU         I_Bit,              0x80                   //IRQ中断控制位,当被置位时,IRQ中断被禁止
.EQU         F_Bit,             0x40                   //FIQ中断控制位,当被置位时,FIQ中断被禁止
 
# 状态屏蔽位
.EQU         T_bit,             0x20          //T位,置位时在Thumb模式下运行,清零时在ARM下运行
 
# 定义程序入口点
.globl _start
                .code 32
 
                .TEXT 
                
_start:
 
# 中断向量表
 
Vectors:
                LDR     PC, Reset_Addr         //把Reset_Addr地址处的内容放入PC中
                             LDR     PC, Undef_Addr
                LDR     PC, SWI_Addr
                LDR     PC, PAbt_Addr
                LDR     PC, DAbt_Addr
                .long   0xb9205f80          @ keep interrupt vectors sum is 0
                LDR     PC, [PC, #-0xff0]               //当前PC值减去0xFF0等于IRQ中断入口地址
                LDR     PC, FIQ_Addr
#地址表
Reset_Addr:                                                             #该地址标号存放Reset_Handler程序段的入口地址
      .long     Reset_Handler
Undef_Addr:                                                             #该地址标号存放Undef_Handler程序段的入口地址
      .long     Undef_Handler
SWI_Addr:                                                                 #该地址标号存放SWI_Handler程序段的入口地址
      .long     SWI_Handler
PAbt_Addr:                                                                #该地址标号存放PAbt_Handler程序段的入口地址
      .long     PAbt_Handler
DAbt_Addr:
      .long     DAbt_Handler
      .long     0
IRQ_Addr:                                                                 #地址标号处存放一个无效的数据
      .long     0
FIQ_Addr:                                                                  #该地址标号存放FIQ_Handler程序段的入口地址
      .long     FIQ_Handler
 
 
Undef_Handler:
      B         Undef_Handler
PAbt_Handler:
      B         PAbt_Handler
DAbt_Handler:
B         DAbt_Handler
  
#软中断的中断服务子程序入口地址
SWI_Handler:                                                           
                STMFD   sp!, {r0-r3, r12, lr}          //入栈,现场数据保护
                MOV     r1, sp                                     //把堆栈指针SP存入R1中
                MRS     r0, spsr                    //把SPSR值存入R0,SPSR值为产生软中断时的CPSR
                TST     r0, #T_bit                          //判断R0(SPSR)的T位是否为0
                             #SPSR的T位不为0,工作在Thumb模式下
                LDRNEH  r0, [lr,#-2]                          //SPSR的T位不为0,则[lr-2]-〉r0
                BICNE   r0, r0, #0xFF00            // SPSR的T位不为0,清除r0的Bit8~Bit15位
                             # SPSR的T位为0,工作在ARM模式下
                LDREQ   r0, [lr,#-4]                          // SPSR的T位为0,则[lr-4] -〉r0
                BICEQ   r0, r0, #0xFF000000   // SPSR的T位为0,清除r0的Bit24~Bit131位
 
                # R0 is interrupt number             //R0是中断号
                # R1 is stack point                                      //R1是堆栈指针
 
                BL      SWI_Exception          //进入软中断处理程序
                LDMFD   sp!, {r0-r3, r12, pc}^          //出栈,现场数据恢复
 
 
# 快速响应中断的中断服务自程序的入口地址
FIQ_Handler:    
                STMFD     SP!, {R0-R3, LR}                         //入栈的现场保护
#                BL           FIQ_Exception                    //进入FIQ的中断处理程序
                LDMFD     SP!, {R0-R3, LR}                         //出栈,恢复现场
                SUBS       PC, LR, #4                                   //返回到主程序
 
# 复位后程序处理的入口地址
Reset_Handler:
                BL       RemapSRAM         //进行存储器映射的操作
#下面几行代码用来判断当前的工作模式
                MRS      R0, CPSR                          //读CPSR到寄存器R0
                AND      R0, R0, #0x1F                   //R0 = R0 AND 0x1F
                CMP      R0, #Mode_USR     //比较R0 和 #Mode_USR,二者相减
//如果相等则说明当前处在用户模式下,需要通过产生11号软中断进入系统模式。因为下面的初始化堆栈
//需要在不同的工作模式下切换,而在用户模式下不能直接切换,只有系统模式可以,所以要通过产生11
//号软中断切换到用户模式。
                SWIEQ    #11                                     
 
                BL       InitStack                      //进行堆栈初始化工作
                            
ARM启动代码分析-philips的LPC2xxx系列32006-7-24 14:33:00
#------------------------------------------------------------------------------
#- 初始化C变量
#------------------------
#- 下表由连接器自动产生
#- RO: 只读=代码区。
#- RW: 可读可写=预先初始化的数据(初始化的全局变量)和预先被清零的数据(未初始化的全局变量)。.
#- ZI: 预先被清零的数据区(未初始化的全局变量)
#- 预先被初始化的数据区定位在代码区之后。
#- 预先被清零的数据区定位在预先被初始化的数据区之后。
#- 注意数据区的位置 : 
#- I如果用 ARM SDT, 当链接器选择no -rw-base时, 数据区被映射在代码区之后
#- 你可以把数据区房子内部的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  
                .extern Main                                        /*声明外部变量*/
                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区中
                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]为首地址的单元中
#下面几行代码设置存储器映射控制寄存器
                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值,返回
 
#进入系统工作模式
 
ToSys:
               STMFD   SP!, {LR}                                       //把LR值压入堆栈
               swi     #11                                                             //产生11号软中断,11 –〉R0
               LDMFD   SP!, {pc}                                        //恢复PC值,返回
 
# 进入用户工作模式
 
ToUser:
               STMFD   SP!, {LR}                                       //把LR值压入堆栈
               swi     #12                                                             //产生12号软中断,11 –〉R0
               LDMFD   SP!, {pc}                                        //恢复PC值,返回
关键字:ARM  启动代码  LPC2xxx系列 引用地址:ARM启动代码分析-philips的LPC2xxx系列

上一篇:LPC2132 调试记
下一篇:s3c2410(ARM9)启动代码分析

推荐阅读最新更新时间:2024-03-16 15:01

布局物联网再出招 ARM厚植资安防护战力
行动/物联网应用安全更有保障。瞄准行动、物联网装置资料安全防护需求,安谋国际(ARM)近期针对Cortex-A核心发布授信执行环境(TEE)认证计画,协助行动处理器厂确保设计安全性,并购并Offspark,以强化其物联网开发平台mbed传输层安全协议(TLS)和Cryptobox等功能,期从晶片设计源头建立起滴水不漏的防护机制。 ARM安全行销暨系统与软体部门总监Rob Coombs表示,目前并无任何产业认证机制,用以评估行动及物联网装置的安全性,因此即便晶片商、系统厂老王卖瓜,但终端用户仍可能暴露在资料外泄或遭骇客窃取的风险中。为克服此一问题,ARM正致力发展从Cortex-A硬体核心、Trust Boot到Trust O
[物联网]
ARM-Linux驱动--ADC驱动(中断方式)
硬件平台:FL2440 内核版本:2.6.28 主机平台:Ubuntu 11.04 内核版本:2.6.39 原创作品,转载请标明出处: http://blog.csdn.net/yming0221/archive/2011/06/26/6568937.aspx 这个驱动写了好久,因为原来的Linux内核编译的时候将触摸屏驱动编译进内核了,而触摸屏驱动里的ADC中断在注册的时候类型选择的是 IRQF_SAMPLE_RANDOM,不是共享类型,所以,自己写的ADC驱动在每次open的时候,总提示ADC中断注册失败。 解决方案: 重新配置内核,选择触摸屏驱动以模块的形式编译,而不是直接编译进内核,这样Linux在
[单片机]
<font color='red'>ARM</font>-Linux驱动--ADC驱动(中断方式)
基于ARM7嵌入式系统的电梯群控系统的设计
目前,大多数电梯公司的群控系统都是采用RS485总线进行通信,但RS485采用主从式的通信方式,由主机发起呼叫,对应的终端应答,因此只能采取轮询的通信方式,实时性差,一旦主机出现故障,整个系统将瘫痪;而CAN总线在电梯群控系统中却体现出更多的优势:CAN总线通信与RS485通信相比抗干扰能力更好;可连接较多的通信节点;通信速率更高;实时性与稳定性高。 本文采用CAN总线来实现群控主机和各电梯之间的通信 。 1 系统总体结构 本系统以ARM7为内核,主频达72 MHz的32 bit微处理器LPC2368作为群控主控制器,它有高达512 KB的片内Flash程序存储器,具有在系统编程(ISP)和在应用编程(IAP)功能,同时
[单片机]
基于<font color='red'>ARM</font>7嵌入式系统的电梯群控系统的设计
STM32和ARM的区别
这个问题大概2009年的时候很多人就在问,请看09年的时候大家给出的若干比喻: http://www.amobbs.com/forum.php?mod=viewthread&tid=3784815&highlight 以后的ARM初学者也都在问。 笔者也是菜鸟,到网上搜了搜。下面先看一张图: 这张图是我在意大利与法国合资的意法半导体公司(ST,世界几大半导体公司之一)的官网上看到的。这说明,STM32是意法半导体公司的产品。 意法半导体(ST)后面为什么要加上M32呢? 这是由于该产品使用的是ARM公司的32-bit ARM Cortex MCUs,我想这就是STM32名字的由来(个人观点哈,反正也是菜鸟笔记)。 想起
[单片机]
STM32和<font color='red'>ARM</font>的区别
基于FPGA与ARM的遥测数据网络化采集
摘要:现有的遥测接收机为PCI接口,需安装在工控机上使用,为实现设备小型化、便携化,设计实现了小型网络接口遥测解调模块,可配合带有网口的计算机使用。采用FPGA进行遥测数据的帧同步与IRIG—B时码解调,将接收到的遥测数据添加时码后发送给ARM处理器中的Linux系统,并编写Linux 2.6下的FPGA驱动程序,实现FPGA数据的读取,然后通过网卡以TCP/IP格式发给主机,主机实现数据存储与显示。 关键词:FPGA;帧同步;ARM;遥测数据;网络化;Linux 以太网接口通信速度快,传输可靠,使用和配置方便,对于20 Mb/s以下的码速率,100 Mb/s的网卡可以进行不丢包转发,采用TCP包格式还可使设备小型化,便
[嵌入式]
基于FPGA与<font color='red'>ARM</font>的遥测数据网络化采集
Proteus仿真ARM7 LPC2101 AD转换器源程序
调试时首先观察待测电阻是否工作正常。在电阻的变化端插入电压探针,具体方式在 左边工具探针中选取电压探针(Voltage)运行仿真,点击电阻,观察探针电压是否在不断 变化。 调试流程 绘制 ADC 接口电路 1.在器件库中找到 ADC 转换芯片(ADC0801),如图连接 ADC0801 和总线信号。其中 ADC0801数据线连接数据总线最低字节(D0-D7),读写信号接总线读写信号(NRD,NWR)。其他信 号请按照下图进行连接。 2.片选信号 AD_CS 接译码电路输出(采用部分译码,对应地址为 0x03XXXXXX)。 3.连接模拟输入,在器件库找到可变电阻(POT-HG)。 完成 ADC0801 工作流程
[单片机]
Proteus仿真<font color='red'>ARM</font>7 LPC2101 AD转换器源程序
基于ARM及GPRS的远程入侵监控系统的设计
随着电子和通信技术的不断发展,单片机已经在数据压缩采集、电子设备、工业控制领域、以及多种家电设备等方面得到了广泛的应用,无线通信因其投资少、维护简单、方便、快捷和实时性强的优势,充分弥补了有线通信的缺陷,尤其是现在已经覆盖全国的GPRS网络已经得到了非常广泛的应用。 同时无线报警系统越来越受欢迎,无线监控报警系统不需要人员在场,将单片机技术、通信技术、网络技术和计算机技术结合起来,通过一定的网络设备建立起通信关系,具有高度的可靠性,集软硬件为一体,是对待监测范围内的待监设备完成自动准确采集、传输的系统。 可见设计出一种低价格适于家用的、工作性能稳定可靠的智能型入侵监控报警系统是必要的。通过此系统对家里出现的入室盗窃
[安防电子]
基于<font color='red'>ARM</font>及GPRS的远程入侵监控系统的设计
快数学Arm(17)--uC/OS-II任务管理块TCB
原指望Arm7能得到快速学习,但看了之后发现与C51的难度不是相同数量级的.如果真的想学好,还是需要研究很多东西的.我绕了个圈子,接着转向学习uC/OS-II,学一样东西无法按照书上的套路按部就班的学,那样实在太慢了.看了一项uC/OS-II的教材,发现要学好它是需要花费一些时间的,对于时间比较短缺的我来说是不是有足够的时间把它学下去,我也不知道,但只要我不被其他的更重要的事情打断,我想我是能够坚持下去的,我相信我的毅力. 在前面我们知道了uC/OS-II(后面写成ucos2,敲起来方便些)是可以实现多任务的,看了书以后发现这种多任务虽然功能要比C51强了很多,但真的需要投入很多精力才能逐渐弄清楚,而且C语言差的人,没有汇编经
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved