前言
记得以前刚学习单片机根本不会关注单片机的内存大小,点个灯,点个oled屏幕,程序能跑起来就很开心了。后面工作了之后,很多单片机的选用都是极简的,都是基本所有资源都用完,且内存也是比较小的,这个时期就开始去关注单片机的内存,当时只知道单片机内存分为栈区(stack)、堆区(heap)、初始化数据段(.data)、未初始化数据段(.bss)和文本区(.text)。当时觉得已经够复杂了再深入也没有了解了,并不知道这些个数据再单片机上是怎样存储的,哈哈哈废话说了这么多下面来看看我个人对于单片机存储的新的认识吧。
单片机的存储配置
本次单片机我使用的是航芯ACM32FP0X,没用过甚至没听到过的同学也没关系,这也是基于ARM-M0架构的所以也大差不差。
资源描述
下面是芯片手册对于芯片内存资源的描述,这里可以看到有32KB SRAM 128KB eFlash
存储器空间映射
这里Eflash的地址是0x1000_0000 可以映射到 0x0000_0000 启动,然后SRAM的其实地址是0x2000_0000,这里也和我们KEIL上的配置对应到如下图,这样对我们的单片机也有了个大概的了解。
第一个IROM1实际上就是我们的FLASH后面的IRAM1实际上就是我们的RAM。
单片机内存结构
知识点回顾
单片机的内存结构可以分为以下方面
栈区(stack):是一种用来存储函数调用时的临时信息的结构,如函数调用所传递的参数、函数的返回地址、函数的局部变量等。在程序运行时由编译器在需要的时候分配,在不需要的时候自动清除。(RAM)
int test(int param1,int param2)
{
int res = 0;
res = param1 + param2;
return res;
}
上述代码中的 param1 和 param2 以及 res 都是属于栈区管理
堆区(heap):需要程序员手动分配,使用malloc 和 free 进行管理 (FLASH)
void test2(void)
{
double * ptd;
ptd = (double * ) malloc (30 * sizeof(double));
/*----一些操作----*/
free(ptd);
}
上面的ptd就属于堆区管理
已初始化数据区(data):这部分数据是在初始化的时候就给定了值的 (FLASH)
int My_Data[10] = {1};
上面的在函数外部定义的一个全局变量 且已经给予的初始值的变量就数据data区
未初始化数据区(bss):这部分就是没有初始化或者初始化给0的数据
int My_Data[10];
同样的没有给予初值的就存储在bss区
(*使用static修饰的数据也在数据区)
文本区(text):这部分数据像是代码和const修饰的常量都是在这个位置 (FLASH)
const int My_Data[10] = {1};
像上面这种加了 const 或者是代码段就是存储在文本区这部分数值仅为可读保证了数据的安全性
在单片机内部的存储情况
从上面的陈述我们可以知道单片机有SRAM和 FLASH 两大类存储 当然还有ROM这篇先不介绍。那么以上这些数据都是存储在flash中吗?答案是否定的,我们都知道单片机每次下载完程序,或者直接查看map文件我们都可以得到 单片此次程序的大小以及结构如下
==============================================================================
Total RO Size (Code + RO Data) 3916 ( 3.82kB)
Total RW Size (RW Data + ZI Data) 3368 ( 3.29kB)
Total ROM Size (Code + RO Data + RW Data) 3928 ( 3.84kB)
===========================================================================
我们需要下进FLASH区的内存计算我们都知道是Code + RO Data + RW Data 的总和,那么这个ZI Data的数据存储在哪呢,是的你已经知道了是存储在SRAM区
FLASH中的内存分布
- Code区 包括了 代码所占空间
- RO Data 则是包括 使用const修饰的常量
- RW Data 则是包括了 初始化变量
SRAM中内存分布
未初始化变量 已初始化变量 也就是 RW Data 和 ZI Data
这里涉及到一个问题,为什么已初始化变量是包含在FLASH里面呢?这就涉及到存储器的性质了因为SRAM是掉电丢失的,所以里面如果放置初始化值了的变量就会丢失,那为什么以初始化变量的值也在SRAM中呢?这还是因为存储器的特性,因为变量在使用过程中需要不断修改所以放在SRAM中擦除和写更加方便。
这一点在map文件中也可以得到映证
小结
从理论上来讲,不论当你当下面临多么大的困难的时候,不要放弃,勇敢面对,永远相信一定会有好的事发生。如果没有,那么也没关系因为我刚刚说了仅仅是从理论上来说。
哈哈加油各位,今天的分享就到这了,无限进步!