zoukankan      html  css  js  c++  java
  • STM32启动代码详细分析

    最近需要学习iap的功能,因此离不开stm32的启动代码的分析,以前看了很多遍,都看不懂,读书百遍,其义自见,因此我有看了一遍,下面的文章,挺好的,因此转载:
     
    在上电复位后,我们都知道会先运行启动代码,但是启动代码到底使干什么用的呢?下面小弟给大家一一列出来。
    1、初始化堆栈指针
    2、初始化 PC 指针
    3、初始化中断向量表
    4、配置系统时钟
    5、调用 C 库函数_main 初始化用户堆栈
    我们根据这以上的几个步骤一一进行详细的解析:
    1、栈的内存分配
    这段代码的意思是,开辟了一个栈,这个栈的大小是0x00000400也就是1KB的大小,名字为STACK,不初始化,可读可写,2^3=8字节对齐。
    那么问题来了,那这个栈到底使干什么的呢?小弟相信大家在学习C语言的时候应该也是知道了,栈区保存的是局部变量,只是当时并没有深入研究它的大小问题。那在这里小弟给大家详细讲解一下栈的作用:
    1、局部变量
    2、函数调用
    3、函数形参
    以上的这三种情况的开销都是使用我们的栈区的资源的。所以啊!这里小弟给个位提个醒,千万不要把栈区当成无止境大小的
    哦!STM32可不比我们的电脑,没有那么多的空间可以给大伙挥霍,如果我们定义的局部变量过大可是会莫名其妙报错的。
    温馨提示:请不要在写程序时,过度使用局部变量,会造成栈的益处,从而导致编译报错,如果在特殊情况下真的需要很大的栈区空间,只需来这里进行栈区大小的修改即可。
    那么小弟再来给这个程序段里的汇编指令做一个详细的介绍
    Stack_Size      EQU     0x00000400
    EQU:宏定义的伪指令,相当于等于,类似与 C 中的 define。
    这句话的意思是,定义一个宏名Stack_Size这个宏代表0x00000400的意思,用我们C语言来表示就是
    #define Stack_Size 0x00000400
    AREA    STACK, NOINIT, READWRITE, ALIGN=3
    AREA:告诉汇编器汇编一个新的代码段或者数据段。
    STACK:表示段名
    NOINIT:表示不初始化
    READWRITE:表示可读可写
    ALIGN=n:表示按照 2^n字节对齐
    这里小弟就不多说了,解释已经很详细了,小哥哥小姐姐们自己组合起来吧
    Stack_Mem       SPACE   Stack_Size
    SPACE:用于分配一定大小的内存空间,单位为字节。
    这句话的意思是,分配一个内存空间,这个内存空间的大小为Stack_Size,也就是我们刚才宏定义的0x00000400
    然后最后标号__initial_sp 紧挨着 SPACE 语句放置,表示栈的结束地址。也就是栈顶的地址。
    温馨提示:栈的生长是由高地址向低地址生长的。



    2、堆的内存分配
    这段代码的意思是,开辟堆的大小为0x00000200也就是512B的大小,名字为HEAP,不初始化,8字节对齐。



    在之前我们一直认为的是,全局变量,静态变量都分配在堆区中,这里是不正确的,我们的全局变量和静态变量,并不是直接
    分配在堆中,这里的堆只有malloc函数分配的内存,会在这里进行分配,而静态变量和局部变量都是在SRAM中分配,这也就是为什么我们全局变量可以定义一个大于512B大小的空间了。
    温馨提示:如果使用了malloc函数一定要注意这个堆咯!不可以大于512B呢!当然这里也可以进行修改。
    那咱们再来一条一条语句进行分析吧!
    Heap_Size       EQU     0x00000200
    这里我们就不多说了这条代码和上面那条是一个意思
    AREA    HEAP, NOINIT, READWRITE, ALIGN=3
    这里也和上面差不多,唯一改变的就是段名是HEAP而不是STACK了
    __heap_base
    在SPACE前出现这条代码代表的是堆的起始地址
    Heap_Mem        SPACE   Heap_Size
    这里是分配一个0X00000200大小的空间
    __heap_limit
    在SPACE后出现这条代码代表的是堆的结束地址
    PRESERVE8
    指定当前文件的堆栈按照 8 字节对齐
    THUMB
    表示后面指令兼容 THUMB 指令。THUBM 是 ARM 以前的指令集,16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集,THUMB-2 是 32 位的,兼容 16 位和 32 位的指令。
    3、向量表



    这段代码的意思是,定义了一个数据短,名字叫RESET,只可读。
    那么这里问题来了,什么是向量表呢!在这里,这个向量表示为了决定中断服务函数的入口的,每一个向量表都是4个字节,
    向量表决定了入口的偏移地址。
    AREA    RESET, DATA, READONLY
    这句话的意思是定义了一个代码段RESET,只可读
    EXPORT  __Vectors
    EXPORT  __Vectors_End
    EXPORT  __Vectors_Size
    这三句话都是同一个意思,相当于C语言中的EXPORT可以被外部文件所引用
    向量表如下
    ...........................省略部分.................................




    这里呢,就是我们的中断向量表了,我们可以发现,它是从栈区中开始加载的,从栈顶开始,
    __Vectors 代表向量起始地址
    __Vectors_End 代表向量结束地址
    DCD:分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表中,DCD 分配了一堆内存,并且以 ESR 的入口地址初始化它们
    Reset_Handler     
    NMI_Handler       
    HardFault_Handler 
    MemManage_Handler 
    BusFault_Handler  
    UsageFault_Handler
    这些都是地址,我们的知道,函数名就是函数的地址,所以我们的中断服务函数必须使用这些作为函数名,否则无法正确进入中断服务函数。
    __Vectors_Size  EQU  __Vectors_End - __Vectors
    通过这句话我们知道结束地址-起始地址,自然就是向量表的大小了。



    好的,个位小哥哥小姐姐,今天的课就上到这里了,剩下的部分我们下回分解。
  • 相关阅读:
    MySQL key分区(五)
    Kolya and Tandem Repeat
    Hadoop源码分析(MapReduce概论)
    写一个随机洗牌函数——概率题
    《说吧,医生》难得的五星级中文原创医学科普。
    《卖体验》:给用户超出预期的体验。营销讲师风格,陷入了锤子模式。三星推荐
    《最大回报:健康投资》:协和医院专家的医疗健康科普书,书有点旧了,水平够专业 三星推荐
    《听体检说:健康都去哪了》:体检项目的科普书,可以当作手册来翻一翻。 三星推荐
    《金融的解释》:深入浅出的金融学入门 三星推荐
    《病有所医当问谁》:市场化是医改大方向,医改的问题是市场化不够 五星推荐
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/11797733.html
Copyright © 2011-2022 走看看