当有多个内存块时,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专题三十六:MDK编译过程和文件类型(四)
下一篇:stm32专题三十八:在SRAM中调试代码
推荐阅读
史海拾趣
90年代初期,“General Microcircuits”敏锐地捕捉到市场对定制化半导体解决方案的需求增长。公司迅速调整战略,成立专门的定制化服务部门,为客户提供从需求分析、设计开发到生产测试的全流程定制化服务。这种以客户为中心的服务模式赢得了众多客户的青睐,尤其是在通信、汽车电子等高端应用领域,公司凭借定制化的高性能芯片解决方案占据了重要的市场份额。
Clever Little Box深知,优质的客户服务是企业长期发展的关键。因此,公司始终注重提升服务质量,为客户提供专业的技术支持和售后服务。同时,公司还注重与客户建立良好的关系,通过定期沟通、反馈收集等方式,了解客户的需求和意见,以便更好地满足客户的期望。
益升华(Essentra)公司深知客户是企业发展的基石。因此,公司始终将客户服务放在首位,致力于为客户提供优质的产品和服务。公司建立了完善的客户服务体系,为客户提供从产品咨询、选购、安装到售后维护的全流程服务。同时,公司还积极开展客户回访和满意度调查活动,及时了解客户需求和反馈意见,不断改进产品和服务质量。这些努力使益升华(Essentra)公司赢得了客户的广泛赞誉和信任。
Boundary Devices公司成立于2003年,总部位于美国亚利桑那州。创立之初,公司便专注于嵌入式系统硬件的开发与生产,凭借对技术的深刻理解和市场需求的敏锐洞察,Boundary Devices迅速在行业中崭露头角。其推出的Boundary Devices插座和适配器,因其兼容性强、性能稳定而备受市场青睐。同时,公司与NXP/Freescale建立了紧密的合作关系,共同推进i.MX系列处理器的应用与发展,为公司的后续发展奠定了坚实的基础。
随着环保意识的不断提高,ELDECO公司积极响应国家号召,将绿色环保理念融入产品设计和生产过程中。公司采用环保材料和节能技术制造ELD产品,减少了对环境的污染和能源消耗。同时,公司还推广绿色出行理念,鼓励运输企业采用更环保的运输方式。通过这些措施,ELDECO公司不仅提高了企业的社会责任感,还为推动绿色交通发展做出了积极贡献。
ENSIGN不仅关注传统电子行业的发展,还积极探索新的业务领域。最近,ENSIGN集团宣布收购位于亚利桑那州的医疗保健园区River Park Post Acute和Elmwood Senior Living,以及其他七家公司。这一收购标志着ENSIGN正逐步向医疗保健领域进军,寻求多元化的发展机会。
介绍了合成孔径雷达及其天线技术!星载天线有源馈电网络的特点!空间辐射对卫星寿命的影响及空间辐射屏蔽机理,阐述了卫星在轨飞行时空间环境的深度剂量曲线,得出轨道质子!电子的分布特点,分析等效铝材料对质子!电子的屏蔽效果,根据元器件的抗辐射性能 ...… 查看全部问答∨ |
网上说UCOS这个内核非常简单,很适合初学者看.于是乎找了一本邵贝贝的己来看.这个本估计有一斤重,看了几天,怎么像看天书一样啊...狂晕,不是说适合初学者看的么`~~~~~~ 肯定是那书商在网上乱发信息,欺骗我等无知少年也.... 不过那UCOS的作者可 ...… 查看全部问答∨ |
小弟设计的电路是一个10K方波信号经过MAX275滤波后滤成规整的正弦信号,然后直接进入MSP430采样。但只要一接单片机采样,信号就有一些比较大的毛刺,去了单片机就没有了。后来在滤波和采样之间加了一级跟随后再采样,虽然毛刺少多了,但一接单片机 ...… 查看全部问答∨ |
|
MSP430FR5739慢慢学之一:C语言的hello world程序 感谢EEWORLD的这次团购,让大家以低廉的价格体验到了TI的新产品。 板子在11月23日就到货了,可是工作繁忙,业余时间也不多,所以学习进程比较缓慢。 这款MSP430FR系列的芯片比其他系列的430功耗要大一些,在LPM3和LPM4模式下功耗在6uA左右( ...… 查看全部问答∨ |