Code-data,RO-data,RW-data,ZI-data 程序运行时加载过程
浅谈Keil-MDK创建项目&编译过程
Code-data,RO-data,RW-data,ZI-data 详解
加载过程
RW-data 和 ZI-data 它们仅仅是初始值不一样而已,为什么编译器非要把它们区分开?这就涉及到程序的
存储状态
了,应用程序具有静止状态
和运行状态
。静止态
的程序被存储
在非易失存储器
中,如 STM32 的内部 FLASH,因而系统掉电后也能正常保存。但是当程序在运行状态
的时候,程序常常需要修改
一些暂存数据
,由于运行速度的要求
,这些数据往往存放
在内存
中(RAM),掉电后这些数据会丢失。因此,程序在静止与运行的时候它在存储器中的表现是不一样的图中的左侧是应用程序的存储状态,右侧是运行状态,而上方是 RAM 存储器区域,下方是 ROM 存储器区域。
程序在存储状态时,RO 节(RO section)及 RW 节都被保存在 ROM 区(内部Flash),当然了code区也是存在ROM区。当程序开始运行时,内核直接从 ROM (内部Flash)中读取代码,并且在执行主体代码前,会先执行一段加载代码,它把 RW 节数据从 ROM 复制到 RAM, 并且在 RAM 加入 ZI 节,ZI 节的数据都被初始化为0。加载完后 RAM 区准备完毕,正式开始执行主体程序。
编译生成的 RW-data 的数据属于图中的 RW 节,ZI-data 的数据属于图中的 ZI 节。是否需要掉电保存,这就是把 RW-data 与 ZI-data 区别开来的原因,因为在 RAM 创建数据的时候,默认值为 0(
这里不太准确,堆栈也是在RAM里面的可是未初始化的变量的值是随机值
),但如果有的数据要求初值非 0,那就需要使用 ROM 记录该初始值,运行时再复制到 RAM。STM32 的 RO 区域不需要加载到 SRAM,内核直接从 FLASH 读取指令运行。计算机系统的应用程序运行过程很类似,不过计算机系统的程序在存储状态时位于硬盘,执行的时候甚至会把上述的 RO 区域(代码、只读数据)加载到内存,加快运行速度,还有虚拟内存管理单元(MMU)辅助加载数据,使得可以运行比物理内存还大的应用程序。而 STM32 没 有 MMU,所以无法支持 Linux 和 Windows 系统。
当程序存储到 STM32 芯片的内部 FLASH 时(即 ROM 区),它占用的空间是 Code、RO-data 及 RW-data 的总和,所以如果这些内容比 STM32 芯片的 FLASH 空间大,程序就无法被正常保存了。当程序在执行的时候,需要占用内部 SRAM 空间(即 RAM 区),占用的空间包括 RW-data 和 ZI-data。