STM32 启动代码 __main 与用户主程序 main() 的区别

2019-04-01来源: eefocus关键字:STM32  启动代码  用户主程序

1、__main 作用

__main函数是C/C++运行时库的一个函数,嵌入式系统在进入应用主程序之前必须有一个初始化的过程,使用__main标号引导系统时必须将应用程序的入口定义为main()。
    
在初始化的过程中,__main函数的作用主要有两点:


1) 完成对映像文件的初始化操作

a、映像文件

链接器把多个目标文件链接成一个映像文件。

b、加载地址和执行地址

映像文件可以有两种地址:加载地址和执行地址。

加载地址是映像文件在存储器中的存储地址;执行地址就是映像文件运行时的地址。

c、加载域和执行域

文件加载的存储区叫加载域,文件运行的存储区叫执行域。

d、从加载地址到执行地址

在结构比较简单的系统中,加载地址就是执行地址;

而在复杂系统中,程序运行前,常常会把映像文件的一部分或全部从存储区域移出去,此时执行地址就不再是加载地址。

知道以上几个概念,__main函数对映像文件的初始操作就不难理解了。

对于加载地址和执行地址不同的映像文件,__main函数会把加载地址的代码和数据复制到执行地址中,并且对被链接器指定为需要初始化为0的段,进行清零操作。


2) 调用__rt_entry函数,进入用户程序。

__rt_entry函数的运行流程如图:



 2、进入主程序

当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序,即呼叫主应用程序。

最简单的一种情况是:

IMPORT mainB main

直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。

在ARM ADS环境中,还另外提供了一套系统级的呼叫机制。

IMPORT __mainB __main


__main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。


所以说,前者是库函数,后者就是我们自己编写的main()主函数;


因此我们用的B __main其实是执行库函数,然后该库函数再调用我们的main() 函数,因此在单步调试时会看到先要跑一段程序(其实是库函数),然后再单步到我们自己的main函数(这个同时也说明如果有B __main 则就对应必须有main函数,否则编译出错);


如果我们用 B main来进入我们的主函数的话,那在单步调试时就看到直接进入到我们自己的main函数了,中间不会看到其他程序;


那么用B __main和用B main 这两这进入我们的main函数方式有什么不同呢?

如果采用前者则会由编译器加入一段"段拷贝"程序,即我们说的从加载域到执行域转化程序;而采用后者就没有这个了;


因此如果要进行 "段拷贝"只能自己动手编写程序来实现了,完成段拷贝后就可以进入我们的主函数了,当然这个主函数不一定是叫做main(),可以起个其他好听的名字,这个有别于使用B __main方式;不管采用哪种方式进入我们的程序,都要有一段"段拷贝"程序,跑完了段拷贝后才能可以进入我们主程序了。


startup.s 这个文件并没有所谓的"段拷贝"功能。


对含有启动程序来说,"执行地址与加载地址相同"不容易实现:


如果执行地址与加载地址相同哪当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main 的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了.因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM等.因此,对含有启动程序来说,"执行地址与加载地址相同"就不容易实现;程序的入口点在C 库中的__main 处,在该点,库代码执行以下操作:

1)将非零(只读和读写)运行区域从其载入地址复制到运行地址。

2)清零ZI 区域。

3)跳转到__rt_entry。


关键字:STM32  启动代码  用户主程序 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/2019/ic-news040143663.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 启动代码汇编指令详解
下一篇:STM32 分散加载文件 .sct 解析

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32MxCube配置串口
基于上一次将第一章:STM32MxCube 基本使用方法,本章直接讲叙述STM32配置串口2的。查看STM32F407电路图:可得USART2接在PA2、PA3。下面新建STM32MxCube工程,开始配置。这里我们配置IO(定义PF9、PF10引脚为LED)、RCC(使用HSE)、USART(串口)。配置USART(串口)USART的配置有好几种,也是最常见的一种”UART异步串行通信”配置来讲述。选择USART2模式为“asynchronous”(异步通信)对应的引脚自动转换为USART。对于系统时钟应该都知道它的作用,就是驱动整个芯片工作的心脏,如果没有了它,就等于人没有了心跳。时钟的快慢也就决定了程序的快慢。STM32
发表于 2020-05-04
STM32MxCube配置串口
STM32CubeMX学习教程之一:GPIO输出之跑马灯
完整源码下载:https://github.com/simonliu009/STM32CubeMX-GPIO-Control软件版本:STM32CubeMX V4.25.0 System Workbench V2.4固件库版本:STM32Cube FW_F1 V1.6.1硬件:OneNet 麒麟座V2.3在STM32CubeMX中新建项目,选择正确的MCU型号首先设置RCC和SYS,如下图然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图GPIO设置 PC7, PC8, PA12和 PC10为GPIO_OUTPUT, (这是麒麟座V2.3的四个LED管脚),如下图
发表于 2020-05-04
STM32CubeMX学习教程之一:GPIO输出之跑马灯
STM32CubeMX学习--(3)串口通信
Cube配置USART配置在Connectivity中选中USART1MODE = AsynchronousHardware Flow Control = DisableParameter Settings中配置Baud Rate = 115200Word Length = 8bitParity = NoneStop Bits =1Data Direction = Receive and TransmitOver Sampling = 16 SamplesNVIC Setting勾选Enable,Preemption Priority =2生成代码修改代码生成代码后,即可使用HAL_UART_Transmit_IT(&
发表于 2020-04-29
STM32CubeMX系列教程 5.0版本环境开发——2.Uart串行通信功能
;                         PS:在明白原理的情况下建议自己手写一次模拟UART。明白了之后,代码重复的事就由STM32芯片的硬件功能来实现就可以了,你只需要会看逻辑分析仪或者示波器分析数据便可。 所谓硬件功能 就是你把数据填充到寄存器,然后配置好相关参数,他会自动帮你发送出去。通俗点说,自己手写整个协议代码实现实现就像你自己把一个快件送到到别人那里再回来,而硬件功能则是你把快件给快递员,快递员帮你送过去。  明显 后者会帮你节省大量时间和精力。它是一个硬件组成,并且你也为此付费
发表于 2020-04-29
STM32CubeMX系列教程 5.0版本环境开发——2.Uart串行通信功能
串口通信(用CubeMX学习STM32)
前言: STM32串口介绍串行通信是单片机与外部设备或其他计算机交换信息的一个方式, 数据一位一位的按顺序传送, 其优点是只需要一条传输线, 协议简单, 但是缺点就是传送速度较慢。串口是单片机上非常便捷的一个工具, 当写程序需要调试的时候, 它可以很方便的提供调试方法, 只要在一些关键代码执行的地方, 通过串口给串口调试助手发送相关信息, 就可以使我们很方便的查看代码在这个位置的执行情况。下面看一下我所使用的单片机上串口的原理图接线外部的发送端TXD就是单片机串口的接收端USART_RX,   外部接收端RXD就是单片机串口的发送端USART_TXTXD : Transmit(TX) Data(D)  Receive(RX
发表于 2020-04-29
【STM32CubeMX】 串口通信(USART) Printf重定向
STM32CubeMX: Version 4.26.1MDK-ARM: Version 5.24.2开发板: 中移onenet 麒麟座MINI板芯片: STM32F103CBT61.STM32CubeMX设置设置外部时钟源设置Debug设置串口 使用USART1 PA9,PA10设置时钟频率设置USART1详细参数生成MDK-ARM工程2.重定向Printf 及 Scanf主要用到两个函数HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout
发表于 2020-04-29
【STM32CubeMX】 串口通信(USART) Printf重定向
小广播
何立民专栏 单片机及嵌入式宝典

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

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