0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

GReq_mcu168 来源:未知 作者:胡薇 2018-09-12 16:15 次阅读

非常简单的一个工程,没有用到任何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似乎又有所不同,这里还应该再次探究。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3002

    浏览量

    73885
  • STM32
    +关注

    关注

    2266

    文章

    10871

    浏览量

    354815

原文标题:用Keil环境编程 发现STM32内存管理的一个问题

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    管理STM32 MCU中的内存保护单元

    本应用笔记介绍如何管理 STM32 产品中的内存保护单元(MPU)。MPU 是用于存储器保护的可选组件。STM32 微控制器(MCU)中嵌入 MPU 之后变得更稳健可靠。
    发表于 12-23 11:04 1032次阅读

    Keil中使用STM32CubeProgrammer

    Keil 环境中对新产品进行下载。对此,用户可以选择等待,也可以自行扩展 Keil 的 FLM 来支持该产品。但考虑到用户产品开发的时间限制以及新的STM32 正式 Pack 很快
    的头像 发表于 11-03 16:50 2488次阅读
    <b class='flag-5'>在</b><b class='flag-5'>Keil</b>中使用<b class='flag-5'>STM32</b>CubeProgrammer

    stm32keil编译环境下如何使用printf函数?

    stm32keil编译环境下如何使用printf函数?
    发表于 12-01 07:34

    内存管理简介

    内存管理1.内存管理简介2. 硬件设计3. 软件设计3.1 STM32CubeMX设置3.2 MDK-ARM
    发表于 12-13 06:17

    请问STM32工程keil下怎么移植到IAR环境

    请问STM32工程keil下怎么移植到IAR环境
    发表于 12-17 07:12

    STM32内存管理的相关资料推荐

    STM32内存管理总结使用一个STM32芯片,对于内存而言有两个直观的指标就是 RAM 大小,FLASH大小,比如
    发表于 02-09 06:22

    Keil环境中建立带FreeRTOS的STM32L项目教程详细说明

    Keil 环境中建立带FreeRTOS的STM32L项目   1、先把source 文件夹复制至project 目录,然后keil
    发表于 11-07 14:35 13次下载
    <b class='flag-5'>Keil</b><b class='flag-5'>环境</b>中建立带FreeRTOS的<b class='flag-5'>STM32</b>L项目教程详细说明

    STM32学习笔记1——软硬件基础之keil5编程与GPIO开发

    STM32学习笔记1——软硬件基础之keil5编程与GPIO开发
    发表于 11-30 12:36 4次下载
    <b class='flag-5'>STM32</b>学习笔记1——软硬件基础之<b class='flag-5'>keil</b>5<b class='flag-5'>编程</b>与GPIO开发

    stm32keil和IAR中的汇编启动代码不相同

    最近学习cortex-A8内核的soc,Linux环境下开发,从汇编到C、uboot分析移植。过程中发现,使用的汇编和keil中同是arm内核的s
    发表于 12-03 12:51 2次下载
    <b class='flag-5'>stm32</b><b class='flag-5'>在</b><b class='flag-5'>keil</b>和IAR中的汇编启动代码不相同

    STM32内存管理相关(内存架构,内存管理,map文件分析)

    STM32内存管理总结使用一个STM32芯片,对于内存而言有两个直观的指标就是 RAM 大小,FLASH大小,比如
    发表于 12-05 20:21 14次下载
    <b class='flag-5'>STM32</b>的<b class='flag-5'>内存</b><b class='flag-5'>管理</b>相关(<b class='flag-5'>内存</b>架构,<b class='flag-5'>内存</b><b class='flag-5'>管理</b>,map文件分析)

    STM32+Keil 5+proteus 8 编程、仿真方法汇总

    介绍Keil 5 是我们真正编程开发的IDE环境。用C语言写程序实现某些功能STM32CubeMX是为stm32特别服务的“代码自动生成”软
    发表于 12-16 16:59 22次下载
    <b class='flag-5'>STM32+Keil</b> 5+proteus 8 <b class='flag-5'>编程</b>、仿真方法汇总

    STM32内存管理

    内存管理详解1、介绍内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且
    发表于 12-24 19:37 13次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>内存</b><b class='flag-5'>管理</b>

    浅谈嵌入式系统裸机编程内存管理

     malloc和freePC编程中是很好用的一种内存分配手段。但是,其嵌入式中,就未必好用了。由于嵌入式裸机编程中,无MMU,即
    发表于 09-15 10:38 1492次阅读

    管理 STM32 MCU 中的内存保护单元

    管理 STM32 MCU 中的内存保护单元
    发表于 11-21 08:11 4次下载
    <b class='flag-5'>管理</b> <b class='flag-5'>STM32</b> MCU 中的<b class='flag-5'>内存</b>保护单元

    AN4838 管理STM32 MCU中的内存保护单元

    AN4838 管理STM32 MCU中的内存保护单元
    发表于 11-21 17:07 0次下载
    AN4838 <b class='flag-5'>管理</b><b class='flag-5'>STM32</b> MCU中的<b class='flag-5'>内存</b>保护单元