历史上的今天
返回首页

历史上的今天

今天是:2025年06月07日(星期六)

2018年06月07日 | STM32的存储分配问题

2018-06-07 来源:eefocus

keil编译后产生下面的信息:
Program Size: Code=37970 RO-data=7598 RW-data=212 ZI-data=12340 
其中
code ro-data rw-data zi-data分别代表什么意思?

回答:
代码段+初始化数据段=FLASH,数据段+0初始化数据段=RAM; 


ARM编译中的RO、RW和ZI DATA区段
ARM程序(指在ARM系统中正在执行的程序,而非保存在ROM中的bin文件)的组成
一个ARM程序包含3部分:RO段,RW段和ZI段
RO是程序中的指令和常量
RW是程序中的已初始化变量
ZI是程序中的未初始化的变量
由以上3点说明可以理解为:
RO就是readonly,
RW就是read/write,
ZI就是zero
ARM映像文件的组成
所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。
Image文件包含了RO和RW数据。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。

Q:为什么Image中必须包含RO和RW?
A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。
ARM程序的执行过程
从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。
实际上,RO中的指令至少应该有这样的功能:
1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中
在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。
说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。 
1; RO
看下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中相差一个字节(字符常量为1字节)。
Prog1:
#include 
void main(void)

;

Prog2:
#include 

const char a = 5;
void main(void)

;

Prog1编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog2编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 61 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1009 ( 0.99kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)

Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
以上两个程序编译出来后的信息可以看出:
Prog1和Prog2的RO包含了Code和RO Data两类数据。他们的唯一区别就是Prog2的RO Data比Prog1多了1个字节。这正和之前的推测一致。
如果增加的是一条指令而不是一个常量,则结果应该是Code数据大小有差别。

2; RW
同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
Prog3:
#include 
void main(void)

;

Prog4:
#include 
char a = 5;
void main(void)

;

Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 1 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。

3; ZI
再看两个程序,他们之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。
Prog3:
#include 
void main(void)


;

Prog4:
#include 
char a;
void main(void)

;

Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 97 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
编译的结果完全符合推测,只有ZI数据相差了1个字节。这个字节正是未初始化的一个字符型变量“a”所引起的。
注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。
即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。
总结:
1; C中的指令以及常量被编译后是RO类型数据。
2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据。
3; C中的已被初始化成非0值的变量编译后市RW类型数据。
附:
程序的编译命令(假定C程序名为tst.c):
armcc -c -o tst.o tst.c
armlink -noremove -elf -nodebug -info totals -info sizes -map -list aa.map -o tst.elf tst.o
编译后的信息就在aa.map文件中。
ROM主要指:NAND Flash,Nor Flash
RAM主要指:PSRAM,SDRAM,SRAM,DDRAM


推荐阅读

史海拾趣

台湾远翔(Feeling Technology)公司的发展小趣事

随着全球对绿色低碳发展的重视,乔光电子积极响应国家号召,于2021年底开始筹划绿色工厂创建项目。公司引入了产品全生命周期理念,持续开展节能低碳、环境保护工作,建立了质量管理体系、职业健康安全管理体系、环境管理体系和能源管理体系等。通过实施一系列绿色低碳、节能技改措施,如废气粉尘收集与处理系统、造粒珠磨机电机变频改造等,乔光电子实现了万元产值能耗和碳排放强度的逐步改善,为企业的可持续发展奠定了坚实基础。

ENTRELECUK公司的发展小趣事

在电子行业的早期,ENTRELEC UK以其创新的接触器设计在市场中脱颖而出。随着技术的进步,公司不断研发新产品,如过载继电器和电动机保护开关,这些产品迅速获得了市场的认可。公司通过持续的研发投入,确保产品始终走在行业前沿,为客户提供更安全、更可靠的解决方案。

ABL Heatsink公司的发展小趣事

ABL Heatsink公司在电子散热领域一直默默耕耘,直到某天,公司的研发团队成功开发了一种新型的高效散热材料。这种材料不仅导热性能卓越,而且成本相对较低,立即引起了业界的关注。随着这种新型散热材料的广泛应用,ABL Heatsink公司的订单量激增,公司规模迅速扩大。

DURAKOOL公司的发展小趣事

面对日益激烈的市场竞争和不断变化的客户需求,DURAKOOL公司始终保持着对创新的追求。公司不断投入研发资源,推动产品升级和技术进步。同时,公司也关注行业趋势和未来发展,积极探索新的业务领域和市场机会。展望未来,DURAKOOL将继续致力于成为全球电子行业的领先者。

请注意,以上故事均为虚构,旨在提供与DURAKOOL公司发展相关的故事概要。如需了解更多关于DURAKOOL公司的详细信息,建议查阅相关报道或公司官方资料。

Elpida Memory公司的发展小趣事

为了挽救Elpida Memory,日本政府采取了积极的援助措施。2009年,日本政府通过《产业再生法》修正案,向Elpida Memory提供了数百亿日元的公共资金和融资支持。这些资金帮助Elpida Memory度过了最困难的时期,并为其后续的重组和发展提供了有力的支持。

HBH-Microwave公司的发展小趣事

HBH-Microwave的故事始于对高性能微波组件的执着追求。在成立初期,公司便聚焦于设计并制造能够满足严苛应用需求的微波放大器。通过不断的技术研发,HBH成功推出了HA6013型号的高功率放大器,该产品在17.0至18.0 GHz频段内表现出色,迅速在通信和雷达领域获得认可。这一创新不仅巩固了HBH在微波技术领域的地位,也为后续产品的开发奠定了坚实的技术基础。

问答坊 | AI 解惑

通过mini2440的蜂鸣器演奏“两只老虎”

程序模拟了音乐的七个音皆(do,re,me,fa,so,la,si),包括低音,中音及高音. 有兴趣的朋友可下载程序到target board一试,或到以下网站观看示范片段. http://v.youku.com/v_show/id_XMTQwMjI0MjI0.html 附件是作者提供的Qtopia应用程序,感兴趣的 ...…

查看全部问答>

一位值得借鉴的电子专业学长的足迹

本帖最后由 paulhyde 于 2014-9-15 09:30 编辑 在哈尔滨工程大学六年,我在学校电子创新实验室呆了四年,这四年里创新实验室给我提供了良好的学习环境和完善的实验设备;在与众多电子爱好者的交流中,使我学到了更多的专业知识;在学校老师们的教 ...…

查看全部问答>

IPHONE手机监控系统安装说明

进入 IPHONE 首先开启  IPHONE首页画面 因为本公司已将软件上传至APP STORE空间 所以接下来点选 APP STORE寻找软件 出现选择的清单页面 输入AVTECH(这是本公司产品的品牌名称),大小写都可以找的到。 这时会出现两个软件 ...…

查看全部问答>

wince找师傅带我入门

初学wince,指望高手指点下明路,要具体点的。不要什么一句话去看书。没用的,我只要快点入门。…

查看全部问答>

信号采集的问题

有没有前人做过  信号采集或者处理   音频的 采集到WinCE板的信号如何才能消除其中的直流电平偏置。 否则FFT的谱全都在0上了 .. 有没有谁知道国内的信号采集处理的 好论坛 …

查看全部问答>

请问如何设计一个类似BTS功能的设备,可以取得无线L3的消息?

  请问如何从空口中提取L3的信号,应该使用何种模块??   TC35系列芯片虽然可以处理GSM协议栈,但不知道是否可以从其端口取得空口的的消息?   现有如下思路如下:      天线 + ??1 + TC ...…

查看全部问答>

如何烧写u-boot和uClinux?

我在linux系统下编译u-boot生成u-boot、u-boot.bin和u-boot.srec三个文件,编译uClinux(2.4.x版)后生成image.ram、image.rom 和 romfs.img。请问用什么工具烧写u-boot和uClinux呢?应该烧哪些文件呢?有没有相关的文档?我之前移植ucos等都是用H- ...…

查看全部问答>

请高手指点---请教并口EPP模式通信的问题

我用电脑并口与51单片机通信的时候,采取的是EPP1.9模式,发现老是nWait=1,不知道什么原因, 有没有这方面的前辈指导一下。感谢不尽。 源码如下: #include /* inp, outp */ #include   /* kbhit() et al  */ #incl ...…

查看全部问答>

请帮忙选一个湿度传感器,最好附价格

最近要开发一个采集室内温度和湿度的模块, 相对来说温度采集的方案挺多的,湿度就相对少了, 据了解湿度采集有电阻式的、电容式的、数字式的多种, 麻烦熟悉的给比较一下各种传感器的优劣, 如果做过这方面的提供些现在使用的型号给我,最好附 ...…

查看全部问答>

51 to ARM

从8位机到32位机过渡的捷径…

查看全部问答>