历史上的今天

今天是:2024年10月28日(星期一)

正在发生

2021年10月28日 | C51和MDK的ROM大小及变量绝对地址初始化

发布者:温柔的心情 来源: eefocus关键字:C51  MDK  ROM大小  变量  绝对地址  初始化 手机看文章 扫描二维码
随时随地手机看文章

#1. C51的ROM大小

Keil编译完之后,显示的Program Size: data=9.0 xdata=8 const=15 code=180,则

The Total ROM(const + code + code-gap + const-gap) is 199BYTE

实际生成的bin文件大小:

这里写图片描述

在.MAP中的C O D E M E M O R Y 中

这里写图片描述

code-gap为0,cosnt-gap为4,则const + code + const-gap=15 + 180 + 4 = 199,刚好和实际生成的bin文件大小一致。

#2. C51的ROM大小优化

如果实际编译显示的const + code远小于实际的Bin文件,表明有非常大的空隙,需要优化。

优化空间,有几个查找方向:


.A51文件中的代码段起始地址CSEG AT 0xXX是否与Off-chip Code Memory设置的起始位置一致,如果不一致可能导致GAP。

函数及变量指定的绝对地址超出Off-chip Code Memory设置的范围。

interrupt vectors at adress: 0xXX设置的中断向量地址是否超出Off-chip Code Memory设置的范围。interrupt vectors at adress必须设置,因为Keil C51默认的是0x03,可能不在Off-chip Code Memory设置的范围内,导致GAP。

打开.MAP文件,搜索GAP,如果存在一些GAP,则可能是多个指定的绝对地址之间有GAP导致的,可以将绝对地址调整对齐。

因为xdata + const + code将占用整个Off-chip(1581为58KB),所以可以将一些const,code类型的变量转换成xdata。总之,根据这三者根据实际情况进行一个调整,总大小不超过58KB即可。有时ROM存放在EEPROM上,所以适当减少const+code的大小,一些变量转换成Xdata是一种方法。

#3. C51变量绝对地址定位及初始化

##3.1. 关键字_at_

int xdata nValA _at_ 0x1114;

int xdata nValA = 0x2222; // nValA绝对地址定位于x:0x1114,初始化值为0x2222


char code nValD _at_ 0xD2;

char code nValD = 0x22; // 此句无效,nValD绝对地址定位于c:0xD2,初始值为0


##3.2. LX51 Locate

当勾选Use Extended liker(LX51) instead of BL51时,即使用LX51 Locate。


LX 51 Locate->User Segments->?CO?MAIN(C:0xD2), ?XD?MAIN(x:0x1114)

LX51 Misc->use linker control file->edit->SEGMENTS (?CO?MAIN(C:0xD2), ?XD?MAIN(x:0x1114))

以上两种设置均可,推荐用前面一种更方便,且还能够添加REMOVEUNUSED等编译关键字。

?CO?MAIN和?XD?MAIN作为segment name,是以变量类型缩写+文件名大写组合而成,对此不熟练,可以打开生成的.MAP文件,查看MEMORY MAP OF MODULE区域的描述也可以找到


当指定了当前文件Segment所在,那么当前文件所有的全局变量,均会在指定的绝对地址之后顺序排列,并且可以对变量进行初始化。


int xdata nValA = 0x2222; // nValA绝对地址定位于x:0x1114,初始化值为0x2222

int xdata nValB = 0x1111; // nValB绝对地址定位于x:0x1116,初始化值为0x1111

char code nValD = 0x22;   // nValD绝对地址定位于c:0xD2,初始值为x22

char code nValD = 0x11;   // nValD绝对地址定位于c:0xD2,初始值为x11


##3.3. BL51 Locate

当不勾选Use Extended liker(LX51) instead of BL51时,即使用BX51 Locate。


BL 51 Locate->code->?CO?MAIN(0xD2)

BL 51 Locate->Xdata->?XD?MAIN(0x1114)

BL1 Misc->use linker control file->edit->CODE( 0X0000-0X0FFF , ?CO?MAIN(0XD2) ) XDATA( 0X1000-0X2FFF , ?XD?MAIN(0x1002) )

以上两种设置均可,推荐使用LX51,这是新的链接器,性能更好。

#4. MDK的ROM大小

此处主要是针对M0而言。Keil编译之后,在.MAP文件结尾会显示:

Code (inc. data) RO Data RW Data ZI Data Debug

26864 2124 1284 2040 26632 118060 Grand Totals

26864 2124 1284 72 26632 118060 ELF Image Totals (compressed)

26864 2124 1284 72 0 0 ROM Totals

===================================================================

Total RO Size (Code + RO Data) 28148 ( 27.49kB)

Total RW Size (RW Data + ZI Data) 28672 ( 28.00kB)

Total ROM Size (Code + RO Data + RW Data) 28220 ( 27.56kB)


Code,不仅包括生成的代码,还包括inline data, literal pools, and short strings。

RO Data,Read Only data,用const修饰的变量,或是地址定位到RO Data的变量。

ZI Data,Zero Initialie data,编译器进行0初始化的数据。所有未显示初始化,或是显式初始化为0的变量均是ZI Data(包括栈变量和堆变量)。

RW Data,Read Write Data,显式初始化为非0的全局变量。

Total Rom Size即是生成的bin文件大小。ROM Size所包含的RW Data为28220-28148=72,而不是2040。

实际的代码:

int nArr[500] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};


nArr作为RW Data,实际大小有2000B,那么为什么通过ROM计算出的RW Data只有72B呢?

首先,RW Data为什么要记录在ROM中呢?这是因为RW Data的初始化值是编译期生成的,所以这些初始化值要记录在ROM中,这样一上电就能够初始化。正因为只记录初始化的值,所以上面的nArr只初始化了10个值,其他未初始化的其实都没有放进ROM中。所以这才导致了两者的不同。


Total RW Size即运行时存放变量的RAM的大小。

#5. MDK的ROM优化


打开.MAP文件,找到Memory Map of the image处,搜查看是否有PAD,如果存在一些PAD,则可能是多个指定的绝对地址之间有GAP导致的,可以将绝对地址调整对齐PAD的大小然后编译再查看.MAP文件的PAD。


因为Code + RO Data + RW Data + ZI Data将占用整个SRAM(5081为60KB),Code一般不易修改,所以可以动态调整RO Data、RW Data以及ZI Data的分布,只要总的大小不超过60KB即可,来优化ROM的大小。有时ROM存放在EEPROM上,所以适当减少ROM的大小,一些变量转换成ZI Data是一种方法。

#6. MDK的变量绝对地址定位及初始化

##3.1. 关键字__attribute__((at(address)))


const int MAX_LUN_CNT __at(0x2000E000) = 10;      // IROM1

const int MY_COLOR[4] __at(0x2000E004) = {1, 2, 3, 4}; // IROM1

int g_Val __at(0x2000E004); // 正确                 // IROM1

int g_Val1 __at(0x2000E200); // 正确 // IRAM1

// 错误.This is fixed with ARM Compiler V5.06u2, released in combination with MDK-ARM V5.20.

int g_Val __at(0x2000E200) = 10;  // Keil 4编译错误,Keil 5.20编译通过

关键字:C51  MDK  ROM大小  变量  绝对地址  初始化 引用地址:C51和MDK的ROM大小及变量绝对地址初始化

上一篇:Keil C51 Code Banking
下一篇:51单片机学习笔记之中断

推荐阅读

        新浪科技讯 北京时间10月27日早间消息,据美国媒体Buzzfeed援引知情人士消息称,亚马逊已从彭博社网站撤下了第四季度广告投放,而苹果下周的发布会未邀请彭博社报道。知情人士表示,这是两家公司对彭博社有争议报道的报复行动。  消息人士称,亚马逊的数字媒介采买机构Initiative已于10月16日向彭博社销售团队通报,由于预算削减,亚马...
  1 模拟偏置  模拟偏置,也称为DC偏置,是一个非常有用的功能,大多数示波器都具有该功能。如果运用得当,可以避免小信号测试时垂直分辨率的丢失的问题。  模拟偏置给输入的信号加上一个直流偏置电压,如果输入信号超出了示波器ADC的测量范围,加上偏置电压之后,能将信号调节到示波器的范围内。  图1 超出范围的信号  图 2 通过模拟偏置将...
苹果今天分享了一个新广告,该广告旨在突出介绍新 iPhone 12 Pro 和 12 Pro Max 上支持的杜比视界 HDR 视频拍摄,编辑和播放功能。‌iPhone 12 Pro‌ 和 ‌iPhone 12 Pro‌ Max 均支持每秒高达 60 帧的杜比视界 HDR 视频录制,而 iPhone 12 和 12 mini 则支持每秒高达 30 帧的录制。
自从2017年开始,瑞萨电子便开启了买买买的海外扩张路线,以平均每两年一家公司的速度,先后收购了包括Intersil与IDT在内的美国公司以及英国公司Dialog。随着如今对于Dialog的收购完成,新瑞萨将如何扩张?如何继续补充“成功产品组合”?日前,借瑞萨TechDay之际,瑞萨电子中国总裁赖长青、瑞萨电子中国物联网及基础设施事业本部应用技术部高级经理詹仁雄...

史海拾趣

问答坊 | AI 解惑

怎么样学FPGA

最近偶在学习FPGA,但是,没有什么进展! 弱弱的问下,报个班如何呢?? 大家提点意见撒…

查看全部问答∨

监控系统中的各种干扰解决大全

1. 木纹状的干扰   这种干扰的出现,轻微时不会淹没正常图像,而严重时图像就无法观看了(甚至破坏同步)。这种故障现象产生的原因较多也较复杂。大致有如下几种原因:  (1)视频传输线的质量不好,特别是屏蔽性能差(屏蔽网不是质量很好的铜 ...…

查看全部问答∨

关于CListCtrl滚动条换肤的疑问

各位好,我想在wince在把clistctrl的滚动条换肤,可是发现OnNcCalcSize在wince下不能用了,请问大家都是怎么解决的呢?谢谢…

查看全部问答∨

关于过程性连续赋值语句

各位大侠,我想问下,过程性连续赋值语句的最大特点是什么啊?   我还想问下,过程性连续赋值语句对于reg变量是不是不支持啊? 我最近用quartusII仿真程序,在全编译的时候出现procedural continuous assignment to register is not su ...…

查看全部问答∨

=== 请问,CCS的help和tutorial里面好多乱码,怎么解决? ===

我用的是CCS2.2,C6000的tutorial里面, dsp/bios那部分里面好多乱码,尤其是涉及到文件路径的地方 是不是我的系统少装了什么? 谢谢…

查看全部问答∨

【每日一片】Cortex-M4 指令集兼容性

        基于 Cortex-M3 的当前应用如果需要更强的计算能力,Cortex-M4 的引进将会扩展 Cortex-Mx 核心在这方面的应用。各大半导体原厂早已计划将 Cortex-M3 继续升级到 Cortex-M4 ,包括 TI、NXP、S ...…

查看全部问答∨

POS机套件的电源方案

电源方案中,并没有把所有的用上,大家觉得该怎么用这些器件呢?欢迎讨论 …

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

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

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

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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