STM32 官方为广大开发者提供一套统一开发固件,主要是屏蔽寄存器封装,提供初始化等功能,较少开发者负担。只需要调用相关模块封装,对相关结构提初始化即可,较少开发调试时间。本次主要以官方STM32F4xx_DSP_StdPeriph_Lib_V1.8.0固件版本为主,主要讲解各个模块主要作用以及使用方法,固件主要结构将在后面做介绍
本次主要讲解开发过程中大家都会忽略的STM32 启动文件流程,STM43 启动文件名为startup_stm32f40_41xxx.s,其目录在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\arm,也可以按照整个文件名搜索整个固件,会发现有很多相同文件分布在不同目录,主要是因为官方固件提供很多开发样例,每个样例都需要进行启动文件,官方提供用例在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Project\STM32F4xx_StdPeriph_Examples\中。启动文件时以.s开头,都是用ARM汇编指令集来完成的。具体ARM汇编可以参考《Arm 体系结构与编程》

启动文件工作
1:初始化堆栈空间
2:PC指针 Rest_Handler
3: 初始化中断向量表
4:系统时钟
5:堆栈初始化完成之后,进入main函数

初始化栈空间
初始化文件开头代码 首先是初始化栈空间代码如下:

上述代码的意思是开辟空间为0x00000400(1KB)的栈空间, 主要用于局部遍历,函数调用,参数形参等开销,不能超过芯片内部SRAM。可以根据需要进行调整,防止程序溢出
EQU:为ARM汇编伪指令,相当于C中define,意思为定义Stack_Size 代表0x00000400
AREA: 汇编伪指令,意思是定义伪一个代码端或者数据段,其格式为
AREA sectionname {,attr} {,attr}
sectionname为定义的代码或者数据段名字, attr为该字段属性
AREA STACK, NOINIT, READWRITE, ALIGN=3
意思为 定义该数据段名字为STACK,NOINIT指定本数据段仅仅保留了内存单元,而没有将各初始值写入内存单元。
READWRITE为该数据段即可写又可读, ALIGN为字节对齐,为2的3次方等于8,8字节对齐。
SPACE:用于一块内存单元,并用0初始化。申请Stack_Size大小内存。
__initial_sp 紧随SPACE后面,表示申请内存的结束地址,即栈顶位置,栈是由高向低生长,故需要指向栈顶位置

初始化堆空间
紧接着为堆空间地址申请,代码如下
堆空间大小为Heap_Size即0x00000200(512Byte),EQU AREA和SPACE指令上面已经讲到 不再解释。__heap_base在SPACE之前,因为堆空间是向上增长的,__heap_base指向为堆的地址,__heap_limit为堆的结束地址。
PRESERVE8:当前代码中数据段是8字节对齐,因为汇编指令中LDRD和STRD指令要求内存单元地址是8字节对齐的,在程序中使用这些指令在数据栈中传送数据时,要求该数据段是8字节对齐。
THUMB:兼容THUMB指令集。THumb指令集是堆ARM指令集的一个子集进行重新编码得到得,其指令长度为16位。THUMN-2为32位。

中断向量表初始化
接下来将会进入中断向量表:

定义RESET数据段为可读,中断向量表本质上为一张中断函数指针,每个地址记录中断服务程序入口地址,发生中断后,STM32将会进入到相应的中断服务程序,每个地址代表不同的中断,由厂商写死,不可更改,《STM32F4xx中文参考手册》中可知,每个地址代表的中断:

篇幅有限并没有详细列出来,可以查看手册
EXPORT:声明一个标号可被外部的文件使用,使标号具有全局属性,上述代表中分别定义__Vectors为中断向量首地址,__Vectors_End为中断向量表末尾地址,__Vectors_Size为中断向量大小,实际代码中断向量表如下:


DCD:分配一个或者多个以字为单位的内存,以4字节对齐,并要求初始化这些内存。
__initial_sp为0x0000 0000地址,为初始化栈地址,Reset_Handler为复位中断程序,该处理采用汇编进行编写
__Vectors_Size为计算中断向量表大小为(__Vectors_End - __Vectors)。

Reset Handler
reset为程序上电进入,设置时钟,进入main函数处理

首先声明Reset_Handler, SystemInit和__main函数,SystemInit为外部C语言编写文件主要是对时钟初始化,__main为main函数入口,可以被该汇编文件进行调用。
LDR:从存储器中加载到寄存器中。
BL:程序跳转指令,程序PC指针跳转到由寄存器/标号给出的地址,并把跳转前的下一条指令地址保存到LR中
BLX: 与BL不同之处,根据寄存器的LSE确定处理器的状态,并把跳转前的下一条指令保存到LR。
上述程序,首先把SystemInit()函数地址加载在R0中,并跳转到SystemInit()函数,执行SystemInit,执行完毕后
加载__main函数,程序跳转到main函数中。
SystemInit()函数功能意义在后续中继续解释。

中断服务程序
中断服务程序默认没有编写,默认的中断程序如下:

上述每个中断程序默认为无限循环,当进入到中断,而开发者有没有实现中断服务程序将会进入死循环。
注意:中断服务程序需要开发者实现相应中断,一般是在stm32f4xx_it.c文件中。

堆初始化
堆的初始化调用是在一下程序中:

IF:相当于C中if ,上述代码意思是判定__MICROLIB宏是否定义
如果定义,将会跳转到__initial_sp,使用上述代码中默认堆栈大小初始化,如果没有定义将会使用__use_two_region_memory,用户自定义。
__MICROLIB宏的定义是在keil5工具中进行勾选,如下所示:

参考文档
《 零死角玩转STM32》
《STM32F4XX中文参考手册》
《arm体系结构与编程》

STM32那点事(1)_STM32F40_41xx启动文件详解相关推荐

  1. STM32启动文件详解-比较清晰的一篇

    STM32启动文件详解 启动文件使用的 ARM 汇编指令汇总 启动程序源码注释(点此下载) 1. Stack-栈 Stack_Size EQU 0x00000400AREA STACK, NOINIT ...

  2. STM32的2.02固件库提供的启动文件详解 stm32f10x_vector.s

    当前的嵌入式应用程序开发过程里,并且C语言成为了绝大部分场合的最佳选择.如此一来main函数似乎成为了理所当然的起点--因为C程序往往从main函数开始执行.但一个经常会被忽略的问题是:微控制器(单片 ...

  3. GD32启动文件详解(同STM32)

    启动文件使用的 ARM 汇编指令汇总 1. Stack-栈 Stack_Size          EQU     0x00000800 AREA    STACK, NOINIT, READWRIT ...

  4. 国产超低功耗华大单片启动文件详解及SystemInit函数分析

    启动代码文件名一般可命名为如startup_hc32xxxx.s.启动代码作用一般是: 1) 堆和栈的初始化 包括堆栈的大小,MSP(main stack pointer)值等.MSP的初始值在复位阶 ...

  5. 004:STM32启动文件详解及SystemInit函数分析(转)

    1 ;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000 2 ;然后在RAM中分配变量使用的堆 3 ;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x080 ...

  6. STM32启动文件详解及SystemInit函数分析

    1 ;先在RAM中分配系统使用的栈,RAM的起始地址为0x2000_0000 2 ;然后在RAM中分配变量使用的堆 3 ;然后在CODE区(flash)分配中断向量表,flash的起始地址为0x080 ...

  7. apache-Tomcat 8.5.39安装包 安装过程以及启动文件详解

    1.apache-tomcat8.5.39 安装包地址 链接:https://pan.baidu.com/s/1-EIftvG-A-XM8VEfkDlJLQ  提取码:fxpp  复制这段内容后打开百 ...

  8. STM32(Cortex-M3)启动过程+IAR中xcl及icf文件详解

    一:STM32(Cortex-M3)启动过程(入口地址) ARM7和ARM9启动时从绝对地址0X00000000开始执行复位中断程序,即固定了复位后的起始地址,但中断向量表的位置是可变的. Corte ...

  9. STM32 之三 标准外设版USB驱动库详解(架构+文件+函数+使用说明+示例程序)

    写在前面 目前,ST的USB驱动有两套,一套是早期的独立版USB驱动,官方培训文档中称为Legacy library:一套为针对其Cube 系列的驱动,根据芯片不同可能有区别,具体见对应芯片的Cube ...

最新文章

  1. 墨奇科技汤林鹏:如何用 AI 技术颠覆指纹识别?
  2. 经典!工业界深度推荐系统与CTR预估必读的论文汇总
  3. SIFT特征及特征匹配:SIFT and feature matching
  4. 电子政务“云”成大势
  5. linux max 函数,sched_get_priority_max()函数 Unix/Linux
  6. 公开信息查询的一些方法,查征信,查婚姻状况,查询公开个人信息
  7. mysql在财务分析中的作用_财务报表分析的作用和目的
  8. 个人小程序/京东推广链接/长链接/短连接/跳转到京东购物小程序
  9. 清明节不加班??不存在的
  10. 计算机主机usb端口使用不了,电脑usb接口不能用怎么办
  11. 用ARCGIS做DEM地形分析
  12. 从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速
  13. 大一期末项目:学生管理系统
  14. 2021-10-27 基于电影数据库的简单查询(数据库第二次实验)
  15. Qt深入浅出(十五)QTableView
  16. python3安装PIL
  17. 中庸——粗浅阅读后的感受,在此勉励
  18. hana 查看表字段_SAP HANA 表格
  19. 首届“攀升玩创嘉年华”端午江城噶事!
  20. CSS实现文字下面波浪线

热门文章

  1. MyEclipse Profile 结合visualvm 监控内存泄露
  2. 【JEECG-Mybatis版本】springmvc+mybatis+代码生成器(代码一键生成)
  3. 退化函数及多种复原方法【Matlab】
  4. Linux文件系统管理命令(第二版)
  5. Configure a VLAN on top of a team with NetworkManager (nmcli) in RHEL7
  6. #淘宝#复制分享宝贝内容,打开淘宝APP,自己主动弹出宝贝提示信息
  7. 技术博客么?开始每天一更
  8. Codeforces Round #250 (Div. 2)—A. The Child and Homework
  9. android中如何执行java命令
  10. 主成分分析中特征值分解与SVD(奇异值分解)的比较及其相关R语言的实现