文章目录
一、前言
实际工作中,经常会遇到编写一些flash的程序。就会想起STM32的内存架构,比如芯片的FLASH大小,RAM大小,STM32的FLASH到底有什么?RAM里有什么?
关于数据类型,变量和堆栈的基础知识,可以学习《安富莱_STM32-V7开发板_用户手册,含BSP驱动包设计(V3.2)》。还有阅读ST官网的编程手册,当前在使用STM32H743,所以阅读《STM32H7x3编程参考手册》的第2章节-存储器和总线架构。
在Keil或者IAR,需要学会查看.map的文件才能了解程序编译后RAM与FLASH的实际情况。在STM32CubeIDE上使用Build Analyzer就可以简单快捷地查看FLASH与RAM的使用情况了。
二、STM32CubeIDE - Build Analyzer
我以STM32H743IIT做演示,使用STM32CubeIDE的Build Analyzer查看FLASH与RAM。从下图看到,STM32H743IIT的FLASH大小是2M,RAM的大小是1M。
2.1、打开Build Analyzer
打开STM32CubeIDE→Window→Show View→Build Analyzer,点击Build Analyzer后,就能出现窗口。
2.2、查看Build Analyzer
Build Analyzer由两部分组成,分别是Memory Regions与Memory Details。
当在代码编译成功后,Build Analyzer会才更新。在Memory Regions可以简单查看STM32的FLASH与RAM被占用了多少,属于比较宏观的查看。需要查看更加细节时,需要切换到Memory Detials。
在实际工作上,我比较关注RAM而很少关注FLASH。原因是FLASH主要是保存代码而RAM是保存程序运行时的数据(比如全局变量,堆数据与栈数据)。以下摘自安富莱教程:
栈(stack)空间,用于局部变量,函数调时现场保护和返回地址,函数的形参等。
堆(heap)空间,主要用于动态内存分配,如malloc,calloc,realloc等函数分配的变量空间是在堆上。
展开RAM后,可以看到RAM分别是由.data与.bss与._user_heap_stack三部分构成。当我们使用RTOS的时候,需要特别关注._user_heap_stack的大小,防止堆溢出。因为当前我的工程比较小,所以RAM_D1,RAM_D2,RAM_D3都没有东西,导致无法展开。
2.3、Build Analyzer的搜索功能
Build Analyzer提供搜索功能,可以非常方便地寻找我们感兴趣的变量到底存在哪里,其实不单单是变量,搜索函数也是可以的,就以我现在的工程为例子吧。
我现在对代码文件Slave1.c里的全局变量encoder_Value,LED5_Num,LED4_Num都很感兴趣,看看它们到底被放在哪里?FLASH?RAM?还是FLASH与RAM都有?
先搜索encoder_Value吧,看看到底存在哪里?原来在RAM的.bss段里,地址是0x2000c9c0,大小是4Byte(encoder_Value是int32_t类型)。
LED5_Num也在RAM的.bss段,地址0x2000c694,大小是4Byte(LED5_Numde是uint32_t类型)。
LED4_Num也在RAM的.bss段,地址0x2000c690,大小是1Byte(LED4_Num是uint8_t类型)。
有没有一个变量,同时被放在FLASH与RAM里?我试着找了一遍,让我找到了。在我编写的bsp_fdcan.c文件里,有一个结构体变量fdcan1。我在Build Analyzer上搜索到,结构体变量fdcan1放在FLASH里又放在RAM里。所以,不要强行让自己记忆全局变量一定放在哪里,在STM32CubeIDE的GCC编译器上,全局变量有可能都在FLASH里与RAM里占用掉一些空间。