历史上的今天

今天是:2024年11月02日(星期六)

2021年11月02日 | stm32专题三十七:自动分配变量到指定 SRAM 空间

发布者:pcwg 来源: eefocus关键字:stm32  SRAM  空间 手机看文章 扫描二维码
随时随地手机看文章

当有多个内存块时,MDK 优先使用空间更大的内存。


使用 sct 文件来进行内存管理:

编程要点:


1 取消勾选Use Memory Layout from Target Dialog,然后直接点击 edit 来编辑工程的 sct 文件:


sct 文件的默认配置如下所示:

看一下此时的 map 文件。可以看到,HEAP 和 STACK 都位于IRAM1 区域。

接下来,我们将64 KB的内存空间分成两块,如下所示(直接复制,然后修改):

我们将 64 KB 的内部SRAM,人为的分成了 20 + 28 KB,按照 MDK 优先使用大容量的空间进行存储,我们预计结果会是保存在ERAM1中,map文件证实了这一结果:

通常,我们会将栈区 STACK 分配到内部 SRAM,用来保存某些程序所用到的局部变量,因此,对sct文件进行修改如下:

通过上述修改,将栈区的内容保存在 IRAM1 中,而其他数据分配不变, map文件如下所示:

有了内存分配,接下来直接使用代码来分析,全局变量、全局数组、局部变量、动态内存 在内存中的地址:


#include "stm32f10x.h"

#include "./usart/bsp_usart.h"

#include "./led/bsp_led.h"  

#include "./sram/sram.h"

#include

 

void Delay(__IO u32 nCount); 

 

//定义变量到“指定的存储空间”

uint32_t testValue  =7 ;

//定义变量到“指定的存储空间”

uint32_t testValue2  =0;


//定义数组到“指定的存储空间”

uint8_t testGrup[100]  ={0};

//定义数组到“指定的存储空间”

uint8_t testGrup2[100] ={1,2,3};

 

/*本实验中的sct配置,若使用外部存储器时,堆区工作可能不正常,

  使用malloc无法得到正常的地址,不推荐在实际工程应用*/

/*另一种我们推荐的配置请参考教程中的说明*/

 

/**

  * @brief  主函数

  * @param  无

  * @retval 无

  */

int main(void)

{

uint32_t inerTestValue =10;

/* LED 端口初始化 */

LED_GPIO_Config();  

    

  /* 初始化串口 */

  USART_Config();

  

  printf("rnSCT文件应用——自动分配变量到“指定的存储空间”实验rn");

  

printf("rn使用“ uint32_t inerTestValue =10; ”语句定义的局部变量:rn");

printf("结果:它的地址为:0x%x,变量值为:%drn",(uint32_t)&inerTestValue,inerTestValue);

  printf("rn使用“uint32_t testValue  =7 ;”语句定义的全局变量:rn");

printf("结果:它的地址为:0x%x,变量值为:%drn",(uint32_t)&testValue,testValue);

  printf("rn使用“uint32_t testValue2  =0 ; ”语句定义的全局变量:rn");

printf("结果:它的地址为:0x%x,变量值为:%drn",(uint32_t)&testValue2,testValue2);

printf("rn使用“uint8_t testGrup[100]  ={0};”语句定义的全局数组:rn");

printf("结果:它的地址为:0x%x,变量值为:%d,%d,%drn",(uint32_t)&testGrup,testGrup[0],testGrup[1],testGrup[2]);

  printf("rn使用“uint8_t testGrup2[100] ={1,2,3};”语句定义的全局数组:rn");

printf("结果:它的地址为:0x%x,变量值为:%d,%d,%drn",(uint32_t)&testGrup2,testGrup2[0],testGrup2[1],testGrup2[2]);

/*本实验中的sct配置,若使用外部存储器时,堆区工作可能不正常,

  使用malloc无法得到正常的地址,不推荐在实际工程应用*/

  /*另一种我们推荐的配置请参考教程中的说明*/

uint32_t * pointer = (uint32_t*)malloc(sizeof(uint32_t)*3); 

if(pointer != NULL)

{

*(pointer)=1;

*(++pointer)=2;

*(++pointer)=3;

printf("rn使用“ uint32_t *pointer = (uint32_t*)malloc(sizeof(uint32_t)*3); ”动态分配的变量rn");

printf("rn定义后的操作为:rn*(pointer++)=1;rn*(pointer++)=2;rn*pointer=3;rnrn");

printf("结果:操作后它的地址为:0x%x,查看变量值操作:rn",(uint32_t)pointer); 

printf("*(pointer--)=%d, rn",*(pointer--));

printf("*(pointer--)=%d, rn",*(pointer--));

printf("*(pointer)=%d, rn",*(pointer));

free(pointer);

}

else

{

printf("rn使用malloc动态分配变量出错!!!rn");

}

  

  LED_BLUE; 

 

  while(1); 

 

 

}


void Delay(__IO uint32_t nCount) //简单的延时函数

{

for(; nCount != 0; nCount--);

}

 

实际串口打印结果如下:


可以看到,全局变量位于 ERAM1,局部变量位于栈区 IRAM1,动态内存位于堆区 ERAM1。

再设想一下,如果ERAM1真的是一个外部扩展的SRAM,那么毫无疑问的,肯定在速度上不如内部SRAM。所以,我们希望优先将变量保存到内部SRAM,而HEAP和其他的才保存在外部的SRAM。但由于 MDK 的链接器特性,都优先使用大容量作为存储空间,那么该怎么办?


其实很简单,只需要在 ERAM1 中注释掉就行;

map 文件结果如下所示:

关于 __attribute__ 关键字的说明


在程序中,当需要指定某个变量的内存地址时, MDK 提供了一个关键字__attribute__,来实现绝对地址定位的功能,这种用法通常是为了把变量指定到外部扩展的存储器。


__attribute__ 的用法如下所示:

指定变量分配到节区:

可以看到,我们将变量定义到名为 EXRAM 的节区中,而在 sct 文件中,我们还可以指定 EXRAM 的执行域:

分配变量到外部SRAM


编程要点:


修改启动文件,在__main执行之前初始化“指定的存储空间”的硬件;

在 sct文件中增加“指定的存储空间”对应的执行域;

使用节区选择语句选择要分配到“指定的存储空间”的内容;

测试;

为什么要修改启动文件?

试想一下,如果我们在程序中,将大量的 RW-data 定义到外部SRAM,那么在分散加载代码的过程中,系统会将原本保存在FLASH中的RW-data复制到SRAM中,这就要求我们必须先完成对外部SRAM的初始化,不然外部SRAM都起不来,还怎么保存数据呢?


修改启动文件如下所示:

在原来的启动文件中可以增加上述加粗表示的代码,增加的代码中使用到汇编语法 IMPORT,引入用户在其它C语言文件中定义的名为 FSMC_SRAM_Init 的函数(函数名要根据具体的程序来改),接着使用 LDR 指令加载函数的代码地址到寄存器 R0,最后使用BLX R0 指令跳转到 FSMC_SRAM_Init 的代码地址执行。


加入的代码实现了 Reset_handler 在执行__main 函数前先调用了我们自定义的FSMC_SRAM_Init函数,从而为分散加载代码准备好正常的硬件工作环境。


在 sct 文件中增加执行域:

关于为什么要定义 STACK 和 stm32f10x_rcc.o的描述:

优先使用内部SRAM作为数据存储器的原因:

关键字:stm32  SRAM  空间 引用地址:stm32专题三十七:自动分配变量到指定 SRAM 空间

上一篇:stm32专题三十六:MDK编译过程和文件类型(四)
下一篇:stm32专题三十八:在SRAM中调试代码

推荐阅读

车载电子操作系统是汽车智能化的核心,能够有效分配车机的硬件资源,对车内各种任务功能进行协同管理,并控制各项任务优先级别。常见的车载电子操作系统有:QNX、Linux(Android,AaliOS)、Windows CE、iOS等,此外还有一些非主流操作系统如Wind River和micro-ITRON 等。QNX:黑莓旗下的一款微内核实时操作系统,是全球第一款通过ISO 26262 ASIL leve...
(文章来源:中科罗伯特机器人学院) 目前,工业机器人制造备受各大生产企业的青睐,无论是传统的制造企业还是新兴企业都十分关注工业机器人的发展。国内机床制造企业在工业机器人方面也加大发展的力度。据了解,工业机器人可以对生产线精密零件进行组装任务,可替代人工在喷涂、、装配等环境中工作,还可与数控超精密铣床等工作进行结合制造模具。 ...
vivo发明的无线充电系统,允许同时有多个充电电路进行工作,比单个充电线圈具有更高的充电功率,可以有效提高无线充电设备的充电效率。 随着无线充电技术的发展,无线充电功能在电子设备中的应用越来越普及,具有无线充电功能的电子设备越来越受用户的青睐,目前无线充电已经成为了各大厂商旗舰机的标配。 例如苹果、华为、小米等,都将无线充电技术应用到...
OPPO K9s幻紫流沙配色采用外纹理工艺,实现亮面哑光同体的视觉效果,光面多彩变幻,哑面星光熠熠。  镜头模组区域的设计灵感来源于赛博朋克世界里高楼外墙的电子屏幕,镭射型号字若隐若现,增加科幻感,激光条纹从上向下,彰显一气呵成的速度美学,整体机身采用了透镜纹理,让背面在不同角度下呈现出光影变幻的效果,更显活力。  OPPO K9s...

史海拾趣

问答坊 | AI 解惑

星载天线有源馈电网络空间辐射屏蔽技术

介绍了合成孔径雷达及其天线技术!星载天线有源馈电网络的特点!空间辐射对卫星寿命的影响及空间辐射屏蔽机理,阐述了卫星在轨飞行时空间环境的深度剂量曲线,得出轨道质子!电子的分布特点,分析等效铝材料对质子!电子的屏蔽效果,根据元器件的抗辐射性能 ...…

查看全部问答∨

简单的uC/OS...我晕~$$^*#!

网上说UCOS这个内核非常简单,很适合初学者看.于是乎找了一本邵贝贝的己来看.这个本估计有一斤重,看了几天,怎么像看天书一样啊...狂晕,不是说适合初学者看的么`~~~~~~ 肯定是那书商在网上乱发信息,欺骗我等无知少年也.... 不过那UCOS的作者可 ...…

查看全部问答∨

MSP430采样带来的干扰

小弟设计的电路是一个10K方波信号经过MAX275滤波后滤成规整的正弦信号,然后直接进入MSP430采样。但只要一接单片机采样,信号就有一些比较大的毛刺,去了单片机就没有了。后来在滤波和采样之间加了一级跟随后再采样,虽然毛刺少多了,但一接单片机 ...…

查看全部问答∨

开关电源测试方法

一. 耐电压   (HI.POT,ELECTRIC STRENGTH ,DIELECTRIC VOLTAGE WITHSTAND)KV   1.1 定义:于指定的端子间,例如:I/P-O/P,I/P-FG,O/P-FG间,可耐交流之有效值,漏电流一般可容许10毫安,时间1分钟。   1.2 测试条件:Ta:25℃;RH:室内湿度 ...…

查看全部问答∨

mc55模块上电20秒后自动关机问题

将mc55模块/IGT引脚置低电平后,mc55模块上电开机,但20秒后mc55模块会自动关机.每次都是这样,找不到原因,请各位指教.谢谢…

查看全部问答∨

Protel.PCB.转SCH全攻略

Protel.PCB.转SCH全攻略…

查看全部问答∨

MSP430FR5739慢慢学之一:C语言的hello world程序

感谢EEWORLD的这次团购,让大家以低廉的价格体验到了TI的新产品。 板子在11月23日就到货了,可是工作繁忙,业余时间也不多,所以学习进程比较缓慢。 这款MSP430FR系列的芯片比其他系列的430功耗要大一些,在LPM3和LPM4模式下功耗在6uA左右( ...…

查看全部问答∨

21个详细且精湛的模拟电子技术问答

先看目录 再看问题1 满意了,就down吧 …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved