STM32
登录
直播中
贺楠
7年用户
927经验值
私信
关注
[问答]
怎样去使用startup_stm32f40_41xxx.s启动文件的各个模块呢
开启该帖子的消息推送
stm32f40x
启动文件
模块
startup_
STM32
f40_41xxx.s各个模块的主要作用是什么?
怎样去使用startup_stm32f40_41xxx.s启动文件的各个模块呢?
回帖
(1)
h1654155275.5842
2021-11-26 15:17:14
STM32 官方为广大开发者提供一套统一开发固件,主要是屏蔽寄存器封装,提供初始化等功能,较少开发者负担。只需要调用相关模块封装,对相关结构提初始化即可,较少开发调试时间。本次主要以官方STM32F4xx_DSP_StdPeriph_Lib_V1.8.0固件版本为主,主要讲解各个模块主要作用以及使用方法,固件主要结构将在后面做介绍
本次主要讲解开发过程中大家都会忽略的STM32 启动文件流程,STM43 启动文件名为startup_stm32f40_41xxx.s,其目录在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0LibrariesCMSISDeviceSTSTM32F4xxSourceTemplatesarm,也可以按照整个文件名搜索整个固件,会发现有很多相同文件分布在不同目录,主要是因为官方固件提供很多开发样例,每个样例都需要进行启动文件,官方提供用例在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0ProjectSTM32F4xx_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_DSP_StdPeriph_Lib_V1.8.0固件版本为主,主要讲解各个模块主要作用以及使用方法,固件主要结构将在后面做介绍
本次主要讲解开发过程中大家都会忽略的STM32 启动文件流程,STM43 启动文件名为startup_stm32f40_41xxx.s,其目录在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0LibrariesCMSISDeviceSTSTM32F4xxSourceTemplatesarm,也可以按照整个文件名搜索整个固件,会发现有很多相同文件分布在不同目录,主要是因为官方固件提供很多开发样例,每个样例都需要进行启动文件,官方提供用例在STM32F4xx_DSP_StdPeriph_Lib_V1.8.0ProjectSTM32F4xx_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工具中进行勾选,如下所示:
举报
更多回帖
rotate(-90deg);
回复
相关问答
stm32f40x
启动文件
模块
startup_stm32f40_41xxx.s
启动
文件
是
怎样
运行的
2021-11-26
755
startup_stm32f40_41xxx.s
启动
代码分析,不看肯定后悔
2021-11-29
760
分析
stm32
启动
文件
2021-11-29
900
怎样
去
分析
startup_stm32f10x_md.s
启动
文件
的源码
呢
2021-11-26
790
怎样
去
选择一种适合
STM32
芯片的
STM32F10x.s
启动
文件
呢
2021-11-29
878
startup_stm32f10x_hd.s
启动
文件
有何功能
呢
2022-01-19
603
startup_stm32f10x_hd.s
启动
文件
有何功能
呢
2021-11-26
1252
STM32F
4寄存器开发指南
2021-11-29
1117
startup_stm32f2xx.s
文件
的
启动
流程是
怎样
的?
2021-11-29
908
如何
去
编写
startup_stm32f10x_hd.s
启动
文件
的代码
呢
2021-11-26
1438
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分