005 - STM32启动代码

news2024/11/28 12:37:12

常用汇编指令

指令名称作用
EQU给数字常量取一个符号名,相当于C语言中的#define
AREA汇编一个新的代码段或者数据段;
SPACE分配内存空间;
PRESERVE8当前文件栈需要按照8字节对齐;
EXPORT声明一个具有全局属性的标号,可被外部文件访问;
DCD以字为单位分配内存,要求按照4字节对齐,并初始化这些内存;
PROC定义子程序,与ENDP成对使用,ENDP表示子程序结束;
WEAK若定义,如果外部声明了该指令修饰的标号,则优先使用外部声明的标号,如果外部没有声明,也不会出错。
IMPORT声明标号来自外部文件,与C语言中的extern关键字类似
B跳转指令,即跳转到一个标号;
ALIGN编译器对指令或者数据的存放地址进行对齐,一般需要跟一个立即数,默认表示按照4字节对齐;
END达到文件的末尾,表示文件结束;
IF,ENSE,ENDIF汇编条件分支语句,与C语言中的if...else...类似
;注释符,与C语言中//类似

启动代码

看一下startup_stm32f4429_439xx.s文件前面的copyright内容

;******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
;* File Name          : startup_stm32f429_439xx.s
;* Author             : MCD Application Team
;* @version           : V1.8.0
;* @date              : 09-November-2016
;* Description        : STM32F429xx/439xx devices vector table for MDK-ARM toolchain. 
;*                      This module performs:
;*                      - Set the initial SP											初始化指针sp
;*                      - Set the initial PC == Reset_Handler							 初始化指针pc
;*                      - Set the vector table entries with the exceptions ISR address		初始化向量终端表
;*                      - Configure the system clock and the external SRAM/SDRAM mounted  	配置系统时钟
;*                        on STM324x9I-EVAL boards to be used as data memory  
;*                        (optional, to be enabled by user)
;*                      - Branches to __main in the C library (which eventually				调用C库
;*                        calls main()).
;*                      After Reset the CortexM4 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.

STM32启动代码由汇编编写,会在系统上电后执行,可以认为启动代码就是整个系统启动的引导程序,功能主要分如下几个:

  1. 初始化栈指针SP = _initial_sp
  2. 初始化PC指针 = Rest_Handler ;
  3. 初始化中断向量表;
  4. 配置系统时钟;
  5. 调用C库函数_main初始化用户栈,从而真正转到C的main函数中。

1、栈

Stack_Size      EQU     0x00000400	;给0x00000400这个立即数一个别名Stack_Size,从名字上可以看出来这是给栈分配空间为1KB,如果不够的话可以修改这里

                AREA    STACK, NOINIT, READWRITE, ALIGN=3 ;栈名称为STACK,NOINIT为不初始化,READWRIT:可读写,ALIGN=3,表示已2^3(8)字节对齐
Stack_Mem       SPACE   Stack_Size		;指定了内存大小等于Stack_Size
__initial_sp						  ;标号__initial_sp紧挨着SPACE放置,表示栈的结束地址,及栈顶地址

打开map文件可以看到关于栈的相关信息
在这里插入图片描述

2、堆

Heap_Size       EQU     0x00000200	;给0x00000200这个立即数一个别名Heap_Size,从名字上可以看出来这是给栈分配空间为512B,如果不够的话可以修改这里

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3 ;堆名称为HEAP,NOINIT为不初始化,READWRIT:可读写,ALIGN=3,表示已2^3(8)字节对齐
__heap_base								;堆的起始地址
Heap_Mem        SPACE   Heap_Size		  ;指定对的内存大小等于Heap_Size
__heap_limit							;堆的结束地址

                PRESERVE8				 ;指定当前文件的堆按照8字节对齐
                THUMB					;后面指令兼容THUMB指令

3、向量表

; 重映射向量表
                AREA    RESET, DATA, READONLY		;定义数据段,名称为RESET,只读模式,
                EXPORT  __Vectors				   ;声明可被外部访问的标号
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size	
;这里我自己理解就类似于一个数组,__Vectors是数组的起始地址,__Vectors_End是数组结束地址,__Vectors_Size在最后做了计算,是起始地址与结束地址的差值
;向量表中记录了系统所有中断向量地址,当内核响应了发生的异常(中断或事件)后,对应的异常服务例程就会执行,所以这里的向量表就是为异常服务机制提供入口地址
__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler                   ; Window WatchDog                                        
                DCD     PVD_IRQHandler                    ; PVD through EXTI Line detection                        
                DCD     TAMP_STAMP_IRQHandler             ; Tamper and TimeStamps through the EXTI line            
                DCD     RTC_WKUP_IRQHandler               ; RTC Wakeup through the EXTI line                       
                DCD     FLASH_IRQHandler                  ; FLASH                                           
                DCD     RCC_IRQHandler                    ; RCC                                             
                DCD     EXTI0_IRQHandler                  ; EXTI Line0                                             
                DCD     EXTI1_IRQHandler                  ; EXTI Line1                   
			   ;由于篇幅原因,中间就删掉了
                DCD     SPI4_IRQHandler                   ; SPI4
                DCD     SPI5_IRQHandler                   ; SPI5
                DCD     SPI6_IRQHandler                   ; SPI6
                DCD     SAI1_IRQHandler                   ; SAI1
                DCD     LTDC_IRQHandler                   ; LTDC
                DCD     LTDC_ER_IRQHandler                ; LTDC error
                DCD     DMA2D_IRQHandler                  ; DMA2D
                                         
__Vectors_End			;这里表示向量表的结束地址

__Vectors_Size  EQU  __Vectors_End - __Vectors		;计算向量表的容量并赋值给__Vectors_Size

4、复位程序

                AREA    |.text|, CODE, READONLY		;定义了名称为.text的代码段,只读
; Reset handler定义名为Reset_Handler的子程序
Reset_Handler    PROC
				;导入Reset_Handler子程序,这里用WEAK修饰表示弱定义,优先定义外部定义的程序,如果没有,也不会报错,
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit				;表示SystemInit函数来自外部
        IMPORT  __main					;表示__main函数来自外部

                 LDR     R0, =SystemInit	;将SystemInit加载到R0寄存器中
                 BLX     R0					;跳转到R0给出的地址
                 LDR     R0, =__main		;将__main加载到R0寄存器中
                 BX      R0					;跳转到R0给出的地址
                 ENDP					   ;程序结束

SystemInit是标准库函数,在system_stm32f4xx.c中定义,主要是用来配置系统时钟,我现在用的F429的开发板,在调用SystemInit后,会将系统时钟配置到180MHz。

__main是个标准C库函数,但是这里要主义的是,这个main不是我们在C语言中的main函数,__main作用是初始化用户栈,完成后在最后调用main转到C语言中。

5、中断服务程序

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler     PROC									;定义了NMI_Handler中断子程序
                EXPORT  NMI_Handler                [WEAK]	;弱定义,若外部定义了则优先使用,如果未定义,也不报错,以下相同
                B       .								;跳转到.,在这里.表示无限循环
                ENDP
;省略了一部分详细看原文档
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP
Default_Handler PROC											;外部中断,同样是弱定义
                EXPORT  WWDG_IRQHandler                   [WEAK]                                        
                EXPORT  PVD_IRQHandler                    [WEAK]                      
                EXPORT  TAMP_STAMP_IRQHandler             [WEAK]         
                EXPORT  RTC_WKUP_IRQHandler               [WEAK]                     
                EXPORT  FLASH_IRQHandler                  [WEAK]                                         
                EXPORT  RCC_IRQHandler                    [WEAK]                                            
                EXPORT  EXTI0_IRQHandler                  [WEAK]                                            
              ;篇幅省略
                EXPORT  LTDC_ER_IRQHandler                [WEAK]
                EXPORT  DMA2D_IRQHandler                  [WEAK]

WWDG_IRQHandler                                                       
PVD_IRQHandler                                      
TAMP_STAMP_IRQHandler                  
;篇幅省略  
LTDC_IRQHandler                   
LTDC_ER_IRQHandler                 
DMA2D_IRQHandler                  
                B       .				;跳转到.,在这里.表示无限循环
                ENDP

这里需要注意的是,使用中断的时候,应为是弱定义的中断服务子程序,因此会优先调用外部定义的服务程序,当我们在外部没有编写配套的中断服务子程序或者编写的服务子程序与启动文件中的程序名不一致时,系统会自动跳转到启动文件中默认的中断服务子程序中,B .然后就在此处无限循环,程序就卡死到这里了

6、用户堆与栈的初始化

                ALIGN		;用来指定符号的对齐方式,默认按照4字节对齐
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
                 IF      :DEF:__MICROLIB	;这里会判断是否定义了__MICROLIB,即表示是否使用MicroLib库,可以看仙女棒中是否勾选
                 EXPORT  __initial_sp		;如果使用MicroLib库,则给__initial_sp、__heap_base、__heap_limit给全局属性,可以让外部文件调用
                 EXPORT  __heap_base
                 EXPORT  __heap_limit
                 ELSE
                 ;如果没有使用MicroLib库,则使用双段存储器模式,并且声明__user_initial_stackheap全局属性,由用户自行初始化堆栈
                 IMPORT  __use_two_region_memory	
                 EXPORT  __user_initial_stackheap
                 ;以下就是没有使用MicroLib库,由用户自行初始化堆栈的程序
__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

配置使用MircroLib库

配置使用MircroLib库

本节内容中需要主要,后续使用的中断的时候,一定要检查中断服务子程序是否写错或者未定义,否则很容易出现中断服务程序无限循环的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/550805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聚观早报 | 小冰启动GPT克隆人计划;ofo创始人在美创业改做咖啡

今日要闻:小冰启动“GPT克隆人计划”;ofo创始人在美创业改做咖啡;OpenAI正准备新的开源AI模型;青年失业率首破20%创新高;微软收购动视暴雪获批 小冰启动“GPT克隆人计划” 5 月 16 日,小冰公司…

Spring Boot + Mybtis-plus集成

目录 需求分析Maven 相关依赖配置文件相关流程MybatisPlus配置自动补全参数配置逻辑删除注解乐观锁注解 需求分析 Spring Boot和MyBatis-Plus是目前使用最广泛的Java web开发框架和ORM框架,它们可以很好地协同工作,提供高效和稳定的系统开发和数据操作。…

[答疑]UML精粹里和你视频里说的不太一样

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> 第五元素 2023-4-14 20:32 这是是UML精粹里的。潘老师,这个跟你视频里讲的是不是不太一样?还是我理解错了? UMLChina潘加宇 这个&#…

软件最后一步------打包

本文章主要是记将源代码打包成程序 Python 一、安装Pyinstaller (用于打包的库) pip install pyinstaller二、使用参数 参数介绍 选项参数参数解释-hhelp(帮助信息)-vversion(版本号)-c显示命令行窗口-w不显示命令行窗口-F生成结果是一个exe程序,所有依赖项被打…

计算机的基本工作原理

参考资料: L-1.6: Common Bus system| How basic computer works - YouTube 准备好内存单元、不同类型的寄存器,内存和寄存器、寄存器和寄存器之间都是通过总线连接(假设是直接把数据总线、控制总线、地址总线变成一条总线)。 使用多路复用器实现的总线&…

C语言—通讯录

通讯录 通讯录的创建通讯录的初始化通讯录添加联系人信息通讯录删除特定联系人信息通讯录查找特定联系人信息通讯录修改特定联系人信息通讯录排序联系人信息通讯录打印联系人信息通讯录整体代码 通讯录的创建 通讯录中是存放人的信息的,人的信息包括:姓…

数据结构—排序算法交换排序(冒泡快排)

目录 1.交换排序—冒泡排序 1.1冒泡排序基本思想 1.2冒泡排序的实现 2.交换排序—快速排序 1.1快速排序基本思想 1.2基准值划分—分析 1. hoare版: 2. 挖坑法: 3. 前后指针版本 1.3 hoare快排的具体实现 1.4 挖坑法快排的具体实现 1.5 前后指…

【Stable Diffusion WebUI】一篇文章教你如何安装和使用Stable Diffusion WebUI

文章目录 Stable Diffusion WebUI1. 安装1.1 下载 stable-diffusion-webui1.2 运行 webui.sh 2. 安装插件2.1 命令行安装2.2 extensions 安装2.3 常用插件 3. 使用教程3.1 页面布局3.3 快捷栏设置3.3.1 PNG Info3.3.2 Tagger Stable Diffusion WebUI 1. 安装 1.1 下载 stable…

Python中的集合介绍

集合set是一个无序的、不可重复的元素集合。 集合的创建 大括号 {} set() a {1, 2, 3, 4, 5} print(type(a))b set([1,2,3,4,5,6,7]) print(type(b),b)c set((1,2,3)) print(c) 运行结果&#xff1a;<class set> <class set> {1, 2, 3, 4, 5, 6, 7} {1, 2, 3} 集…

诺贝尔化学奖:酶分子“定向进化”

2018年&#xff0c;诺贝尔化学奖迎来了历史上第五位女性得主——加州理工学院的Frances H. Arnold教授&#xff0c;以表彰她在“酶的定向进化”这一领域的贡献。 1、“酶的定向进化”到底是什么&#xff1f; 这里有三个点&#xff0c;“酶”、“进化”还有“定向”&#xff1a…

windows10安装Qt

一、下载安装包 1、安装包下载路径调整 由于Qt公司的调整&#xff0c;从5.15版本开始原本下载的路径不再提供安装包 Index of /archive/qt 新安装包放在了official_releases里面了 Index of /official_releases/online_installers 2、安装方式调整 从5.9.0开始安装方式开始…

streamlit应用部署和streamcloud发布APP

文章目录 streamlit应用创建streamcloud创建APP注册streamcloud账号设置StreamLit许可发布APPstreamlit应用创建 streamcloud创建APP StreamCloud是一个用于部署StreamLit App 的平台。 注册streamcloud账号 点击https://share.streamlit.io/ ,进入StreamCloud 注册界面。…

在四维轻云平台中如何使用场景搭建功能?

四维轻云是一款轻量化的地理空间数据管理云平台&#xff0c;能够实现多种地理空间数据的在线管理、编辑及分享。目前&#xff0c;平台具有项目管理、成员管理、场景搭建、在线分享、素材库等功能&#xff0c;支持多用户在线协作管理&#xff0c;实现了轻量化、便捷化的空间数据…

chatgpt赋能Python-pythonda

Python在SEO优化中的作用 简介 SEO&#xff08;Search Engine Optimization&#xff09;即搜索引擎优化&#xff0c;是指通过优化网站目标关键词的排名来提高网站的曝光率和流量。Python是一种高级编程语言&#xff0c;在SEO领域中有着广泛的应用。 Python在SEO中的应用 网…

AudioGPT推出!音频领域都不放过,ChatGPT这是杀疯了!

大家好&#xff0c;我是千与千寻&#xff0c;你们可以叫我千寻哥&#xff0c;算一算写ChatGPT的技术文章已经写到第四篇了&#xff01; 今天和大家介绍的一个项目属于音频领域的ChatGPT的应用实践。真没想不到&#xff0c;在音频领域&#xff0c;ChatGPT都没有放过&#xff0c…

maven聚合工程详解

目录 一、Maven继承二、idea搭建父子工程三、可继承的 POM 元素四、Maven聚合五、idea搭建聚合工程六、继承和聚合的关系七、dependencyManagement八、pluginManagement 本篇文章重点针对这几个问题进行讲解&#xff1a; Maven继承使用IDEA搭建Maven父子工程使用IDEA搭建Maven…

【建议收藏】Python自动化必不可少的测试框架 — pytest

每天进步一点点&#xff0c;关注我哦&#xff0c;每天分享测试技术文章 Python在测试圈的应用非常广泛&#xff0c;特别是在自动化测试以及测试开发的领域&#xff0c;其中在自动化测试中我们常用的测试框架是uniitest和pytest&#xff0c;本文将带领大家搭建以及熟悉pytest的使…

改进YOLOv5系列:ResNeXt融合特征金字塔,引领YOLOv5目标检测

目录 一、介绍1、YOLOv5简介2、ResNeXt简介3、目标检测简介 二、YOLOv5及其局限性1、YOLOv5的架构与原理2、YOLOv5的优势3、YOLOv5的局限性 三、ResNeXt与特征金字塔融合1、ResNeXt的基本原理2、ResNeXt的优势3、特征金字塔的基本原理4、特征金字塔的优势5、ResNeXt与特征金字塔…

mysql JDBC的三种查询(普通、流式、游标)

使用JDBC向mysql发送查询时&#xff0c;有三种方式&#xff1a; 常规查询&#xff1a;JDBC驱动会阻塞的一次性读取全部查询的数据到 JVM 内存中&#xff0c;或者分页读取流式查询&#xff1a;每次执行rs.next时会判断数据是否需要从mysql服务器获取&#xff0c;如果需要触发读…

找计算机研究的论文18个平台

虽然说目前arvix是计算机领域跟进最新研究成果论文的网站&#xff0c;有时候我们也需要找一些其他的好论文&#xff0c;比如一个很久之前的。我们整理了18个相关平台&#xff0c;包括几个可以免费下载和阅读CS相关技术论文的网站&#xff0c;收录到 找计算机研究的论文18个平台…