XIP概念

XIP (eXecute In Place),中文常译为 “原地执行” 或 “就地执行”。它指的是 CPU 能够直接从存储代码的非易失性存储器(通常是 Flash 存储器,如 NOR Flash---为什么是NOR Flash,而不是NAND Flash,NOR Flash 支持随机访问,读写速度快,特别适合直接执行代码。而 NAND Flash 更适合大容量存储,随机访问能力差)中读取指令并执行,而无需事先将代码复制到 RAM中

系统上电启动流程

系统上电会对RAM初始化,初始化的目的是1.初始化堆栈以及存储变量,2.初始化内存控制器,3.设置栈指针SP,4.把主程序从 Flash 搬到 RAM(这一步可以省略,如果省略就是XIP执行,XIP 跑程序虽然比 RAM 慢点,但好处是省钱。很多嵌入式应用,比如智能电表、工业传感器,性能要求不高,但对成本敏感,XIP 就派上用场了);这部分大多使用汇编(一是C语言依赖栈来存储变量,二是汇编执行效率高),例如keil或IAR自带的启动文件startup.s

加载地址和执行地址

1.对于 XIP 代码,加载地址和执行地址是一样的,存在 Flash 里,跑也在 Flash 里
2.而非 XIP 代码,加载地址在 Flash,执行地址在 SRAM,得靠启动代码或者链接器脚本搬过去
3.XIP 部分的代码直接在 Flash 里跑,地址不变;而非 XIP 部分,比如某个关键函数,可能被搬到SRAM 里跑,以提高速度
假设你写了个 C 函数,特别关键,要求执行速度快。你希望它运行在 SRAM 里,而不是 Flash。链接器会把这个函数的加载地址(Flash 里的位置)和执行地址(SRAM 里的位置)分开。开机后,启动代码负责把这个函数从 Flash 搬到 SRAM,然后程序跳转过去执行。这就不属于 XIP,因为加载地址和执行地址不一样
反过来,如果你的代码直接在 Flash 里跑,地址没变,那就是 XIP。比如,很多 RTOS 的内核代码会选择直接从 Flash 运行,省下 SRAM 给任务栈和动态数据

实现XIP

Keil、IAR 或者 GCC,都有办法控制代码的加载和执行地址
1.链接器命令:用 -RO(只读)和 -RW(读写)选项,指定代码和数据的执行地址。比如在 Keil 里,你可以在 Target 设置里调整这些参数
2.分散加载文件(Scatter File):更灵活的方式,通过写散文件(scatter file)精确控制每个段的加载和执行地址。国内很多做复杂项目的工程师都喜欢用散文件,因为它能细粒度地管理内存布局

免责声明
本文部分内容参考自微信公众号 【立芯嵌入式】 的原创文章,版权归原作者所有,本文仅用于学习与交流目的。
如有不妥之处,烦请原作者联系指正,我将第一时间修改或删除相关内容
本文仅代表个人观点,不构成任何商业用途。如涉及版权等问题,请联系本人处理。