随着单片机硬件的发展,其中的RAM和flash越做越大。MCU在实际的使用中,通常程序都是运行在flash上的,RAM的高速空间并没有得到充分的利用,如果我们的程序需要运行的更快,系统有更好的实时性,我们可以考虑将这部分代码放到RAM中运行,下边我们将以STMF103RCT6作为举例,向大家介绍在keil环境中如何使程序在RAM中运行。
在STMF103RCT6单片机上有两个存储空间,一个是片上的FLASH(相当于硬盘),有256K,另一个就是SRAM(相当于内存),有64K。
下边是使用keil生成项目时的项目大小信息:
Code:程序代码不分大小
RO-data:程序定义的常量
PW-data:已经初始化的的全局变量
ZI-data:未初始化的全局变量,以及初始化为0的变量
下面给出三个值:
RO Size= Code + RO Data (程序占用FLASH空间的大小).
RW Size-RW Data +ZI Data (运行时程序占用RAM空间的大小).
ROM Size=Code + RO Data + RW Data (烧写时程序占用FLASH空间的大小).
我们都知道,在烧写程序的时候,需要烧写bin文件或者hex文件到STM32的flash当中,三部分:cole, RO-data和RW-data,为什么不包含ZI数据呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域(这一区域在RAM中)一律清零即可。包含进去反而浪费flash存储空间。
STM32上电启动以后, cpu根据boot0和boot1的硬件引脚决定从flash还是ram中启动,默认是从flash中启动;启动之后会搬运rw-data到ram,但是不会搬运code;也就是说 cpu执行的代码是在flash中读取的,而不是在ram中。
快速新建一个项目,使一个LED灯闪烁。
实现函数如下:
在main函数中:
通过查看xx.msp文件,可以看到LEDToggle函数编译后的地址是放在flash中的
那么如何将LEDToggle函数放在STM32的SRAM中:
1.打开编译后生成的xx.sct文件,修改该文件
同时可以看到
Flash起始地址:0x08000000
RAM起始地址:0x20000000
2.在xx.sct文件中,定义一个RAMCODE的section,放在RW_IRAM1执行区域(0x20000000-0x00002000)。
3.修改代码
方法一:用#pragma arm section code = "RAMCODE" 和 #pragma arm section将需要放到SRAM中的程序包括起来;
然后编译,重新打开xx.msp文件,可以看到LEDToggle函数编译后的地址已经在SRAM中
方法二:在需要放到RAM中的函数前,用__attribute__((section("RAMCODE")))声明该函数放在RAMCODE section中。
然后编译,重新打开xx.msp文件,可以看到LEDToggle函数编译后的地址同样在SRAM中
注意事项:
注意使用方法一时,该函数中调用到的所有函数也要放到RAMCODE section中,#pragma arm section code=“RAMCODE ”和#pragma arm section中可以包含多段代码。
对嵌入式物联网感兴趣的小伙伴,可以多了解一下相关信息。(看过来)