在Keil环境编程中发现STM32内存管理存在的问题

发布者:森绿企鹅最新更新时间:2023-07-20 来源: elecfans关键字:Keil  STM32  内存管理 手机看文章 扫描二维码
随时随地手机看文章

非常简单的一个工程,没有用到任何IO操作,与STM32有关的仅仅只有芯片的选择,即其SRAM大小有区别。图1是工程示意图,从图中可以看出,除了自己编写的代码外,仅仅增加了2个文件,即system_stm32f10x.c和startup_stm32f10x_hd.s,其中为了对startup_stm32f10x_hd.s进行修改,将其从库文件夹复制到了项目文件夹中。

图1


代码1

int main()

{

int a,b,c,d;

a=10;b=20;

c=a+b;

for(;;);

}

myex1.c(3): warning: #550-D: variable "c" was set but never used

linking...

Program Size: Code=796 RO-data=336 RW-data=20 ZI-data=1636

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 1 Warning(s).

代码2

int main()

{ const int x=16;

int a,b,c,d;

a=10;b=20;

c=a+b;

for(;;);

}

myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

myex1.c(3): warning: #550-D: variable "c" was set but never used

linking...

Program Size: Code=800 RO-data=336 RW-data=20 ZI-data=1636

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 2 Warning(s).

说明:

(1)Code增加了4字节

(2)其余没有任何变化

代码3

int main()

{ const int x=16;

int myArry[100];

int i;

int a,b,c,d;

a=10;b=20;

c=a+b;

for(i=0;i<100;i++)

myArry[i]=i;

for(;;);

}

myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

myex1.c(3): warning: #550-D: variable "myArry" was set but never used

myex1.c(5): warning: #550-D: variable "c" was set but never used

myex1.c(5): warning: #177-D: variable "d" was declared but never referenced

linking...

Program Size: Code=816 RO-data=336 RW-data=20 ZI-data=1636

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 4 Warning(s).

分析:程序中增加了数组myArry,Code增加为816字节,但是RO-data等仍未变化

代码4

int main()

{ const int x=16;

int myArry[100]={1,2,3,4,5,6};

int i;

int a,b,c,d;

a=10;b=20;

c=a+b;

for(i=0;i<100;i++)

myArry[i]=i;

for(;;);

}

myex1.c(2): warning: #177-D: variable "x" was declared but never referenced

myex1.c(3): warning: #550-D: variable "myArry" was set but never used

myex1.c(5): warning: #550-D: variable "c" was set but never used

myex1.c(5): warning: #177-D: variable "d" was declared but never referenced

linking...

Program Size: Code=1024 RO-data=360 RW-data=20 ZI-data=1636

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 4 Warning(s).

分析:

(1)由于myArry作了初始化,因此RO-data增加了 360-336=24字节。原因是32位机中int型变量是32位的,占4字节,所以初始6个值后,增加了24字节。

(2)再增加初始化变量的数量,则RO-data随之增加,而Code不再变化,也就是Code由代码3的816字节增加到1024字节,是增加了初始化处理的代码量。

根据以上分析,似乎与已知资料有冲突。

***************************************************

RO是程序中的指令和常量RW是程序中的已初始化变量ZI是程序中的未初始化的变量由以上3点说明可以理解为:RO就是readonly,RW就是read/write,ZI就是zero

****************************************************

如果按此说明,增加变量应该增加RO,但从代码1到代码2的变化来看,仅是增加了Code,却没有增加RO。

初始化变量时,应该增加RW,但是从代码2~代码4,RW却没有任何变化。

看来这个说法只能适用于ARM芯片,即运行时需要将代码调入RAM运行的芯片,对于STM32这类芯片并不完全适用。

以下再作研究:

当使用 int myArray[300]时:


图2

当使得int myArray[100]时:


图3

应该是向下生成的??

而且与芯片无关,无论选择6K RAM还是48K RAM都是如此,且当数组再大时,就会将地址置于小于0x2000000的地址,但编译并不报错。

当使得int myArray[450]时:


图4

当然,执行是错误的。

当int myArray[409]时:正指向0x2000000

去掉其他变量,对于这个地址没有影响!

代码5

int myArray[400]={1,2,3,4,5,6,7,8,9,10,11,12,13,14};

int main()

{ const int x=16;

int a,b,c,d;

int i;

a=10;b=20;

c=a+b;

for(i=0;i<100;i++)

myArray[i]=i;

for(i=0;i<100;i++)

c+=myArray[i];

d+=x;

for(;;);

}

编译结果:

compiling myex1.c...

linking...

Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 0 Warning(s).

分析:

本段程序将数组作为全局变量来定义,情况立即发生了变化。RW-data变成了1620。其中的1600应该是这个数组增加的4*400=1600,而20则是代码1~代码4中一直都有的。

经查验资料,局部变量是放在栈中的,如果栈定义得较小,那么变量数就很少。因此当数组在main内部定义时,是作为局部变量从栈中分配内存给它。所以在代码1~代码4的实验中还发现,即便更改芯片,从6KB RAM的C4到48KB RAM的VC,编译的结果不发生变化,其原因就在于不论哪种芯片,给它分配的栈是固定的。栈的大小应该在启动代码中修改。

图5

更改这个:startup_stm32f10x_hd.s可以更改栈的大小。

改成500后的编译结果如下:

linking...

Program Size: Code=1048 RO-data=392 RW-data=20 ZI-data=1892

FromELF: creating hex file...

"myex1.axf" - 0 Error(s), 0 Warning(s).

说明:注意到ZI-ddata已发生了变化。

至此可以明白RO-data ZI-data应该是针对栈来说的。即栈中的只读数据和零数据??但是RW-data似乎又有所不同,这里还应该再次探究。


关键字:Keil  STM32  内存管理 引用地址:在Keil环境编程中发现STM32内存管理存在的问题

上一篇:stm32f103开发板原理图分析
下一篇:stm32单片机引脚介绍及功能

推荐阅读最新更新时间:2024-11-07 15:47

Keil C51中静态库的生成与使用
1、将要生成库文件的代码新建一个工程,比如LibExample,然后把代码加到其中,在Option for target中的Output里选择Create Library,编译通过生成库文件。如下2图 2、将生成的库文件(LibExample.lib)拷贝到新项目(Hello)文件夹中,添加到工程文件中,并包含库文件的.h文件(LibExample.h),这样在新项目中即可调用,如下2图 库文件还是可以反编译成汇编,这点对单片机来说是个坏消息,呵呵,要防止轻易被破解的话用C语言写大量的冗余代码或者其他防反汇编代码倒是不错。
[单片机]
<font color='red'>Keil</font> C51中静态库的生成与使用
采用Keil4为ARM7 (LPC2103)创建工程 及J-link调试
采用Keil4为ARM7创建工程,采用J-LINK调试,具体步骤如下: 在菜单里的Project里选择New uVision project...,选择正确的路径并命名保存; 在弹出来的对话框中选择CPU,NXP(founded by philips)- LPC2103; 在弹出的对话框按“yes”复制LPC2100启动文件到工程; 在Project里面选择Option for Target'Target 1'...,Target里面的IROM1要配置正确(0x0 0x8000),一般采用默认值就可以了;Output选择里面的Name of Executable的命名不能用点号;Debug里面的选择
[单片机]
基于Proteus的温控报警器设计
Proteus软件是由英国Lab Center Elec—tronics公司开发的最新版本EDA工具软件,它集电路设计、制版及仿真等多种功能于一身,是目前世界上最先进、最完整的嵌入式系统设计与仿真平台。它是一种可视化的支持多种型号单片机(如51、PIC、AVR、Motorola hcll等),并且支持与当前流行的单片机开发环境(Keil、MPLAB、LAR)连接调试的软硬件仿真系统。针对微控制系统与外设的混合电路的电路仿真、软件仿真、系统协同仿真,做到了一体化和互动效果。 Proteus包含以下应用软件: ISIS——智能原理图输入系统,系统设计与仿真的基本平台。 IARES——高级PCB布线编辑软件。 在Pro
[单片机]
基于Proteus的温控报警器设计
关于stm32stop模式下,串口唤醒中的问题及解决办法
首先讲一下应用场景:STM32F1 + HAL库+ Freertos ,STOP模式下利用串口引脚唤醒。 stop mode 处理内容如下: 1,配置所有引脚为模拟输入(参考官方代码) 2,配置串口接收引脚为外部中断 3,进入stop mode 4,初始化串口等外设 现象:第一次从stop模式唤醒时串口能正常通信,判断一段时间后无数据则再一次进入stop mode,然后再一次唤醒,此时串口无法输出。 最后发现原因是串口重新初始化时HAL_UART_Init()函数中会判断if(huart- State == HAL_UART_STATE_RESET),此时才会执行HAL_UART_MspInit(huart),配置串口
[单片机]
STM32写内部FLASH
思想: FLASH分三个区: Bootloader区: 校验备份程序,若满足条件将用备份程序替换用户程序,否者运行用户程序. 运行区:运行用户程序,程序中要求能接受用户程序到备份区,接收完后,在备份区的程序头内打上标记,然后启动Bootloader,由Bootloader完成程序替换 备份区:用户程序在此接受 4.1 空间分区 STM32L151C8T6有64KB的FLASH空间,每4KB是一个区,每个区有16个页,程序编程是按页来编程的. 程序的Vector是按512的整数倍偏移的, 空间划分如下图, 后续所示的设置都是基于这个空间划分来配置的. 程序头的含义是这个新程序正文的标签,标记了当前程序的版本号,程序总校验,程
[单片机]
<font color='red'>STM32</font>写内部FLASH
入坑STM32后,我们应该如何学习?
01 前言 在STM32之前,都是老大头51,带着它的“小弟们” MSP430、AVR、PIC在单片机界呼风唤雨。 那个时候,市场上遍布8位机,大学教材用51入门,个人、企业学单片机基本上也都在用51。 虽然AVR也有一些8位机市场,但与stc带领下的51单片机是完全不能相比的。 当然,这个时候也有16位机的msp430,其他厂家单片机还有pic,高端嵌入式处理器等市场有arm7、arm9等。 这个时期的单片机市场是百花齐放、百家争鸣,但总体来说,还是势均力敌、一片祥和的。 那么,这个局势是从什么时候开始打破的呢?这还得从物联网的崛起说起。 02 原因 当时,物联网(Internet of Things,IoT)逐步进入人们的
[单片机]
入坑<font color='red'>STM32</font>后,我们应该如何学习?
STM32 中断向量表的位置 、重定向
我们也知道怎么跳到main函数了,那么,中断发生后,又是怎么跑到中断入口地址的呢? 从stm32f10x.s可以看到,已经定义好了一大堆的中断响应函数,这就是中断向量表,标号__Vectors,表示中断向量表入口地址,例如: AREA RESET, DATA, READONLY ; 定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000) EXPORT __Vectors IMPORT OS_CPU_SysTickHandler IMPORT OS_CPU_PendSVHandler __Vectors DCD __initial
[单片机]
<font color='red'>STM32</font> 中断向量表的位置 、重定向
STM32中ucos的编写程序
* Includes ------------------------------------------------------------------*/ #include config.h /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ //定义 堆栈大小 //#define TASK_STK_SIZE 128 #define TASK_STK_SIZ
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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