zoukankan      html  css  js  c++  java
  • 19.1 详解startup_M051.s

    Keil新建的所有工程中,毫无例外地都包含startup_M051.s,如图19.1-1。

     

    图19.1-1 startup_M051.s

     

    该文件主要作用于上电时初始化单片机的硬件堆栈、初始化RAM分配内存空间和跳转到主函数即main函数。硬件堆栈是用来存放函数调用地址、变量和寄存器值的;分配内存空间为异常提供更加快速的访问,减少中断延迟。如果不加载该startup_M051.s文件,编译的代码可能会使单片机不能正常工作。

    那么什么是堆栈呢?在计算机领域,堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈这两种数据结构。堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。

    堆,一般是在堆的头部用一个字节存放堆的大小,堆中的具体内容由程序员安排。

    栈,在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,接着是函数中的局部变量,注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址(后进先出),也就是主函数中的下一条指令,程序由该点继续运行。

    虽然堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。

    startup_M051.s文件并不复杂,只要用户有基本的汇编基础,就可以看懂,以下就给出该上电初始化文件的详细注解,可以作为参考,只作为选学内容。

     

    程序清单19.1-1 startup_M051.s核心内容详解

     

    Stack_Size      EQU     0x00000400        ;//栈大小定义为0x00000400字节

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;声明数据段STACK

    ;该数据段内存单元无初始化,可读写,并重新字对齐

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    AREA    STACK, NOINIT, READWRITE, ALIGN=3

    Stack_Mem       SPACE   Stack_Size       ;//为栈分配内存空间,并初始化为0

    __initial_sp

     

     

    Heap_Size       EQU     0x00000000  ;//堆大小定义为0x00000000字节

     

                    AREA    HEAP, NOINIT, READWRITE, ALIGN=3

    __heap_base

    Heap_Mem        SPACE   Heap_Size        ;//为堆分配内存空间,并初始化为0

    __heap_limit

     

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;声明数据段RESET

    ;该数据段内存单元只读

    ;功能:为所有Handler分配内存单元

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    PRESERVE8                ;//当前堆栈保持8字节对齐

                    THUMB                    ;//THUMB模式

    ;//向量表映射到复位地址0

                    AREA    RESET, DATA, READONLY

                    EXPORT  __Vectors

     

    __Vectors       DCD     __initial_sp              ; Top of Stack

                    DCD     Reset_Handler             ; Reset Handler

                    DCD     NMI_Handler               ; NMI Handler

                    DCD     HardFault_Handler         ; Hard Fault Handler

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     SVC_Handler               ; SVCall Handler

                    DCD     0                         ; Reserved

                    DCD     0                         ; Reserved

                    DCD     PendSV_Handler            ; PendSV Handler

                    DCD     SysTick_Handler           ; SysTick Handler

     

                    DCD     BOD_IRQHandler  

                    DCD     WDT_IRQHandler  

                    DCD     EINT0_IRQHandler

                    DCD     EINT1_IRQHandler

                    DCD     GPAB_IRQHandler 

                    DCD     GPCDE_IRQHandler

                    DCD     PWMA_IRQHandler 

                    DCD     PWMB_IRQHandler 

                    DCD     TMR0_IRQHandler 

                    DCD     TMR1_IRQHandler 

                    DCD     TMR2_IRQHandler 

                    DCD     TMR3_IRQHandler 

                    DCD     UART0_IRQHandler

                    DCD     UART1_IRQHandler

                    DCD     SPI0_IRQHandler 

                    DCD     SPI1_IRQHandler 

                    DCD     SPI2_IRQHandler 

                    DCD     SPI3_IRQHandler 

                    DCD     I2C0_IRQHandler 

                    DCD     I2C1_IRQHandler 

                    DCD     CAN0_IRQHandler 

                    DCD     CAN1_IRQHandler

                    DCD     Default_Handler 

                    DCD     USBD_IRQHandler  

                    DCD     PS2_IRQHandler  

                    DCD     ACMP_IRQHandler 

                    DCD     PDMA_IRQHandler

                    DCD     Default_Handler 

                    DCD     PWRWU_IRQHandler

                    DCD     ADC_IRQHandler

                    DCD     Default_Handler  

                    DCD     RTC_IRQHandler  

                          

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ;声明代码段|.text|,只读

    ;功能:复位时,代码从该代码段首先执行

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                

                    AREA    |.text|, CODE, READONLY

     

                    ENTRY                             ;//进入代码段

                    

    Reset_Handler   PROC

                    EXPORT  Reset_Handler             [WEAK]

                    IMPORT  __main                  ;//引入C文件中的main函数

                    

                    LDR     R0, =__main            ;//获取C文件中的main函数地址

                    BX      R0                       ;//跳转到main函数

                    ENDP

                    

                                       

    NMI_Handler     PROC

                    EXPORT  NMI_Handler               [WEAK]

                    B       .               ;//停止

                    ENDP

    HardFault_Handler\

                    PROC

                    EXPORT  HardFault_Handler         [WEAK]

                    B       .                           ;//停止

                    ENDP

    SVC_Handler     PROC

                    EXPORT  SVC_Handler               [WEAK]

                    B       .                           ;//停止                  

                    ENDP

    PendSV_Handler  PROC

                    EXPORT  PendSV_Handler            [WEAK]

                    B       .                           ;//停止

                    ENDP

    SysTick_Handler PROC

                    EXPORT  SysTick_Handler           [WEAK]

                    B       .                           ;//停止

                    ENDP

     

    Default_Handler PROC

     

                    EXPORT  BOD_IRQHandler            [WEAK]

                    EXPORT  WDT_IRQHandler            [WEAK]

                    EXPORT  EINT0_IRQHandler          [WEAK]

                    EXPORT  EINT1_IRQHandler          [WEAK]

                    EXPORT  GPAB_IRQHandler           [WEAK]

                    EXPORT  GPCDE_IRQHandler          [WEAK]

                    EXPORT  PWMA_IRQHandler           [WEAK]

                    EXPORT  PWMB_IRQHandler           [WEAK]

                    EXPORT  TMR0_IRQHandler           [WEAK]

                    EXPORT  TMR1_IRQHandler           [WEAK]

                    EXPORT  TMR2_IRQHandler           [WEAK]

                    EXPORT  TMR3_IRQHandler           [WEAK]

                    EXPORT  UART0_IRQHandler          [WEAK]

                    EXPORT  UART1_IRQHandler          [WEAK]

                    EXPORT  SPI0_IRQHandler           [WEAK]

                    EXPORT  SPI1_IRQHandler           [WEAK]

                    EXPORT  SPI2_IRQHandler           [WEAK]

                    EXPORT  SPI3_IRQHandler           [WEAK]

                    EXPORT  I2C0_IRQHandler           [WEAK]

                    EXPORT  I2C1_IRQHandler           [WEAK]

                    EXPORT  CAN0_IRQHandler           [WEAK]

                    EXPORT  CAN1_IRQHandler           [WEAK]

                    EXPORT  USBD_IRQHandler           [WEAK]

                    EXPORT  PS2_IRQHandler            [WEAK]

                    EXPORT  ACMP_IRQHandler           [WEAK]

                    EXPORT  PDMA_IRQHandler           [WEAK]

                    EXPORT  PWRWU_IRQHandler          [WEAK]

                    EXPORT  ADC_IRQHandler            [WEAK]

                    EXPORT  RTC_IRQHandler            [WEAK]

                    

    BOD_IRQHandler

    WDT_IRQHandler

    EINT0_IRQHandler

    EINT1_IRQHandler

    GPAB_IRQHandler

    GPCDE_IRQHandler

    PWMA_IRQHandler

    PWMB_IRQHandler

    TMR0_IRQHandler

    TMR1_IRQHandler

    TMR2_IRQHandler

    TMR3_IRQHandler

    UART0_IRQHandler

    UART1_IRQHandler

    SPI0_IRQHandler

    SPI1_IRQHandler

    SPI2_IRQHandler

    SPI3_IRQHandler

    I2C0_IRQHandler

    I2C1_IRQHandler

    CAN0_IRQHandler

    CAN1_IRQHandler

    USBD_IRQHandler

    PS2_IRQHandler

    ACMP_IRQHandler

    PDMA_IRQHandler

    PWRWU_IRQHandler

    ADC_IRQHandler

    RTC_IRQHandler

                    B       .                        ;//停止

                    ENDP

     

                    ALIGN                            ;//添加补丁字节满足一定的对齐方式

     

     

    ; //用户初始化的堆栈

     

                    IF      :DEF:__MICROLIB          ;//检查是否定义了__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

     

                    ALIGN                            ;//添加补丁字节满足一定的对齐方式

     

                    ENDIF

     

     

                    END

     

     

    深入重点:

    ü 什么是堆栈?

    ü startup_M051.s上电时初始化单片机的硬件堆栈、初始化RAM分配内存空间和跳转到主函数即main函数

    ü 使用IMPORTEXPORT声明外部符号时,若链接器在连接微控制器时不能解释该符号,而伪指令中没有[WEAK]选项时,则链接器会报告错误,若伪指令中有[WEAK]选项时,则链接器不会报告错误,而是进行下面的操作:

              1:如果该符号被B或者BL指令引用,则该符号被设置成下一条指令的地址,该B或者  BL指令相当于一条NOP指令。

              2:其他情况下该符号被设置为0

    …………………………………………

     

    书籍下载地址(复制到下载工具进行下载):

     

     

     

    https://files.cnblogs.com/wenziqi/ARMCortex-M0原理与应用实践.part1.rar

     

     

     

    https://files.cnblogs.com/wenziqi/ARMCortex-M0原理与应用实践.part2.rar

     

     

     

    注:书籍内容会不定期进行更新!

     

  • 相关阅读:
    《何以为家》--观影心得
    博弈论 -- 巴什博弈
    《黑客攻防技术-系统实战》第二章--栈溢出1
    《汇编语言》--程序范例
    《黑客攻防技术-系统实战》开篇讲解
    ptrace理解
    DPDK初始化
    C++ 对象内存模型
    DPDK学习路线计划
    DPDK学习开篇
  • 原文地址:https://www.cnblogs.com/wenziqi/p/2358294.html
Copyright © 2011-2022 走看看