代码大小比较:IAR ARM与Keilµ;视野
我目前正在为STM32F103微控制器开发一个小项目,该微控制器具有Cortex-M3 CPU。 由于CMSIS标准头文件,可以使用与IAR和KeilµVision完全相同的代码。正因为如此,我发现比较两种编译器的代码大小(这对于小型微控制器来说是最关键的)很有趣 两个编译器都设置为最大优化级别(针对大小)。不幸的是,我不太清楚IAR和Keil是如何度量代码大小的 例如,IAR为我提供以下输出:代码大小比较:IAR ARM与Keilµ;视野,arm,keil,iar,cortex-m3,Arm,Keil,Iar,Cortex M3,我目前正在为STM32F103微控制器开发一个小项目,该微控制器具有Cortex-M3 CPU。 由于CMSIS标准头文件,可以使用与IAR和KeilµVision完全相同的代码。正因为如此,我发现比较两种编译器的代码大小(这对于小型微控制器来说是最关键的)很有趣 两个编译器都设置为最大优化级别(针对大小)。不幸的是,我不太清楚IAR和Keil是如何度量代码大小的 例如,IAR为我提供以下输出: 868 bytes of readonly code memory 28 by
868 bytes of readonly code memory
28 bytes of readonly data memory
2'056 bytes of readwrite data memory
Keil说:
Program Size: Code=676 RO-data=252 RW-data=0 ZI-data=1640
乍一看,我无法检测到哪些字节与使用的闪存大小有关,哪些与使用的SRAM有关
当然,我知道,闪存是只读的,SRAM是读写的,但在IAR一侧有代码内存
和数据内存
,在Keil一侧有ZI数据
和代码
这里有谁对此有更深入的了解吗?让我们试着以一种系统的方式将其分解。从程序员的角度来看,我们想区分代码(指令)和数据 代码通常存储在某种非易失性存储器(ROM、闪存等)中,并在运行时由处理器内核读取和执行。现代MCU通常从闪存读取指令,但也可以从RAM执行代码。这主要是为了更快地运行代码(因为闪存访问速度相当慢),或者为了实现一些可以更新整个闪存的更新功能。从RAM运行代码也可以用来构造自修改软件,但这是一个相当奇特的用例 当谈到数据时,我们通常首先想到变量,这些变量在运行时(读写)被修改,因此需要存储在随机存取存储器(RAM)中,RAM通常是易失性的(值在断电时丢失)。但要记住的还有更多类型:
- 常数:在运行时不会改变的数据值,例如外围寄存器地址或硬编码延迟时间。这些值需要放入非易失性存储器中,该存储器可以是只读的(例如闪存)
- 初始化变量:程序的大多数变量需要有一个定义的初始值(例如循环计数变量的起始值)。该初始值实际上只是一个常量数据值(见上文),在其生命周期开始时自动复制到其关联变量。由于一个典型的程序需要相当多的初始化值,现代编译器实现了不同的优化方法来减少初始化器的内存占用。这些包括对所有初始化为零的变量进行集群(零初始化),并为非零初始化变量提供不同的数据压缩方法
+---------------------+-----------------------+-------------------+
| Memory Object | IAR term | Keil term |
+---------------------+-----------------------+-------------------+
| Code in ROM | readonly code memory | Code |
| Code in RAM | readwrite code memory | ? |
| Constants in ROM | readonly data memory | RO-Data |
| Initializers in ROM | readonly data memory | (RW-Data) |
| Variables in RAM | readwrite data memory | RW-Data + ZI-Data |
+---------------------+-----------------------+-------------------+
使用IAR计算内存使用非常简单:
- ROM使用率=(只读代码存储器)+(只读数据存储器)
- RAM使用率=(读写代码内存)+(读写数据内存)
- ROM使用率=(代码)+(RO数据)+(RW数据)
- RAM使用率=(RW数据)+(ZI数据)
- 常数:在运行时不会改变的数据值,例如外围寄存器地址或硬编码延迟时间。这些值需要放入非易失性存储器中,该存储器可以是只读的(例如闪存)
- 初始化变量:程序的大多数变量需要有一个定义的初始值(例如循环计数变量的起始值)。该初始值实际上只是一个常量数据值(见上文),在其生命周期开始时自动复制到其关联变量。由于一个典型的程序需要相当多的初始化值,现代编译器实现了不同的优化方法来减少初始化器的内存占用。这些包括对所有初始化为零的变量进行集群(零初始化),并为非零初始化变量提供不同的数据压缩方法
- 让我们试着以系统的方式来分解这一点。从程序员的角度来看,我们想区分代码(指令)和数据
代码通常存储在某种非易失性存储器(ROM、闪存等)中,并在运行时由处理器内核读取和执行。现代MCU通常从闪存读取指令,但也可以从RAM执行代码。这主要是为了更快地运行代码(因为闪存访问速度相当慢),或者为了实现一些可以更新整个闪存的更新功能。从RAM运行代码也可以用来构造自修改软件,但这是一个相当奇特的用例
当谈到数据时,我们通常首先想到变量,这些变量在运行时(读写)被修改,因此需要存储在随机存取存储器(RAM)中,RAM通常是易失性的(值在断电时丢失)。但要记住的还有更多类型:
+---------------------+-----------------------+-------------------+
| Memory Object | IAR term | Keil term |
+---------------------+-----------------------+-------------------+
| Code in ROM | readonly code memory | Code |
| Code in RAM | readwrite code memory | ? |
| Constants in ROM | readonly data memory | RO-Data |
| Initializers in ROM | readonly data memory | (RW-Data) |
| Variables in RAM | readwrite data memory | RW-Data + ZI-Data |
+---------------------+-----------------------+-------------------+
使用IAR计算内存使用非常简单:
- ROM使用率=(只读代码存储器)+(只读数据存储器)
- RAM使用率=(读写代码内存)+(读写数据内存)
- ROM使用率=(代码)+(RO数据)+(RW数据)
- RAM使用率=(RW数据)+(ZI数据)