alphavor_jay的个人空间 https://blog.eetop.cn/840234 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

ARM启动过程(Cortex-M3 NXP LPC1768为例)

已有 26864 次阅读| 2012-7-23 19:13 |个人分类:ARM(Cortex-M3)

1. 基本概念(CMSIS): Cortex Micro-controller Software Interface Standard,微控制器软件接口标准。

2. CMSIS标准的文件结构:
a) core_cm<x>.c (stdint.h)
b) system_<device>.c (core_cm<h>, system_<device.h>)
c) startup_<device>.s

其中core_cm<x>.c以及core_cm<h>中为内核设访问层,其中定义了定义了内核中得外设几丁质以及一些内核的访问及控制函数。

startup_<device>.s文件是系统的启动文件,其包括堆和栈的初始化配置、中断向量表的配置以及将程序引导到main()函数等功能。

system_<device.h>和system_<device>.c文件则是由ARM公司提供模版,各芯片制造商根据自己芯片的特点来编写的。

3. 注解startup_<device>.s文件
此文件主要完成三项工作:堆栈以及堆的初始化、定位中断向量表、调用Reset Handler
a) 堆栈以及堆的初始化
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size         EQU     0x00000200

                      AREA     STACK, NOINIT, READWRITE, ALIGN=3  
//指明8字节对齐(ALIGN=3)

Stack_Mem SPACE   Stack_Size
__initial_sp       //此标号有一层隐含的意思那就是在M3中堆栈是满递减堆                                     //栈,因为它指定了堆栈指针位于堆栈的高地址(在 //Stack_Mem之后)


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000000

                AREA     HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem       SPACE Heap_Size
__heap_limit

以上堆和栈的具体地址可以在工程编译后产生的*.map文件中看到。

b) 定位中断向量表
PRESERVE8   
//PRESERVE8指定了以下的代码位8字节对齐

THUMB
//THUMB指定了接下来的代码为THUMB指令集

; Vector Table Mapped to Address 0 at Reset

                AREA    RESET, DATA, READONLY
//此语句声明RESET数据段

                EXPORT  __Vectors
//导出向量表标号,EXPORT作用类似于C语言中的extern

__Vectors       
                DCD     __initial_sp                       ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler

                ; External Interrupts
                DCD     WDT_IRQHandler             ; 16: Watchdog Timer
                DCD     TIMER0_IRQHandler         ; 17: Timer0
                DCD     TIMER1_IRQHandler         ; 18: Timer1
                DCD     TIMER2_IRQHandler         ; 19: Timer2
                DCD     TIMER3_IRQHandler         ; 20: Timer3
                DCD     UART0_IRQHandler           ; 21: UART0
 (……省略)


c) 调用Reset Handler
; Reset Handler

Reset_Handler   
PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP

注释:引导程序进入__main(此__main是C_Library中的函数,非main())

d) 其他的代码
这段代码是NXP公司的LPC1700系列的MCU特有的一段代码,其他公司的Cortex-M3 MCU的启动程序是没有这段代码的。

这段代码是指定LPC1700的CRP加密级别的代码段,芯片上电后会自动读取这一地址的值以确定加密方式,其中CRP_Key = 0xffffffff为不加密(0级加密),CRP_Key = 0x12345678为1级加密,CRP_Key = 0x87654321为2级加密,CRP_Key = 0x43218765为3级加密(最高级加密),3级加密将会禁止所有的ISP指令,也就是说,芯片将不能读写、不能擦除。
                IF     :LNOT::DEF:NO_CRP
                AREA     |.ARM.__at_0x02FC|, CODE, READONLY
CRP_Key         
DCD     0xFFFFFFFF
                ENDIF


                AREA     |.text|, CODE, READONLY

e) 堆栈以及堆的初始化行为
; User Initial Stack & Heap

                IF       :DEF:__MICROLIB
                
                EXPORT  __initial_sp
                EXPORT  __heap_base
                EXPORT  __heap_limit
                
                ELSE
                
                IMPORT  __use_two_region_memory
                EXPORT  __user_initial_stackheap
__user_initial_stackheap

                LDR     R0, =  Heap_Mem
                LDR     R1, = (Stack_Mem + Stack_Size)
                LDR     R2, = (Heap_Mem +  Heap_Size)
                LDR     R3, = Stack_Mem
                BX       LR

4. ARM启动工程详解

点赞

发表评论 评论 (3 个评论)

回复 ZIDANESAHA005 2013-7-15 17:05
正在学习启动代码,很有用,好像还没写完,期待中:lol

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 8

    粉丝
  • 0

    好友
  • 22

    获赞
  • 51

    评论
  • 2656

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-27 21:08 , Processed in 0.016906 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部