STM32__main代码分析

发布者:WanderlustGlow最新更新时间:2019-03-08 来源: eefocus关键字:STM32  main  代码分析 手机看文章 扫描二维码
随时随地手机看文章

STM32启动代码主要是分配堆栈及设置向量表,然后跳转到__main函数。

跳转具体到代码段部分如下:


[cpp] view plain copy

  1. Reset_Handler   PROC  

  2.                 EXPORT  Reset_Handler             [WEAK]  

  3.                 IMPORT  __main  

  4.                 LDR     R0, = __main  

  5.                 BX      R0  

  6.                 ENDP  


当您看到__main函数时,估计应该有不少人认为这个是main函数的别名或是编译之后的名字,否则在启动代码中再也无法找到和main相关的字眼了。可事实是,__main和main是完全两个不同的函数,并且你无法找到__main代码,因为这个是编译器自动创建的。

     

查看MDK的文档,会发现有这么一句说明:It is automatically created by the linker when it sees a definition of main()。简单点来说,当编译器发现定义了main函数,那么就会自动创建__main。

 

程序经过汇编启动代码,执行到__main()后,可以看出有两个大的函数:

__scatterload():负责把RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作。

__rt_entry():负责初始化堆栈,完成库函数的初始化,最后自动跳转向main()函数。

 

分析__scatterload()函数

执行到__main(),先跳转到_scatterload下图红框框中代码所示,执行完后,R10和R11就被赋给成了下面两个值。


Map文件中的symbol








然后执行_scatterload_null代码,将R10对应地址存放的的4个字copy到R0~R3中,可以看出

R0:0x1000表示的是keyled.o加载域起始地址

R1:0x30000100为keyled.o运行域地址

R2:0X160为copy的大小,keyled.o的大小从map文件中得知就是0x160 Byte

R3:0X1E4 是_scatterload_copy 代码的起始地址,实用BXR3 就能跳转到_scatterload_copy来复制代码。

 



跳到_scatterload_copy,开始copy,循环0x16次,每次搬移4个字(16Byte),共搬移0x16*0x10=0x160





复制完keyled.o代码后,进一步循环到_scatterload_null准备好,ZI段需要清零的地址和范围

执行完这个循环后

R1:0x30050000 为ZI段的起始地址

R2:0x618为ZI段大小,换成十进制是1560.从map文件得知ZI大小就是1560Byte

R3:0x20c 为_scatterload_zeroinit 的地址





执行下面红框框中循环体,共清零0x610Byte范围,然后再执行蓝框框中代码,清零8Byte,总共0x618

ZI段清零(0x30050000~0x30050618)





然后使用BX R14跳转到0x000001BC处,顺序执行到BL  __rt_enty 指令

成功跳转到__rt_enty函数


 


分析__rt_entry()函数

先调用__user_setup_stackheap()函数来建立堆栈





可以看出在这个函数中,会执行到BL__user_initial_stackheap()函数,这样也就明白了,为什么使用分散加载文件,需要设置__user_initial_stackheap这个函数来设置堆栈空间。



关键字:STM32  main  代码分析 引用地址:STM32__main代码分析

上一篇:STM32之RCC原理
下一篇:STM32分散加载文件

推荐阅读最新更新时间:2024-03-16 16:25

STM32移植Marlin固件
marlin入口函数为loop所以沿着loop函数一步一步分析 get_command(); //读取串口接收到的数据根据 n和*来读取到一个完整的命令并保存在combuffer中 process_commands() { -----code_seen('G') //查看当前命令中有没有G这个代码 -----get_coordinates() //获取命令中XYZF字符后面的值并保存在Destinatio 和feedrate变量 -----prepare_move() //根据get_coordinates()获得的值和之前设定好的一些变量来控制步进电机
[单片机]
STM32 NVIC 中断
***************************** STM32 NVIC 中断 一、STM32 的中断分组:STM32 将中断分为 5 个组,组 0~4。该分组的设 置是由 SCB- AIRCR 寄存器的 bit10~8 来定义的。具体的分配关系如表所示: 组…,…,. bit 分配情况 …,…,…,…分配结果 0 …,…,…,…,…,…0:4 …,…,…,…0 位抢占优先级,4 位响应优先级 1 …,…,…,…,…,…1:3 …,…,…,…1 位抢占优先级,3 位响应优先级 2 …,…,…,…,…,…2:2 …,…,…,…2 位抢占优先级,2 位响应优先级 3…,…,…,…,…,…3:1…,…,…,… ,3 位抢占优
[单片机]
STM32大行当道,Microchip却集中发布60余款8位MCU
为满足对 8 位微控制器 (MCU) 的需求,Microchip 一下子推出了 5 个新系列、超过 60 款器件,涵盖PIC 和 AVR。 嵌入式设计正成为电子产品越来越流行和重要的元素。就目前而言,您可以在市场上的绝大多数电子和消费设备中找到 MCU。 支持种类繁多的嵌入式设备需要一个多功能的市场,提供满足大多数应用需求的产品。为了满足这一需求,Microchip 最近发布了五个全新的 8 位 PIC 和 AVR MCU 系列,总计超过 60 款器件。 在本文中,我们将介绍 8 位 MCU,它们为何如此重要,以及 Microchip 的五个新系列带来了什么。 单片机位宽 由于 MCU 可用于许多不同的应用,因
[单片机]
<font color='red'>STM32</font>大行当道,Microchip却集中发布60余款8位MCU
用FPGA搭建一个STM32内核?
1.必要的基础知识 为了更快的完成在FPGA上实现ARM Cortex-M3软核,一些必要的基础知识还是要有的! FPGA开发基础知识,如FPGA开发流程,设计、综合、布局、布线、约束、下载 Xilinx Vivado开发环境使用基础,如BlockDesign设计方式,管脚分配,Bit流文件生成与下载 ARM Cortex-M3内核的使用基础,如STM32、MM32、GD32、CH32等微控制器的开发。 Keil-MDK开发环境的使用基础,基本的工程建立、编译、下载流程。 如果以上知识都具备,那么,恭喜你!可以在2小时内完成ARM Cortex-M3软核在FPGA上的实现。 2.Cortex-M3 FPGA IP核下载 首先,
[单片机]
用FPGA搭建一个<font color='red'>STM32</font>内核?
stm32按键轮循点灯
一、实验描述及工程文件清单 1.实验描述: 按键-引脚连接:KEY1-PC5 KEY2-PC2 KEY3-PC3 LED-引脚连接:LED1-PB5 LED2-PD6 LED3-PD 用扫描的方式查询是否有按键按下:key1按下时,LED1状态取反;key2按下时,LED2状态取反;KEY3按下时,LED3状态取反。 3.库文件、用户文件: 4.USER文件: main.c、led.c、key.c、stm32f10x_it.c 二、这是我的流程图 三、代码编写 1.main.C /********************************************
[单片机]
<font color='red'>stm32</font>按键轮循点灯
stm32 大容量芯片烧录出错
在烧录stm32f103vet6 的时候总是出错。 生成代码量相对芯片的容量不是很大,芯片是512K的flash,64K 的RAM 生成的代码大约32K MDK的配置是 full erase chip ,program verify reset and run 每次烧录的一定的时候就会停止响应, 解决方案一: 烧录之前先整体擦除,然后烧录 解决方案二: MDK的配置改成扇区擦除,如下图: 这个样子烧录可以成功,但是MDK大部分情况下无法显示进度条。 应该是个bug!!!!
[单片机]
<font color='red'>stm32</font> 大容量芯片烧录出错
STM32学习笔记之以太网的通信+lwip协议移植
STM32F107自带 MAC控制器 而有的芯片把Mac和PHY坐到一起了,像ENC28J60 以太网通信 依据 TCP/IP协议是 LWIP协议,这个LWIP 协议是可以运行在STM32上面的。 STM32F107为以太网外设专门做的库直接下载对应的demo 可能协议版本不一样,下载运行即可。 主要有几个部分说明一下 1、修改 ethernetif.c 包含了与以太网网卡密切相关的初始化、发送、接收等函数的实现。这个文件夹中的函数并不能使用,它们都是一个框架性的结构,移植者需要根据自己使用的网卡特性来完成这些函数。 2、mem管理 使用系统堆内存管理或者使用自定义内存管理(类
[单片机]
STM32单片机学习(3) 串口中断通信
/* * * 软件功能: 串口实验(软件延时方式) * */ #include stm32f10x.h #include string.h #include delay.h u8 uart1_buf ; int count=0; //字符串长度 int flag=0; void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void USART1_Configuration(void); void Uart1_PutChar(u8 ch); void Uart1_PutString(u8* buf
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved