RP2040在Zephyr+MCUboot下SRAM执行代码触发Hard Fault,如何配置MPU?
RP2040 + Zephyr + MCUboot SRAM执行代码触发Hard Fault问题
背景
我在Zephyr和MCUboot环境下使用RP2040,最终目标是通过UART总线借助MCUMGR实现固件升级。MCUboot采用A/B双槽无缝升级机制:设备重启时,MCUboot会检查是否有新固件,若有则启动新固件;升级过程中,交换算法会将目标固件写入槽0。由于操作Flash的函数不能在Flash中执行(避免擦除自身代码),这类函数必须映射到SRAM中执行,但RP2040默认通过Direct-XIP直接从Flash执行代码。
故障现象
SRAM中的代码无法正常执行:当程序进入位于SRAM的函数(如flash_range_erase)并执行第一条指令时,立即触发Hard Fault。
触发故障的指令:
0x2000c144 <flash_range_erase>: push {r4, r5, r6, r7, lr}
Zephyr崩溃日志:
E: ***** HARD FAULT ***** E: r0/a1: 0x0003d000 r1/a2: 0x00002000 r2/a3: 0x00002000 E: r3/a4: 0x00000000 r12/ip: 0x2000c145 r14/lr: 0x100022e5 E: xpsr: 0x21000000 E: Faulting instruction address (r15/pc): 0x2000c144 E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0 E: Current thread: 0x2000c3d0 (unknown) E: Halting system
验证测试
将flash_range_erase函数从SRAM移回Flash执行(移除指定函数存放位置的宏),函数可正常运行,确定是MPU不允许SRAM执行代码导致的故障。
修改前代码(放在SRAM):
void __no_inline_not_in_flash_func(flash_range_erase)(uint32_t flash_offs, size_t count) { ... }
修改后代码(放在Flash):
void flash_range_erase(uint32_t flash_offs, size_t count) { ... }
尝试的解决方法
尝试通过设备树overlay配置SRAM的MPU属性,添加以下配置后问题未解决:
&sram0 { /delete-property/ compatible ; /delete-property/ reg ; compatible = "zephyr,memory-region", "mmio-sram"; zephyr,memory-region = "RAM_EXECUTABLE"; zephyr,memory-region-mpu = "RAM"; reg = < 0x20000000 0x10000 >; //Configure SRAM for MCUboot fixed for MPU // RAM size has to match with BOOTLOADER_SRAM_SIZE (see menuconfig) };
问题
- MPU会导致这种Hard Fault吗?
- 如何在Zephyr中配置SRAM以允许从SRAM执行代码?
内容的提问来源于stack exchange,提问作者Thisora
相关产品推荐
相关产品推荐

