0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32芯片的工程代码问题

strongerHuang 来源:茶话MCU 作者:Miler 2021-11-16 09:20 次阅读

基于STM32芯片的工程代码里有个很重要的文件,即启动文件。该文件主要由汇编语言写成,文件名冠以.s结尾,它是芯片程序运行首先要执行的一个文件。其功能及作用简单点说就是做执行用户程序前的基本准备,比方执行复位程序初始化栈、堆,做时钟系统的默认配置、中断矢量表的定义与分配等。

网络上有些文章对该文件做了不错的整体性介绍,这里仅就该文件中的几个小问题一起交流分享下。【注:下面用到的工程是基于STM32F429的,使用IDE为ARM MDK】

怎么在编译后的MAP文件里看不到变量__heap_base?

有人发现在启动文件里明明有定义__initial_sp和__heap_base,可在MAP文件里只看到__initial_sp的地址安排,却死活找不到__heap_base的影子。为什么呢?

这是因为我们目前的工程代码里没有涉及到堆操作。虽然启动文件里有针对HEAP的配置,但由于代码里实际上没用到堆,编译时候就没分配堆的地址相关信息,自然在MAP文件里找不到__heap_base。

以上图为例,其实此时Heap_Size写多大是没啥实际意义的,写0x200和写0没差别。这就像我们在代码定义一些完全不会被用到的变量一样,编译时是不会被安排内存空间的。

然而,如果我们在代码里有涉及HEAP操作,若启动文件里的HEAP配置依然如上图所示,那情况就不一样了。比方我们在用户代码做动态内存分配,这里使用malloc函数进行动态内存分配示例下。

这时我们再去查看MAP文件,就可看到堆的地址信息了,跟启动文件里分配的一致。顺便提醒下,我们在用户代码里做内存动态分配时注意分配的空间大小要遵循启动文件里预设的HEAP大小限制,必要时需做适当调整。

启动文件里怎么用掉了1KB的RAM

有人在查看STM32程序代码编译后的MAP文件时,发现启动文件就用掉了1024B的RAM,如下图所示。觉得有点奇怪,想知道这1KB用到哪里去了?是不是固定的?

我们知道启动文件主要基于汇编写成,实现些最基本的软硬件初始化工作,似乎用不到这么多RAM。

其实,这里1KB初始值为0的RAM,是安排给栈用的,而这个栈大小的配置就是在启动文件里实现,但并非仅限于用在启动文件里。MAP文件里显示的启动文件所用ZI数据大小,跟下面栈配置是关联的。

显然,这个RAM开销并非固定的。

尽管我们建立工程时可能有些默认配置或经验配置,但我们完全可以结合自身工程代码的需要灵活调整。如果说,代码里函数调用涉及到的局部变量较少、中断嵌套情形也不多,你完全可以将栈数据设计得小些,或许很多时候512B【0x200】都绰绰有余了。总之,这个数据不是固定不变的,具体开发时按需调整。

比方,我将上面的栈空间大小改为512B,再看看编译后的结果。那个ZI Data大小也随之而变了。

上面是基于栈空间大小的调整来解释启动文件里ZI数据的大小变化。如果说我们的代码里还用到堆,这时启动文件里的ZI数据就不仅仅是栈空间大小的数据了,还会包括堆空间的大小。比方,我们在代码里启用动态内存分配使用到堆。在启动文件里对堆、栈的配置如下:

按照上面配置并启用动态内存分配,再去查看编译结果,基于启动文件所用到的ZI数据大小变成了栈与堆空间二者之和。如下图所示【1024+512=1536】:

启动文件里的RO Data是怎么产生的?

有人在查看MAP文件时,发现启动文件里产生了一批RO只读数据,如下图所示:

上图是基于STM32F429的工程编译后产生的,那个428 Bytes只读数据怎么来的?

其实,这个数据就是存放中断向量地址表所用到的,不同的系列这个数据会有差异。该向量表除了第一个字单元存放MSP栈顶地址外,其它均为系统异常或中断入口地址,作为常量数据存放在FLASH里。我们具体看看这里的428B怎么来的。打开启动文件,我们可以看到一串连续的DCD操作,如下图所示:

以STM32F429为例,在启动文件里稍微数数可得知这里共有107个地址入口项,每项用到一个4字节字,刚好对应上面的428 Bytes.

启动文件里的__main函数跟用户的main()有关系吗?

我们知道,启动文件的主要功能就是为用户程序的正常运行做最基本的初始化准备工作,__main()函数就是完成该使命的重要一环。它是一个C库初始化函数入口,主要负责执行一些必要的代码及数据从装载区到执行区的拷贝,将ZI内存区的数据初始化为0。对C库函数进行初始化,初始化堆、栈等,有时还可能包括一些代码解压操作,最后跳转至用户man()函数运行用户程序。

一般来讲,关于这个__main()函数的功能及作用大致了解就好,通常将其视为黑盒子。

启动文件里对中断矢量表起始地址进行初始化是在哪里实现的?

在STM32 MCU家族里,除了基于Cortex M0内核的STM32F0系列外,都有个中断矢量寄存器【SCB-》VTOR】用来初始化中断矢量表的起始地址。它的初始化一般在启动文件的复位程序里的SystemInit()函数完成。

最后基于该话题顺便给些提醒作为本篇结尾。我们在基于STM32芯片做IAP应用时,对于APP代码记得做好VTOR的重定位【注:F0系列操作例外】;在从BOOT区跳转到APP区之前先将刚才开启过的所有中断使能都禁用掉;如果开启了Cache的话,也将Cache禁用掉;保证跳转时清清爽爽,不捎一滴水,不带一片云。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2232

    文章

    10650

    浏览量

    347876
  • 变量
    +关注

    关注

    0

    文章

    588

    浏览量

    28087

原文标题:关于STM32启动文件的几个小问题

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32移植而引发的两个小疑问

    STM32用户将基于STM32F0芯片代码移植到STM32F4系列时遇到了些麻烦。其中有个问题跟中断处理有关。有个中断服务程序
    的头像 发表于 11-18 14:12 461次阅读
    因<b class='flag-5'>STM32</b>移植而引发的两个小疑问

    ROS与STM32串口通信代码

    这里以一个智能车代码工程为例,抽取串口通信部分代码 在头文件中,进行串口头文件的包含 # include 在类的定义中,什么一个 serial 类的实例 serial::Serial
    的头像 发表于 11-17 18:10 412次阅读

    MCU(STM32F767IGTX)上电启动后执行的代码分析

    这一节,我们来看一下MCU(STM32F767IGTX)上电启动后执行的代码,也就是常说的启动代码。上一节里我们已经讲过了CubeIDE工程的启动
    的头像 发表于 11-06 15:04 384次阅读

    利用Simulink自动生成STM32串口代码

    功能:利用Simulink自动生成STM32串口代码,在Keil中编译后直接下载到主芯片,实现串口通讯的功能。
    的头像 发表于 10-25 17:04 855次阅读
    利用Simulink自动生成<b class='flag-5'>STM32</b>串口<b class='flag-5'>代码</b>

    STM32CubeMX的配置和C代码的生成

    电子发烧友网站提供《STM32CubeMX的配置和C代码的生成.pdf》资料免费下载
    发表于 09-20 09:53 4次下载
    <b class='flag-5'>STM32</b>CubeMX的配置和C<b class='flag-5'>代码</b>的生成

    STM32L4、STM32L4+和STM32G4系列微控制器上的专利代码读取保护

    电子发烧友网站提供《STM32L4、STM32L4+和STM32G4系列微控制器上的专利代码读取保护.pdf》资料免费下载
    发表于 09-19 16:16 0次下载
    <b class='flag-5'>STM32</b>L4、<b class='flag-5'>STM32</b>L4+和<b class='flag-5'>STM32</b>G4系列微控制器上的专利<b class='flag-5'>代码</b>读取保护

    用户代码移植到STM32芯片时发生非对齐错误怎么办

    为什么基于Cortex-M3/M4的STM32芯片组织的用户代码移植到基于Cortex-M0/M0+的STM32芯片时为何可能会发生非对齐错
    的头像 发表于 09-09 15:48 964次阅读
    用户<b class='flag-5'>代码</b>移植到<b class='flag-5'>STM32</b><b class='flag-5'>芯片</b>时发生非对齐错误怎么办

    STM32L4、STM32L4+和STM32G4系列微控制器上的专利代码读取保护

    电子发烧友网站提供《STM32L4、STM32L4+和STM32G4系列微控制器上的专利代码读取保护.pdf》资料免费下载
    发表于 08-01 10:03 0次下载
    <b class='flag-5'>STM32</b>L4、<b class='flag-5'>STM32</b>L4+和<b class='flag-5'>STM32</b>G4系列微控制器上的专利<b class='flag-5'>代码</b>读取保护

    stm32中使用mlx90614的驱动代码

    关于stm32中使用mlx90614的驱动代码
    发表于 06-25 10:07 0次下载

    STM32启动文件startup_stm32f10x_hd.s的代码讲解

    本文对STM32启动文件startup_stm32f10x_hd.s的代码进行讲解,此文件的代码在任何一个STM32F10x
    的头像 发表于 06-22 10:31 2401次阅读
    <b class='flag-5'>STM32</b>启动文件startup_<b class='flag-5'>stm32</b>f10x_hd.s的<b class='flag-5'>代码</b>讲解

    详解STM32启动文件

    本文对STM32启动文件startup_stm32f10x_hd.s的代码进行讲解,此文件的代码在任何一个STM32F10x
    发表于 06-10 17:19 682次阅读
    详解<b class='flag-5'>STM32</b>启动文件

    基于STM32单片机ADC使用库文件设计源代码

    基于STM32单片机ADC使用库文件设计源代码
    发表于 04-26 15:07 4次下载

    基于STM32单片机DMA使用库文件设计源代码

    基于STM32单片机DMA使用库文件设计源代码)
    发表于 04-26 15:03 1次下载

    基于STM32单片机SD卡使用库文件设计源代码

    基于STM32单片机SD卡使用库文件设计源代码
    发表于 04-26 14:27 1次下载

    基于STM32单片机SPI使用库文件设计源代码

    基于STM32单片机SPI使用库文件设计源代码
    发表于 04-26 14:26 4次下载