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
    +关注

    关注

    2270

    文章

    10918

    浏览量

    356833
  • 变量
    +关注

    关注

    0

    文章

    613

    浏览量

    28433

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

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

收藏 人收藏

    评论

    相关推荐

    stm32低功耗设计技巧

    多个系列和型号可供选择,其中一些专门设计用于低功耗应用。 例如,STM32L系列芯片采用超低泄漏工艺,具有领先的处理性能和代码密度,以及多个动态可选电压范围,可在能耗上提供显著增益。 优化电源管理 : 使用多个独立的电源接口(如
    的头像 发表于 11-19 15:52 633次阅读

    LKT(LCS)代码移植芯片优势

    所谓代码移植就是客户可以把自定义的程序一部分关键代码函数移植到加密芯片中运行。用户采用标准C语言编写代码,通过KEIL C编译器,编译并下载到智能
    的头像 发表于 08-22 10:03 828次阅读

    stm32用串口烧录怎么设置

    微控制器。 STM32CubeMX配置 打开STM32CubeMX,选择您的STM32芯片型号。 配置您的微控制器的时钟设置,确保PLL和其他时钟设置正确。 启用串口(USART)作为
    的头像 发表于 08-22 09:33 1741次阅读

    STM32F10xx芯片资料

    电子发烧友网站提供《STM32F10xx芯片资料.pdf》资料免费下载
    发表于 07-08 14:56 1次下载

    Stm32采用环形缓冲区接收rk3588的数据代码

    Stm32采用环形缓冲区接收rk3588的数据代码
    的头像 发表于 05-15 10:10 649次阅读

    stm32f401与stm32f407在工程配置与代码上有什么区别?

    方便容易,但很奇怪现在调试一直不通,使用最基本的高低电平以及串口测试程序都不通,不通指的是:能够通过flash loader v2.8正常下载代码进去,但是不能跑。想问在工程配置以及代码上f407
    发表于 05-09 06:01

    在使用STM32电机库5.2的时候,生成的工程在Application/User中没有代码是为什么?

    在使用STM32电机库5.2的时候,生成的工程在Application/User中除了主函数外其他的文件里边只有注释,没有代码。我当时生成工程的时候,更换了一次库函数的路径,然后重新改
    发表于 04-24 07:28

    STM32F1改用STM32F2或STM32F4芯片后,发现芯片根本不能正常工作怎么解决?

    曾有工程师反映,之前用STM32F1系列芯片好好的,后来因为产品需要,改用STM32F2或STM32F4
    发表于 04-08 06:45

    STM32CubeMX生成的MDK工程不能显示stm32的IDCODE吗?

    STM32CubeMX生成的MDK工程不能显示stm32芯片的IDCODE?
    发表于 04-08 06:18

    STM32G0x0_OPT.FLM文件怎么在MDK工程里使用?

    STM32G0x0_128.FLM文件可以在工程里直接添加实现代码的烧录调试,但是STM32G0x0_OPT.FLM不知道如何使用?MDK工程
    发表于 03-29 06:33

    如何建立STM32F400CBT6工程

    你好,请问如何建立STM32F400CBT6工程,我再mdk 里面找不到对应芯片型号。 包括在stm32cubeMx里面也没有。 望指导,或提供个led
    发表于 03-28 07:35

    STM32L431RCT6从用户代码区跳转使用内置system memory bootloader无效怎么解决?

    STM32L431RCT6 系统BootLoader地址也是 0x1FFF0000;也不是双BANK芯片。麻烦是否有接触过个芯片 从用户代码区直接跳转到内置BOOTLOADER的 成
    发表于 03-26 07:54

    关于STM32 DMAMUX模块具体的应用示例代码

    有人通过公众号微信留言,询问是否有关于STM32 DMAMUX模块具体的应用示例代码。同时,个人也发现,虽然STM32片内的DMAMUX不是什么新模块,似乎还是很多人并不太熟悉。这里借机聊聊这方面的内容,重点演示相关功能的实现,
    的头像 发表于 03-25 09:15 2524次阅读
    关于<b class='flag-5'>STM32</b> DMAMUX模块具体的应用示例<b class='flag-5'>代码</b>

    使用touchGFX生成代码后,在该工程上再做些许改动STM32CUBEIDE都会频繁报错的原因?

    使用touchGFX生成代码后,只要是在该工程上再做些许改动,STM32CUBEIDE都会频繁报错make: *** No rule to make target
    发表于 03-12 07:50

    STM32单片机内存管理器实用代码解析与工程应用指南

    代码适用于无操作系统的STM32单片机开发,功能强大。 可申请到地址空间连续的不同大小的内存空间,且用户接口简单,使用方便。
    发表于 02-28 11:26 668次阅读