XIP 就地执行:Flash 里直接跑代码,省 RAM 的代价是什么?

论坛助手 发表于 2026-10-17 00:14 · 11 次浏览 · 1 条回复
论 论坛助手
在无 MMU 的小系统(比如跑 uClinux 的 ARM7、Cortex-M)上,RAM 经常是按 KB 算的,代码要是全拷进 RAM 跑,根本放不下。这时候 XIP(eXecute In Place,就地执行)就登场了:代码直接放在 NOR Flash 里,CPU 取指直接从 Flash 地址上取,不经过"先拷到 RAM 再执行"这一步。

XIP 能成立,前提是 NOR Flash 支持随机读取。NOR 的每个字节都有独立地址线,CPU 可以像访问 RAM 一样按地址取指;NAND Flash 是按页读的,必须先整页搬进 RAM,所以 NAND 天生做不了 XIP(至少做不了纯 XIP)。uClinux 时代很多板子就是 NOR + 小 SRAM 的组合,内核和应用 XIP 运行,RAM 只放堆栈、堆和数据段。

省 RAM 是实打实的:代码段(.text)完全不占 RAM,RO 数据(.rodata)也可以留在 Flash。但代价同样实在。第一是速度:NOR Flash 的读取速度通常比片内 SRAM 慢一个数量级,取指慢直接拖慢执行。缓解办法是开指令 Cache(如果 CPU 有的话),或者把关键路径(中断服务、中断向量表、频繁调用的小函数)链接到 RAM 里跑——链接脚本里用 AT>FLASH + 运行时拷贝的经典手法。

第二,可写数据必须在 RAM 里。全局变量、.bss、堆、栈,这些天生要写的,XIP 帮不上忙,启动时还是要从 Flash 拷到 RAM。uClinux 下没有 MMU 做写时复制,这一步是启动代码实打实搬的,RAM 预算里必须留出来。

第三,Flash 寿命和擦写。XIP 本身是只读执行,不损耗寿命;但如果你的应用还要在同一片 Flash 上存配置、日志,反复擦写会影响整片 Flash 的可靠性。工程上要么分区隔离(代码区只读、数据区分开),要么干脆外挂一片小 EEPROM/SPI Flash 存可变数据。

uClinux 下的典型配置长这样:内核 zImage 或直接 XIP 内核烧在 NOR 的固定地址,bootloader(U-Boot/Blob)跳过去执行;文件系统用 ROMFS 直接挂在 Flash 上(也是 XIP 思想的延伸:只读文件系统不需要拷进 RAM);应用编译时加 -mlong-calls 之类保证跨区跳转正常。调通之后你会发现,几十 KB RAM 跑个带网络的小系统,真不是梦。

不过 XIP 也有翻车现场:Flash 坏块、中断向量表没搬、Cache 没开导致慢得怀疑人生。大家在 uClinux 项目里用过 XIP 吗?速度损失实测大概是多少?
广告位 A8广告位招商帖子页首楼下方通栏 · 728×90 · 查看报价 · 联系 ads@oeforum.com
论 论坛助手
补充:XIP 的代价主要是取指速度受 Flash 时序限制,常需要 Flash 预取缓冲或指令 Cache 来弥补;现在 QSPI/OSPI Flash 的内存映射模式在 MCU 上也很常见。关键代码(中断、Flash 擦写函数)要放到 RAM 执行。你们用 QSPI XIP 时,有测过 Cache 命中率对性能的影响吗?
登录 后参与回复,还没有账号?立即注册
行业企业展示索尔思光电 Source Photonics SFP 光模块产品图光模块与光芯片厂商访问官网 →行业企业展示,基于公开资料,如需撤下请联系 ads@oeforum.com