扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

Keil RT1170 自定义下载算法实操:FlexSPI Flash 烧录方案

7小时前
211
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

NXP i.MX RT1170 通过 FlexSPI 外接 NOR Flash(如 W25Q512N)时,Keil MDK 默认无匹配下载算法,导致程序无法烧录调试。核心解决思路是基于 Keil 自带模板,修改 Flash 属性描述、实现标准编程接口,复用 NXP SDK 的 FlexSPI 驱动,生成专属.FLM 算法文件。本文详解从工程搭建到验证的完整流程,新手也能快速适配任意 FlexSPI NOR Flash。

1. 核心背景与目标

1.1 痛点场景

  • 硬件:RT1170EVKB 开发板 + W25Q512NWEIQ(64MB NOR Flash,FlexSPI1 接口,AHB 映射地址 0x30000000);
  • 问题:Keil 无官方下载算法,更换外部 Flash 后无法烧录调试;
  • 优势:复用 NXP SDK 驱动,无需从零开发 FlexSPI 操作函数,效率翻倍。

1.2 最终目标

生成适配 W25Q512N 的.FLM 下载算法,实现 Keil 环境下 “擦除→编程→验证” 全流程,支持程序烧录与在线调试。

2. 环境准备

2.1 硬件清单

  • 开发板:NXP i.MX RT1170EVKB;
  • 外部 Flash:Winbond W25Q512NWEIQ(64MB,Quad SPI 模式);
  • 调试器:CMSIS-DAP(或 J-Link,本文以 CMSIS-DAP 为例)。

2.2 软件工具

  • IDE:Keil MDK 5.x;
  • SDK:NXP MCUXpresso SDK for RT1170EVKB(含 FlexSPI NOR Flash 驱动);
  • 核心模板:Keil 自带_Template(路径:Keil_v5→ARM→Flash→_Template)。

3. Keil 下载算法核心结构

Keil 自定义下载算法由 3 个核心文件 + 底层驱动组成,结构清晰,无需复杂开发:
  • FlashDev.c:描述 Flash 硬件属性(容量、页大小、地址、超时等),Keil 通过该文件识别 Flash;
  • FlashPrg.c:实现 Keil 标准编程接口(Init、EraseSector、ProgramPage 等),调用 SDK 驱动;
  • FlashOS.h:Keil 提供的接口规范头文件,必须保留,无需修改;
  • 底层驱动:复用 SDK 的flexspi_nor_flash_ops.c,包含 Flash 初始化、擦除、编程等现成函数。

Keil 调用流程

Init()(初始化FlexSPI)→ EraseSector/EraseChip(擦除)→ ProgramPage(编程)→ Verify(校验)

4. 分步构建流程(重点实操)

4.1 工程搭建与配置

(1)复制模板工程

  • 找到 Keil 安装目录下的_Template文件夹,复制到自定义开发目录(如 “RT1170_Flash_Algorithm”);
  • 保留文件夹内所有文件(FlashDev.c、FlashPrg.c、FlashOS.h 等),重命名工程为 “RT1170_W25Q512N.uvprojx”。

(2)工程选项配置

  1. 打开工程,点击「Options for Target」→「Device」,选择 “MIMXRT1176DVMAA:cm7”(匹配 RT1170 内核);
  2. 「C/C++」选项卡:
    • 定义宏:CPU_MIMXRT1176DVMAA_cm7
    • 包含路径:添加 SDK 的 FlexSPI、CMSIS 相关头文件路径(如 “SDK/devices/MIMXRT1176/drivers”“SDK/CMSIS/Core/Include”);
    • 优化等级:设为 “O1”,避免驱动函数被优化失效。

4.2 FlashDev.c 修改(描述 Flash 属性)

核心是让 Keil 识别 W25Q512N 的关键参数,直接替换以下代码:
// W25Q512NWEIQ(64MB,FlexSPI1映射地址0x30000000)
struct FlashDevice const FlashDevice = {
    FLASH_DRV_VERS,          // 驱动版本(固定不变)
    "W25Q512NWEIQ 64MB Flash",// 设备名称(自定义,便于识别)
    EXTSPI,                  // 设备类型:外部SPI/QSPI
    0x30000000,              // AHB映射起始地址(必须与硬件一致)
    0x04000000,              // 设备容量:64MB(0x04000000字节)
    256,                     // 编程页大小:256字节(W25Q512N固定)
    0,                       // 保留参数:设为0
    0xFF,                    // 擦除后默认值:0xFF
    100,                     // 页编程超时:100ms(留足裕量)
    3000,                    // 扇区擦除超时:3000ms(4KB擦除足够用)
    // 扇区布局:全片4KB均匀扇区
    0x001000, 0x00000000,    // 扇区大小4KB(0x1000),起始偏移0
    SECTOR_END               // 扇区布局结束标记
};
  • 关键注意:起始地址、容量、页大小必须与 Flash datasheet 和硬件映射一致,否则烧录失败。

4.3 FlashPrg.c 定制(实现标准接口)

无需开发 FlexSPI 操作,直接调用 SDK 的flexspi_nor_flash_ops.c函数,实现 Keil 要求的 5 个核心接口:
#include "FlashOS.H"
#include "fsl_flexspi.h"
#include "flexspi_nor_flash_ops.h"

#define FLEXSPI_BASE FLEXSPI1       // 对应硬件FlexSPI1
#define FLASH_BASE_ADR 0x30000000   // AHB映射基地址

// 1. 初始化FlexSPI和Flash
int Init(unsigned long adr, unsigned long clk, unsigned long fnc) {
    (void)adr; (void)clk; (void)fnc;
    flexspi_nor_flash_init(FLEXSPI_BASE);  // 复用SDK初始化函数
    return 0;
}

// 2. 反初始化(无需操作,返回0即可)
int UnInit(unsigned long fnc) {
    return 0;
}

// 3. 整片擦除
int EraseChip(void) {
    return flexspi_nor_erase_chip(FLEXSPI_BASE);  // SDK函数
}

// 4. 扇区擦除(adr为Keil传入的AHB地址,需转换为Flash偏移)
int EraseSector(unsigned long adr) {
    return flexspi_nor_flash_erase_sector(FLEXSPI_BASE, adr - FLASH_BASE_ADR);
}

// 5. 页编程(将buf数据写入adr地址)
int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf) {
    return flexspi_nor_flash_page_program(FLEXSPI_BASE, adr - FLASH_BASE_ADR, (uint32_t*)buf);
}
  • 核心技巧:Keil 传入的是 AHB 映射地址,需减去FLASH_BASE_ADR转换为 Flash 内部偏移,否则地址错乱。

4.4 SDK 集成要点

  1. 从 NXP SDK 中复制flexspi_nor_flash_ops.c和对应的头文件(flexspi_nor_flash_ops.h)到工程目录;
  2. 工程中添加这两个文件,确保编译时能链接到flexspi_nor_flash_init等函数;
  3. 若更换其他 Flash(如 W25Q128JVSIQ),只需修改flexspi_nor_flash_ops.c中的 LUT(查找表),无需改动下载算法框架。

4.5 编译生成.FLM 算法文件

  1. 工程选项→「Output」→确认输出文件名(如 “RT1170_W25Q512N.axf”);
  2. 「User」选项卡→「After Build/Rebuild」添加命令:
    cmd.exe /C copy "Objects%L" ".RT1170_W25Q512N.FLM"
    
  3. 点击编译,成功后会在工程目录生成RT1170_W25Q512N.FLM文件;
  4. 将.FLM 文件复制到 Keil 安装目录:Keil_v5→ARM→Flash

5. 验证与调试

  1. 打开 RT1170 的 Keil 工程(如 LED 闪烁例程),配置 FlexSPI NOR Flash 模式;
  2. 工程选项→「Debug」→「Settings」→「Download」→「Add」,选择新增的 “W25Q512NWEIQ 64MB Flash”;
  3. 配置 RAM 用于算法运行:起始地址0x20000000(DTCM),大小0x8000(32KB);
  4. 点击「Load」烧录程序,Keil 会显示 “Erase Done→Programming Done→Verify OK”,验证成功;
  5. 启动调试,可正常设置断点、单步运行,说明算法生效。

6. 关键注意事项

  1. 超时设置:FlashDev.c 中的编程 / 擦除超时需留足裕量(如 W25Q512N 页编程典型 3ms,设为 100ms),避免 Keil 误判失败;
  2. LUT 适配:更换 Flash 型号时,核心是修改flexspi_nor_flash_ops.c的 LUT,确保 FlexSPI 时序匹配;
  3. 地址映射:AHB 映射地址必须与硬件配置一致(RT1170 FlexSPI1 默认 0x30000000);
  4. 工程独立:下载算法工程需单独构建,仅生成.FLM 文件,不参与应用程序编译。
RT1170 Keil 自定义下载算法的核心是 “模板 + SDK 复用”:FlashDev.c 描述硬件属性,FlashPrg.c 实现标准接口,SDK 提供 FlexSPI 底层驱动,三步即可生成专属算法。该方案不仅适配 W25Q512N,更换其他 FlexSPI NOR Flash 时,仅需修改 Flash 属性和 LUT,通用性极强。

相关推荐