0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何在Keil中添加Flash烧写算法

恩智浦MCU加油站 来源:恩智浦MCU加油站 作者:恩智浦MCU加油站 2022-09-01 08:43 次阅读

Flash,相信大家一定都不陌生,作为一种非易失性内存,其显著特点就是即便系统掉电,其上的存储内容也不会丢失。也正因如此,其作为程序存储介质而被广泛应用。

当然,也有他的弊端或者说不便利性,那就是Flash的读写操作往往不是那么的招人“喜欢”。即便是Nor Flash,也仅仅是能够实现按地址的随机读操作,而不能实现随机写。而且,数据的写入往往都是基于块操作的,也就是说,想要将数据写入flash中,即便只想更新哪怕一个字节,也要对一整个块来操作。并且要执行类似于:先擦除再写入的操作。

而既然我们想要将程序烧写到flash中,那不可避免地就要编写相应的flash操作程序来辅助实现。

本期小编就将为大家介绍下,如何在Keil中添加Flash烧写算法,能够让Keil帮助我们进行程序的烧写工作。

何为FLM文件

回想一下,在Keil这款IDE中,如果想要将程序烧写到Flash中,首先要干的一步就是打开项目属性页要选择合适的flash下载算法,而这个算法本身就是一个FLM文件:

1ecbb5dc-298e-11ed-ba43-dac502259ad0.png

FLM文件结构

那么FLM文件是怎么构成呢?Keil规定,一个FLM文件中一般要有以下函数:

1ef2b68c-298e-11ed-ba43-dac502259ad0.png

其中最为重要的有5个,我们来一一说明:

int Init (unsigned long adr, unsigned long clk, unsigned long fnc);负责flash器件的初始化工作,其中:
a)adr: 设备首地址
b)clk:时钟频率(Hz)
c)fnc:要执行的flash操作,包括,1:Erase,2:Program,3:Verify

int EraseSector (unsigned long adr);擦除addr所指定地址处的整个sector

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf);对flash进行烧写操作,其中:
a)adr:待烧写地址
b)sz:待烧写数据长度
c)bug:待烧写数据

int EraseChip (void); 擦除整块flash

int UnInit (unsigned long fnc); Uninit flash, 并根据传入的fnc执行不同的flash后操作,fnc的定义同Init

编写FLM文件

Keil很贴心的为我们准备了一个模板工程,可以以说包含了生成一个FLM文件的所有,工程文件位置在 Keil安装目录ARMFlash\_Template:

1f157a6e-298e-11ed-ba43-dac502259ad0.png

我们所需要修改的就是FlashDev.c以及FlashPrg.c两个文件,为了方便测试,小编就直接在i.MX RT1170 EVK上挂载的IS25WP128-JBLE Flash为例进行说明。

首先是FlashDev.c文件,这里面主要提供了一些Flash的基本硬件信息,定义了诸如Flash器件名,sector大小,写入块大小等,参考实现如下:

struct FlashDevice const FlashDevice  =  {
   FLASH_DRV_VERS,     // 别改!!!
   "IS25WP128-JBLE",   // 简单粗暴,直接定义
   EXTSPI,             // 设备类型,可选:ONCHIP, EXT8BIT, EXT16BIT, 
                       // EXT32BIT, EXTSPI
   0x30000000,         // Flash首地址,挂载到AHB总线的地址
   0x01000000,         // Flash大小,16MB
   256,                // 烧写Page 大小
   0,                  // Reserved, must be 0
   0xFF,               // Initial Content of Erased Memory
   100,                // Program Page Timeout 100 mSec
   3000,               // Erase Sector Timeout 3000 mSec

   0x001000, 0x000000, // Sector 大小  4KB
   SECTOR_END
};
接下来是FlashPrg.c,负责实现与Flash操作有关的所有函数。这里,让我们继续发扬大树下好乘凉的优良传统。下载RT1170_EVK最新SDK代码,找到基于flexspi的nor flash工程:boardsevkmimxrt1170driver_examplesflexspi orpolling_transfercm7,这里有一个flexspi_nor_flash_ops.c,里面已经包含了所有flash操作相关的操作函数,不过文件中缺少了FlexSPI引脚的初始化代码,需要进行添加:
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_05_FLEXSPI1_A_DQS, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_06_FLEXSPI1_A_SS0_B, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_07_FLEXSPI1_A_SCLK, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_08_FLEXSPI1_A_DATA00, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_09_FLEXSPI1_A_DATA01, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_10_FLEXSPI1_A_DATA02, 1U);
IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B2_11_FLEXSPI1_A_DATA03, 1U);

IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_05_FLEXSPI1_A_DQS,   0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_06_FLEXSPI1_A_SS0_B,  0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_07_FLEXSPI1_A_SCLK,  0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_08_FLEXSPI1_A_DATA00, 0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_09_FLEXSPI1_A_DATA01, 0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_10_FLEXSPI1_A_DATA02, 0x0AU);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B2_11_FLEXSPI1_A_DATA03, 0x0AU);

到void flexspi_nor_flash_init(FLEXSPI_Type *base)函数中。

修改好之后,将文件拷贝并添加到我们刚才找到的FLM工程中,当然还要将原SDK工程中的app.h文件一并拷贝过来。由于需要用到flexspi的底层操作,还需要添加fsl_flexspi.c文件,添加好后的工程长这个样子:

1f2a1ae6-298e-11ed-ba43-dac502259ad0.png

接下来就是修改FlashPrg.c,首先添加头文件以及函数引用:

#include "fsl_flexspi.h"
#include "app.h" 
extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
extern void flexspi_nor_flash_init(FLEXSPI_Type *base);
#define FLEXSPI_BASE (FLEXSPI1)
#define FLASH_BASE_ADR (0x30000000)

接下来是相应函数的实现,这里有一点需要注意,针对函数传入的adr即地址变量,实际上已经被转换为了映射到AHB总线上的地址,而我们对于Flash的操作都是基于Flash本身的地址而言的,因此需要做一个简单的转换,减去一个偏移量(FLASH_BASE_ADR):

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  (void)adr;
  (void)clk;
  (void)fnc;
  flexspi_nor_flash_init(FLEXSPI_BASE);
  return (0); 
}
int UnInit (unsigned long fnc) {
  return (0);                                 
}
int EraseChip (void) {
  return (flexspi_nor_erase_chip(FLEXSPI_BASE)); 
}
int EraseSector (unsigned long adr) {
  return (flexspi_nor_flash_erase_sector(FLEXSPI_BASE, adr - FLASH_BASE_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));                                  
}

至此,我们就完成了所有的代码准备工作。当然,为了让程序能够正常编译,还需要对工程进行配置,其中最主要的是头文件路径以及预编译符号的添加,右键工程属性并添加:

1f512852-298e-11ed-ba43-dac502259ad0.png

头文件路径:

1f84fc04-298e-11ed-ba43-dac502259ad0.png

为输出文件起一个专属名字:

1fafd4a6-298e-11ed-ba43-dac502259ad0.png

选择正确的芯片类型为MIMXRT1170DVMAA:cm7:

1fd0fe06-298e-11ed-ba43-dac502259ad0.png

这样,就完成了所有的准备工作,接下来就是熟悉的编译链接,不过注意,不能点击运行按钮。在当前目录下,找到生成的rt1170_validation_board.FLM, 并将其拷贝到Keil安装目录ARMFlash下。

接下来进行测试,我们直接打开SDK中hello world工程,在工程属性中打开Flash下载页面,点击Add按钮即可看到我们所添加的Flash算法并确定:

1ff69a08-298e-11ed-ba43-dac502259ad0.png

之后就是正常的编译链接烧写之路,最终显示:

221e1dc4-298e-11ed-ba43-dac502259ad0.png

证明我们已经烧写成功,之后进行调试即可正常调试。

22312f36-298e-11ed-ba43-dac502259ad0.png

至此,我们就完成了FLM文件的编写,并且在hello_world的工程中进行了测试。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    117

    文章

    3788

    浏览量

    81094
  • keil
    +关注

    关注

    68

    文章

    1213

    浏览量

    166938
  • 烧写
    +关注

    关注

    0

    文章

    57

    浏览量

    14305

原文标题:编写Keil的自定义Flash烧写算法FLM

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    28335flash的问题

    本帖最后由 smileicy 于 2015-4-21 13:02 编辑 数次flash,都没有成功,我的步骤是:一:删除283
    发表于 04-21 12:51

    单片机如何在flash运行程序

    ——————————————————————————————1、单片机如何在flash运行程序以C8051F系列为例,单片机的程序经过keil等IDLE软件编译成hex文件,然后通过
    发表于 01-24 07:07

    TMS320F2812片内Flash在线技术

    基于TMS320F2812内部Flash在线技术,提出了一种串口Flash技术。详细论述
    发表于 12-20 17:02 57次下载

    基于CCS的DSP片外Flash直接设计

    基于CCS的DSP片外Flash直接设计 自加载后DSP能够正常运行,关键是Flash中原程序代码的正确
    发表于 10-04 09:41 3358次阅读
    基于CCS的DSP片外<b class='flag-5'>Flash</b>直接<b class='flag-5'>烧</b><b class='flag-5'>写</b>设计

    JTAG接口在线Flash的实现

    本文阐述了一种针对TMS320VC5509A DSP 简单有效的Flash 方法, 并提出了程序自举引导的实现方法。可以有效地解决程序代码存储问题和DSP 脱机自举问题.
    发表于 09-16 14:43 1.6w次阅读
    JTAG接口在线<b class='flag-5'>烧</b><b class='flag-5'>写</b><b class='flag-5'>Flash</b>的实现

    CCS4向内置flash程序过程

    用CCS4向内置flash程序过程这期间要用到100V2仿真器
    发表于 12-04 14:44 18次下载

    FPGA配置– 使用JTAG是如何SPI/BPI Flash的?

    Xilinx的JTAG电缆可以通过FPGA“直接”SPI/BPI。很多对xilinx开发环境不熟悉的用户,如果第一次接触这种模式可能会有疑惑,FPGA是如何做到JTAG和
    发表于 02-08 02:40 8444次阅读
    FPGA配置– 使用JTAG是如何<b class='flag-5'>烧</b><b class='flag-5'>写</b>SPI/BPI <b class='flag-5'>Flash</b>的?

    使用JTAGNand Flash实验解析

    4.4 实验内容使用JTAGNand Flash 1.实验目的 通过使用JTAGFlash
    发表于 10-18 17:03 6次下载
    使用JTAG<b class='flag-5'>烧</b><b class='flag-5'>写</b>Nand <b class='flag-5'>Flash</b>实验解析

    基于DSP虹膜识别系统Flash方法的研究

    基于DSP虹膜识别系统Flash方法的研究
    发表于 10-19 14:41 2次下载
    基于DSP虹膜识别系统<b class='flag-5'>中</b><b class='flag-5'>Flash</b><b class='flag-5'>烧</b><b class='flag-5'>写</b>方法的研究

    CCS的DSP片外Flash直接设计

    CCS的DSP片外Flash直接设计
    发表于 10-20 08:29 3次下载
    CCS的DSP片外<b class='flag-5'>Flash</b>直接<b class='flag-5'>烧</b><b class='flag-5'>写</b>设计

    如何采用DATA进行Flash的在线

    自加载后DSP能够正常运行,关键是Flash中原程序代码的正确。CCS编译生成的.out格式文件不能直接用于Flash
    的头像 发表于 02-06 08:51 3655次阅读
    如何采用DATA进行<b class='flag-5'>Flash</b>的在线<b class='flag-5'>烧</b><b class='flag-5'>写</b>

    KeilSTM32F750内部Flash的方法有哪些

    库中大部分都是提供使用外部 QSPI Flash 的例程,导致有些用户不清楚如何在 ARM Keil 对其内部 Flash 进行
    发表于 07-13 08:00 13次下载
    <b class='flag-5'>Keil</b><b class='flag-5'>中</b><b class='flag-5'>烧</b><b class='flag-5'>写</b>STM32F750内部<b class='flag-5'>Flash</b>的方法有哪些

    Keil MDK下的串行Flash下载算法设计

    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是Keil MDK工具下i.MXRT的串行NOR Flash下载算法设计。 在i.MXRT硬件那些事系列之《在串行NOR Flas
    的头像 发表于 10-23 14:30 2935次阅读
    <b class='flag-5'>Keil</b> MDK下的串行<b class='flag-5'>Flash</b>下载<b class='flag-5'>算法</b>设计

    Jlink使用技巧之SPI Flash存储芯片

    大多数玩单片机的人都知道Jlink可以Hex文件,作为ARM仿真调试器,但是知道能SPI Flash的人应该不多,本篇文章将介绍如何
    发表于 01-26 18:37 4次下载
    Jlink使用技巧之<b class='flag-5'>烧</b><b class='flag-5'>写</b>SPI <b class='flag-5'>Flash</b>存储芯片

    可供用户修改的FLASH驱动介绍

    程序。程序通过与 V8MON 进行数据交互进行 FLASH 探测,FLASH 擦除,FLASH 操作。由于
    发表于 06-08 14:39 0次下载
    可供用户修改的<b class='flag-5'>FLASH</b><b class='flag-5'>烧</b><b class='flag-5'>写</b>驱动介绍