经常听到程序代码可在NOR Flash上运行,而不能在NAND Flash上运行的说法,关于这个说法容易给人造成误解,因为CPU执行代码分为取指、译码、执行三个步骤,所以真正运行代码的还是CPU,对于NOR Flash可以直接运行代码的说法,指的是CPU可以直接通过地址总线从NOR Flash上完成取指的操作。更深入的理解这个概念,我们先了解以下知识点。
1.FLASH存储器
FLASH 存储器又称为闪存,它也是可重复擦写的存储器。根据存储单元电路的不同,FLASH存储器又分为 NOR FLASH 和 NAND FLASH,其二者特性对比如表所示:
NOR与NAND特性的差别,主要是由于其内部“地址/数据线”是否分开导致的。由于 NOR的地址线和数据线分开,它可以按“字节”读写数据,符合 CPU 的指令译码执行要求,所以假如 NOR上存储了代码指令, CPU 给 NOR一个地址, NOR 就能向
CPU 返回一个数据让 CPU 执行,中间不需要额外的处理操作。
而由于 NAND 的数据和地址线共用,只能按“块”来读写数据,假如 NAND 上存储了代码指令, CPU 给 NAND 地址后,它无法直接返回该地址的数据,所以不符合指令译码要求。 即不支持立即执行的特性(eXecute In Place),若代码存储在NAND上,可以先把它加载到RAM存储器上,再由CPU执行。
注:由于Flash擦写通常是整块擦写,块内有一位失效整个块就会失效,这被称为坏块,而Nor 和 Nand Flash都有可能存在坏块,所以Flash存储器需要“探测/错误更正(EDC/ECC)”算法来确保数据的正确性。
2.XIP( eXecute In Place)
XIP,executed in place,本地执行。操作系统采用这种系统,可以不用将内核或执行代码拷贝到内存,而直接在代码的存储空间(Nor Flash)直接运行。采用这样的技术既可以节省可用内存又可以减少加载的时间。由于Nand Flash的特性不支持XIP,所以不能在 Nand Flash中运行代码。
代码执行流程如上图所示,其中NAND Flash执行代码时,需要先将代码加载到RAM中,CPU再从RAM中取指、译码、运行。而NOR Flash支持XIP,CPU可以直接通过总线从NOR Flash中取指,不需要将代码加载到RAM中运行。
3.分散加载
首先我们简单了解下MDK的编译过程,它与其它编译器的工作过程是类似的,该过程见图。
在工程的编译提示输出信息中有一个语句"Program Size:Code=xx RO-data=xx RW-data=xx ZI-data=xx",它说明了程序各个域的大小,编译后,应用程序中所有具有同一性质的数据(包括代码)被归到一个域,程序在存储或运行的时候,不同的域会呈现不同的状态,这些域的意义如下
详细的MDK编译过程及文件类型全解可参考野火大哥的博客https://www.cnblogs.com/firege/p/5806134.html