005 - STM32学习笔记 - 启动代码

news2024/12/23 0:47:55

005 - STM32学习笔记 - 启动代码

常用汇编指令

指令名称作用
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/564192.html

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

相关文章

【ChatGPT】ChatGPT自动生成思维导图

参考视频:https://edu.csdn.net/learn/38346/613917 应用场景:自学,“研一学生如何学习机器学习”的思维导图 问:写一个“研一学生如何学习机器学习”的思维导图内容,以markdown代码块格式输出 # 研一学生如何学习…

探索人工智能和机器学习的前沿趋势

🌟 深度学习的突破🌟 强化学习的进展🌟 可解释性和公平性的挑战(1000字)🌟 自动化和智能化的未来(1000字) 在当今科技飞速发展的时代,人工智能(Artificial In…

全网最牛最前面的浦发银行软件测试面试题精讲分析

面试永远都是软件测试人重点关注的问题,最近也总有很多想去银行面试的小伙伴来问我,有没有什么方法技巧传授一下。 那今天就给大家总结一些浦发银行的面试题,小伙伴们可以看看如果是自己能不能流畅地回答上来这些面试题。 1、说说你们公司测…

c++积累12-const

1、文件作用域-const修饰变量默认为文件局部变量 注意:非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定它为extern。 1) 未被const修饰的变量在不同文件的访问 可以看到是能够默认不加const是可以正常访问的 2) …

某大型啤酒企业:构建网络安全软实力,首选Coremail反钓鱼演练

客户背景 某大型啤酒厂商的公司规模和市场份额多年来始终都处于行业领先地位,积极赞助多项体育赛事,持续丰富和提升品牌形象。作为一家具有全球影响力的企业,自然也成为了全球黑客等攻击团伙的重点目标,而系统攻击的开端便是钓鱼…

什么是产品路线图?如何做产品路线图规划

产品路线图规划 •产品路线图是一个高层次的战略计划,它描述了产品在未来一段时间可能会如何发展和壮大,产品路线图确保整个产品团队持续关注产品的目标,帮助产品负责人把握产品的战略方向,调整产品的优先级和产品规划。 里程碑…

轻松打造智能化性能测试监控平台:【JMeter+Grafana+Influxdb】的优化整合方案

目录 【引言】 【背景说明】 【实现原理】 【平台搭建】 方法一:Windows或macOS环境下搭建 1.InfluxDB安装 2.grafana安装 3.jmeter配置 方法二:Linux环境下搭建 1.influxdb安装 2.grafana安装 3.jdkjmeter安装 方法三:docker容…

L1-093 猜帽子游戏

宝宝们在一起玩一个猜帽子游戏。每人头上被扣了一顶帽子,有的是黑色的,有的是黄色的。每个人可以看到别人头上的帽子,但是看不到自己的。游戏开始后,每个人可以猜自己头上的帽子是什么颜色,或者可以弃权不猜。如果没有…

python接口自动化测试之unittest自动化测试框架基本使用

目录 unittest简单介绍 unittest基础使用 unittest.Testcase setUp tearDown setUpClass tearDownClass 测试用例 unittest.main() unitteest提供的各种断言方式 unittest测试用例跳过执行 跳过执行测试用例共有四种写法 self.skipTest(reason) 跳过执行测试用例注…

手动搭建一个简单的MVVMLight框架的方法

本章讲述:手动搭建一个简单的MVVMLight框架步骤: 1、下载MVVMLight所需要的dll库文件 主要文件包括:CommonServiceLocator.dll、GalaSoft.MvvmLight.dll、GalaSoft.MvvmLight.Extras.dll、GalaSoft.MvvmLight.Platform.dll、System.Windows.…

小兔新--项目实战总结1

目录 Layout-吸顶导航交互实现 吸顶交互 vueUse Layout-Pinia优化重复请求 为什么要优化 如何优化 Home-懒加载指令优化 场景和指令用法 实现思路和步骤 回顾核心步骤代码 Home-懒加载指令优化 问题1:逻辑书写位置不合理 问题2:重复监听问题 一级分类-解决路由缓存问…

Web基本与HTTP协议

目录 一:域名 1.域名概述 2.域名空间结构 3. 域名注册 二: 网页访问(HTTP/HTTPS) 1.网页的基本概念 2.网站 3.主页 4.域名 5.HTTP 6.URL 7.网页基本标签 (1)网页摘要信息的作用 (…

Oracle SQLTUNING优化SQL

通过AWR的TOPSQL观察到sqlid为6pk9xfmjd0s8j的sql语句耗时1分钟。 通过ash观察到,该SQL由于全表扫描占用了大量的IO资源。 解析执行计划,看到是MED_SALE_ORDER表做了全表扫描。 该表有678W条记录,全表扫描必定IO指标会冲高,影…

SFM过程(一)

以图像为基础的三维重建过程SFM基本如下图所示&#xff1a; 以SfM-Toy-Library代码为例&#xff0c;如下&#xff1a; ErrorCode SfM::runSfM() {if (mImages.size() < 0) {cerr << "No images to work on." << endl;return ErrorCode::ERROR;}//in…

Java-网络原理

目录 一、网络互连 局域网LAN 广域网WAN 二、网络通信基础 IP地址 端口号 认识协议 三、五元组 四、协议分层 五、OSI七层模型 六、TCP/IP五层&#xff08;或四层&#xff09;模型 网络分层对应 七、封装和分用 一、网络互连 随着时代的发展&#xff0c;越来越需要计…

Smartbi电子表格故事之用数据进行销售问题分析

天津小麦商贸有限公司&#xff08;X&M&#xff09;成立于2012年11月&#xff0c;主营业务是商贸流通业&#xff0c;主要是日用商品的批发销售。 2012年前&#xff0c;公司创始人&#xff08;总经理和销售总监&#xff09;一直从事外贸的生意&#xff0c;自从2008年金融危机…

java 课程信息管理系统Myeclipse开发mysql数据库struts2结构java编程计算机网页项目

一、源码特点 java 课程信息管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0c;使…

Scrum的执行过程及产品Backlog梳理的目的、时间、内容

Scrum的迭代运行过程 产品Backlog梳理 目的&#xff1a; •对下个Sprint的需求进行需求细节梳理和精化&#xff0c;识别技术风险和依赖&#xff0c;完成估算和优先级排序。 时间&#xff1a; •本Sprint开始后第6天&#xff0c;2小时以内 。 内容&#xff1a; •理解需求…

2020下半年

2020下半年 d a b 小阶向大阶对齐 b b 平均cpi: MIPS: d c 公加验&#xff0c;私解签 加密防止被动攻击&#xff0c;认证防止主动攻击 a 访问控制包括&#xff1a;授权&#xff0c;确定存取权限&#xff0c;实施存取权限 c a c a 先申请先得 b b 著作权包括&…