南有乔木z

随心所欲,想写啥就写啥。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、基础概念声明

中断向量:

  说明:由硬件产生的中断标识码,一般用于存放中断服务程序的跳转指令。根据硬件产生的中断号查找中断向量表来确定对应的中断向量。CM3内核有15个异常
        和240个中断源。
 
程序的内存分配:(更多内容: http://blog.csdn.net/c12345423/article/details/53004747 )
栈(stack)

  说明:由编译器自动进行分配和释放,一般用于存放函数的参数和局部变量的值。操作方式类似于数据结构中的栈。

  特性:由于栈的操作顺序是先进后出,因此用栈顶指针(top)来进行操作栈空间。在STM32中,此段空间在启动文件(汇编文件)中被分配,相当于在OS中给任务分配的栈空间。

     栈的生长方式为由下至上,栈顶指针为当前程序所占用RAM空间的最大值。

                图1. KEIL硬件调试观察栈顶指针的大小

 

                 图2. MAP文件中确定栈的起始地址

  相关代码:

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000200

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

       
        堆(heap) :

  说明:由程序员进行分配和释放,若程序员没有进行释放,最后由OS进行释放。
       全局区(静态区):初始化的全局变量及静态变量被放置在一起,而未初始化的全局变量和静态变量存放在另一块区域。
       文字常量区:字符串存放的位置。
       程序代码区:存放函数体的二进制文件。
    异常(中断)发生时的内核操作:
        ①、保护现场(压栈操作)。处理器通过硬件将相关的寄存器xPSR、PC、LR R12及R0-R3保存到当前使用的堆栈中。
        ②、取向量 CM3内核内部有 数据总线(Dbus)和指令总线(Ibus)。在Dbus保存处理器状态的同时,Ibus将从向量表取出异常向量,并获取ISR函数的地址,
      保护现场和取向量是同时进行的。
        ③、更新寄存器(恢复现场)。
        
    
二、启动文件与内核架构的说明
    
    1.不同的CPU需要的启动文件不同,定义的硬件资源如 定时器、串口等不同。
    
    2.复位后的执行过程:
         相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,
CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC = 0x000000)同时中断
     向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况:
    (1) 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处;
    (2) 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处;
    (3) 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述;
    
    而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的
下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。


三、启动文件的内容说明

     1.开辟一定大小的堆栈空间,设置SP、PC指针。
     2.在代码的起始位置建立中断向量表,第一个表项是栈顶指针(从Flash启动,为0x8000000),第二个表项是复位中断服务程序入口地址。
     3.在复位中断服务程序中设置系统初始时钟 、实现由__main跳转到C语言 main函数。
          __main不是C语言中mian的入口。__main标号表示C/C++标准实时库函数里的一个初始化子程序__main的入口地址。该程序的一个主要作用是初始化堆栈
       (对于程序清单一来说则是跳转__user_initial_stackheap标号进行初始化堆栈的),并初始化映像文件,最后跳转C程序中的main函数。这就解释了为何
       所有的C程序必须有一个main函数作为程序的起点——因为这是由C/C++标准实时库所规定的——并且不能更改,因为C/C++标准实时库并不对外界开放源代码。
       因此,实际上在用户可见的前提下,程序在第204行后就跳转至.c文件中的main函数,开始执行C程序了。

posted on 2017-12-02 16:53  南有乔木z  阅读(454)  评论(0编辑  收藏  举报