• 启动文件讲解


    本章参考资料《 STM32F4xx 中文参考手册》第十章-中断和事件:表 46.
    STM32F42xxx STM32F43xxx 的向量表; MDK 中的帮助手册—ARM Development Tools:
    用来查询 ARM 的汇编指令和编译器相关的指令。 

     

    启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
    1 初始化堆栈指针 SP=_initial_sp
    2 初始化 PC 指针=Reset_Handler
    3 初始化中断向量表
    4 配置系统时钟
    5 调用 C 库函数_main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界 

     

    在讲解启动代码的时候,会涉及到 ARM 的汇编指令和 Cortex 内核的指令,有关
    Cortex 内核的指令我们可以参考《 CM3 权威指南 CnR2》第四章:指令集。剩下的 ARM 的
    汇编指令我们可以在 MDK->Help->Uvision Help 中搜索到,以 EQU 为例,检索如下: 

     

     这里将回到最初的前面几篇文章的问题,为什么需要手动编写一个SystemInit() 函数让编译器不报错。

    WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部
    文件没有声明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并
    不是唯一的。
    IMPORT:表示该标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似。这里表
    SystemInit __main 这两个函数均来自外部的文件。
    SystemInit()是一个标准的库函数,在 system_stm32f4xx.c 这个库文件总定义。主要作
    用是配置系统时钟,这里调用这个函数之后, F429 的系统时钟配被配置为 180M
    __main 是一个标准的 C 库函数,主要作用是初始化用户堆栈,最终调用 main 函数去
    C 的世界。这就是为什么我们写的程序都有一个 main 函数的原因。如果我们在这里不
    调用__main,那么程序最终就不会调用我们 C 文件里面的 main,如果是调皮的用户就可以
    修改主函数的名称,然后在这里面 IMPORT 你写的主函数名称即可。

    你可能会说,_main函数我们也没有写啊,为什么不报错,这个_main函数是MDK编译器自动给我生成的,不用用户操心。

    在启动文件里面已经帮我们写好所有中断的中断服务函数,跟我们平时写的中断服务
    函数不一样的就是这些函数都是空的,真正的中断复服务程序需要我们在外部的 C 文件里
    面重新实现,这里只是提前占了一个位置而已。
    如果我们在使用某个外设的时候,开启了某个中断,但是又忘记编写配套的中断服务
    程序或者函数名写错,那当中断来临的时,程序就会跳转到启动文件预先写好的空的中断
    服务程序中,并且在这个空函数中无线循环,即程序就死在这里。

     下面这段话引用自《 CM3 权威指南 CnR2》 3.8—复位序列,CM4 的复位序列跟 CM3 一样。 —秉火
    注。
    在离开复位状态后, CM3 做的第一件事就是读取下列两个 32 位整数的值:
    1、 从地址 0x0000,0000 处取出 MSP 的初始值。
    2、 从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量, LSB 必须是
    1。 然后从这个值所对应的地址处取指。

  • 相关阅读:
    记录慕课学习爬取中国大学排名(由上交大计算的排名结果)
    SuperMap iMobile for Android室内导航APP
    Android studio入坑记录(SuperMap iMobile开发)
    2019年的十月和十一月
    python学习国庆期间
    学习python——collections系列
    又是快乐学习python的一天
    学习MATLAB
    Python学习练习题
    使用javaScript来实现一个有序链表
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/6746065.html
Copyright © 2020-2023  润新知