i.MX RT1064 作为 NXP 高性能跨界 MCU,内置 4MB 片上 Flash 的同时保留外置 QSPI Flash 接口,可满足大型应用的存储需求。默认情况下,RT1064 从内部 Flash 启动,SDK 例程也仅适配内部存储,本文详解如何复用 RT1060-EVK 的 Flash 驱动,实现外置 Flash 的编程与 XIP(就地执行)调试,无需额外开发驱动,直接在 RT1064-EVK 上验证外置存储方案。
1. 核心原理与环境准备
1.1 关键前提:硬件兼容性
RT1064-EVK 与 RT1060-EVK 的外置 QSPI Flash 硬件配置完全一致,包括引脚连接、Flash IC 型号,因此 RT1060-EVK 的 Flash 驱动可直接复用,无需修改硬件或驱动代码。
1.2 软硬件环境
- 硬件:NXP MIMXRT1064-EVK 开发板(板载外置 QSPI Flash)、USB 调试线;
- 软件:MCUXpresso IDE、RT1064 SDK、RT1060-EVK Flash 驱动(IDE 内置);
- 核心工具:GUI Flash Programmer(MCUXpresso IDE 集成)、串口终端(辅助调试)。
1.3 XIP 核心概念
XIP 即代码在 Flash 中直接执行,无需加载到 RAM,节省 RAM 资源的同时支持大型程序运行。RT1064 外置 QSPI Flash 的 XIP 地址为
0x60000000,需将应用程序链接到该地址区间。2. 分步实现流程
2.1 工程配置:适配外置 Flash
(1)选择 SDK 例程并修改地址
- 从 RT1064 SDK 中选择任意例程(如
hello_world、dcp),以evkmimxrt1064_dcp为例; - 修改工程内存配置:打开
MCU Settings,将程序 Flash 地址改为0x60000000(外置 QSPI Flash 起始地址); - 替换 Flash 驱动:在工程配置中选择
RT1060_SFDP作为 Flash 驱动(复用 RT1060-EVK 的驱动)。
(2)注释 FlexSPI1 重复初始化代码
RT1064 SDK 例程默认会重新初始化 FlexSPI1 接口(连接外置 Flash),但 XIP 模式下代码正从该 Flash 读取,实时初始化会导致程序跑飞,需修改
clock_config.c:// 注释掉以下FlexSPI1时钟初始化代码
// CLOCK_SetDiv(kCLOCK_Flexspi1PreDiv, 7);
// CLOCK_SetDiv(kCLOCK_Flexspi1Div, 2);
// CLOCK_SetMux(kCLOCK_Flexspi1Mux, 0);
2.2 烧录应用程序到外置 Flash
(1)编译工程
完成配置后编译工程,生成
.axf(调试文件)和.bin(二进制文件)。(2)使用 GUI Flash Programmer 烧录
- 打开 MCUXpresso IDE 的
GUI Flash Programmer; - 选择调试探针(如 LinkServer/CMSIS-DAP),连接 RT1064-EVK;
- 选择烧录文件:选中编译生成的
.axf或.bin文件; - 确认 Flash 驱动:确保驱动为
RT1060_SFDP,烧录地址为0x60000000; - 点击 “Program” 开始烧录,日志显示 “Finished writing Flash successfully” 即完成。
2.3 制作并烧录 Bootloader(实现启动跳转)
RT1064 默认从内部 Flash 启动,需在内部 Flash 烧录一个简易 Bootloader,实现从内部 Flash 跳转到外置 Flash 的 XIP 应用。
(1)基于 SDK 例程改造 Bootloader
- 选择
evkmimxrt1064_flexspi_nor_polling_transfer例程(已初始化 FlexSPI1 接口); - 添加串口轮询等待(避免外置 Flash 未烧录时误跳转);
- 增加跳转代码,指向外置 Flash 中应用的入口地址:
#define APP_START 0x60000000 // 外置Flash XIP起始地址 typedef void (*app_func_t)(void); void bootloader_jump(void) { app_func_t app_entry; uint32_t app_stack; // 读取应用栈顶地址(XIP地址+4) app_stack = *(uint32_t *)(APP_START); // 读取应用入口地址(XIP地址+8) app_entry = (app_func_t)*(uint32_t *)(APP_START + 4); // 初始化应用栈 __set_MSP(app_stack); // 跳转到应用程序 app_entry(); } int main(void) { // 初始化串口(用于轮询等待) BOARD_InitUART(); PRINTF("Press any key to jump to external Flash...n"); // 等待串口输入,确认外置Flash已烧录应用 getchar(); // 执行跳转 bootloader_jump(); while (1); }
(2)获取应用入口地址
编译外置 Flash 应用后,打开工程生成的
zephyr.map(或.map)文件,搜索_Vectors(向量表起始地址),该地址即为应用入口地址(示例:0x60001030),需同步更新到 Bootloader 的跳转地址中。(3)烧录 Bootloader 到内部 Flash
- 将 Bootloader 工程的 Flash 地址设为内部 Flash 默认地址(
0x00000000); - 编译后通过 MCUXpresso IDE 烧录到 RT1064 内部 Flash。
2.4 XIP 调试配置与验证
(1)IDE 调试设置
- 打开外置 Flash 应用工程(如
evkmimxrt1064_dcp),进入调试配置; - 选择调试探针,确认 Flash 驱动为
RT1060_SFDP; - 勾选 “Reset target after programming”,确保调试时 MCU 重启并执行 Bootloader。
(2)启动调试流程
- 连接 RT1064-EVK 到 PC,打开串口终端(波特率与 Bootloader 配置一致);
- 点击 MCUXpresso IDE 的 “Debug” 按钮,烧录应用到外置 Flash;
- 串口终端提示 “Press any key to jump to external Flash...”,输入任意字符触发跳转;
- IDE 将自动断点在应用程序的
main函数,此时代码已在外部 Flash 中 XIP 执行。
(3)功能验证
- 单步调试:可正常执行代码、查看变量、监控外设状态;
- 运行验证:应用程序正常输出日志(如 DCP AES 测试通过),说明 XIP 调试成功。
3. 关键避坑事项
- 地址配置准确:外置 Flash XIP 地址固定为
0x60000000,工程链接地址与 Bootloader 跳转地址需一致; - 驱动选择正确:必须选择
RT1060_SFDP驱动,不可使用 RT1064 默认的内部 Flash 驱动; - 跳过 FlexSPI 初始化:XIP 模式下重复初始化 FlexSPI1 会导致代码读取失败,务必注释相关代码;
- Bootloader 跳转地址:需从应用
map文件中获取实际入口地址(非固定0x60000000,需包含向量表偏移); - 串口轮询必要:避免外置 Flash 未烧录应用时,Bootloader 直接跳转导致程序卡死。
阅读全文
268