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

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

3天内不再提示

恩智浦经典LPC系列MCU内部Flash IAP驱动介绍

痞子衡嵌入式 来源:痞子衡嵌入式 2023-03-30 09:19 次阅读

LPC 系列 MCU 是恩智浦公司于 2003 年开始推出的非常具有代表性的产品,距今已经有近 20 年的生命。按时间线演进来说,其主要分为三代:

- 元老:基于 ARM7/9 内核的 LPC2000/3000 系列
- 中坚:基于 Cortex-M0/0+/3/4 内核的 LPC800/1100/1200/1300/1500/1700/1800/4000/4300/54000
- 新锐:基于 Cortex-M33 内核的 LPC5500 系列。

其中坚产品即是痞子衡今天要重点聊的经典 MCU,从其第一颗 LPC1800 到至今仍有新型号出来的 LPC800,仍然深受广大开发者喜爱。今天痞子衡想讨论的是内部 Flash 驱动这个对嵌入式软件开发者来说既冷门又不冷门的话题

Note:本文内容主要以 LPC845 这个型号为例,未必完全适用其它经典 LPC 型号,具体需要查看相应手册。

一、关于MCU内部Flash的基本概念

痞子衡先解释下为什么内部 Flash 驱动这个话题既冷门又不冷门。说它冷门是因为大部分嵌入式软件开发工程师写的应用代码里很少包含 Flash 操作功能(除非应用需要 OTA 升级或者断电保存参数),因此对 Flash 模块的关注度不如其它外设模块。说它不冷门则是在 IDE 中调试或者编程器做量产又离不开 Flash 操作,所以避不可免地关注 Flash 擦写算法、性能、寿命、效率等。

话说回来,Flash 外设一般由两部分组成:Flash 控制器 + Flash Memory 介质,其 Memory 介质部分从原理上属于并行 NOR Flash,MCU 上电 Flash 外设总是使能的,可以通过 AHB 总线直接读取其映射空间内任意 Flash 地址处的数据/指令,所以其最主要的作用就是存储可执行代码。

如果应用程序需要做 OTA 升级,则需要借助 Flash 控制器完成擦除和写入操作。这里就有一些概念性的东西出现了,比如 Flash 擦除正常是按 Block/Sector 为单元(不排除有些支持按 Page 擦除),并且擦除操作是将 Block/Sector 里全部 bit 从 0 恢复为 1。而 Flash 写入则是按 PUnit 为最小单元的(可能是 1/2/4/8 bytes),一次性最多写入一个 Page 的数据(这里指一次完整命令执行等待过程)。擦除和写入操作都不是立刻就完成的,需要等待 Memory 介质更新完成(读 Flash 控制器相应状态位寄存器)。

LPC845 内部 Flash 一共 64KB,划分为 64 个 Sector,每个 Sector 大小为 1KB。每个 Sector 包含 16 个 Page,每个 Page 大小为 64Bytes。支持按 Sector/Page 擦除,IAP 仅支持按 Page 写入(但是控制器底层最小写入单元是 4bytes),不支持 RWW 特性。

    64KB          N/A            N/A           1KB          64Bytes       4Bytes
Flash Memory > Flash Bank >= Flash Block > Flash Sector > Flash Page >= Flash PUnit >= Flash Byte
                   |              |             |              |             |
                RWW单元        擦除单元        擦除单元      最大写入单元    最小写入单元

关于 Flash 擦写操作,还有一个重要概念叫 Read-While-Write(简称 RWW),因为默认代码是执行在 Flash 里,如果我们这个时候还做 Flash 擦写操作,就会让同一个 Flash 处于又做擦写处理同时也要响应 AHB 总线来的读指令请求,大部分 Flash 是无法支持这个特性的,因此常见的操作是将触发 Flash 擦写命令以及读 Flash 状态的代码重定向到 RAM 里去执行。而 LPC 上不一样的 Flash IAP 驱动设计正是为了解决这个 RWW 限制的。

二、一般Flash驱动设计

在讲 LPC Flash IAP 特色驱动之前,我们先来看看一般 MCU 上 Flash 驱动设计,就以恩智浦 Kinetis MK60DN512Z 系列为例。它的 Flash 外设是 FTFL (详见参考手册里 Chapter 28 Flash Memory Module (FTFL) 章节),Flash 大小为 512KB,分为两个 256KB Block (这里就相当于Bank),支持 RWW 特性(以 Block 为单元)。每个 Block 包含 128 个 Sector,每个 Sector 大小为 2KB。它其实没有明确的 Page 概念(但是最大写入单元是专用 4KB FLEXRAM 的一半,可以理解为 Page 大小就是 2KB),支持的最小写入单元是 4bytes。

   512KB         256KB          256KB          2KB            2KB         4Bytes
Flash Memory > Flash Bank >= Flash Block > Flash Sector >= Flash Page > Flash PUnit >= Flash Byte
                   |              |             |              |             |
                RWW单元        擦除单元        擦除单元      最大写入单元    最小写入单元

在官方驱动 SDK_2_2_0_TWR-K60D100MdevicesMK60D10driversfsl_flash.c 里我们重点关注如下 5 个基本函数,这些函数都是直接操作 FTFL 外设寄存器来完成相应 Flash 擦写功能的。其中 flash_command_sequence() 内部函数设计是核心,每一个 API 基本都会调用它,这里面有一个关于解决 RWW 限制的黑科技设计,后面痞子衡会写文章专门介绍。

//一般初始化函数,主要是软件层面初始化
status_tFLASH_Init(flash_config_t*config);
//为了解决RWW限制而特殊设计的命令触发执行函数
status_tFLASH_PrepareExecuteInRamFunctions(flash_config_t*config);
staticstatus_tflash_command_sequence(flash_config_t*config)
//擦除函数,长度不限(需要按Sector对齐),key参数是为了降低误擦除风险
status_tFLASH_Erase(flash_config_t*config,uint32_tstart,uint32_tlengthInBytes,uint32_tkey);
//写入函数,长度不限(仅最小写入单元对齐限制),函数内部自动结合Page和PUnit写入命令做处理
status_tFLASH_Program(flash_config_t*config,uint32_tstart,uint32_t*src,uint32_tlengthInBytes);

三、LPC Flash IAP驱动设计原理

终于来到本文核心 - LPC Flash IAP 驱动了。按照我们一般经验,首先是翻看 LPC845 用户手册寻找 Flash 外设,但是很遗憾,用户手册里并没有 Flash 外设详细介绍,取而代之的是 Chapter 5: LPC84x ISP and IAP 章节。因为 LPC 全系列都包含 BootROM(映射地址为 0x0F00_0000 - 0x0F00_3FFF),而 BootROM 代码里包含了 Flash 擦写驱动,因此官方直接推荐用户调用 ROM 里的 Flash 驱动 API 来完成操作,而不是按照传统方式提供直接操作 Flash 外设寄存器的 SDK 源码。

BootROM 提供的 API 不止 Flash IAP 一个,可以在 Boot Process 章节里如下图里找到全部 API。这里我们可以看到 Flash IAP 函数的统一入口地址是 0x0F001FF1,这在 SDK 里 LPC845_features.h 文件里有如下专门宏:

/*@briefPointertoROMIAPentryfunctions*/
#defineFSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION(0x0F001FF1)
04988e6a-ce98-11ed-bfe3-dac502259ad0.png

有了 IAP 入口地址,调用起来就简单了,芯片用户手册里直接给了参考 C 代码,可以看到 API 设计上将全部支持的 13 个函数集中在一起了,复用了输入参数列表 command_param 和输出结果列表 status_result。痞子衡之前写过一篇 《二代 Kinetis 上的 Flash IAP 设计》,那个 API 接口设计更偏向现代嵌入式软件开发者的习惯,而 LPC Flash IAP 接口设计是 2008 年推出来的,那时候看是超前时代。

unsignedintcommand_param[5];
unsignedintstatus_result[5];

typedefvoid(*IAP)(unsignedint[],unsignedint[]);
#defineIAP_LOCATION*(volatileunsignedint*)(0x0F001FF1)
IAPiap_entry=(IAP)IAP_LOCATION;

iap_entry(command_param,status_result);
04b45f14-ce98-11ed-bfe3-dac502259ad0.png

四、LPC Flash IAP驱动快速上手

最后看一下官方驱动 SDK_2_13_0_LPCXpresso845MAXdevicesLPC845driversfsl_iap.c ,这相当于将 Flash IAP 做了二次封装,我们重点关注如下 6 个基本函数。其中 iap_entry() 最终调用的是 ROM 中代码,直接执行在 ROM 区域,不会和 Flash 访问冲突,天然没有 RWW 限制问题。

擦除函数 IAP_ErasePage()/IAP_EraseSector() 没什么好说的,就是这个写入函数 IAP_CopyRamToFlash() 命名有点绕,不符合一般习惯,然后需要特别注意的是写入长度 numOfBytes 必须是 Page 倍数,且不能超过一个 Sector 大小(但是实测可以横跨两个 Sector 一次性写入多个 Page 数据,所以这仅仅是软件代码人为规定,不是 Flash 控制器限制)。

最后还有一个注意点就是擦写操作都是所谓的 two step process,就是需要先调用一下 IAP_PrepareSectorForWrite() 函数才行,这个设计其实是为了降低程序跑飞出现误擦写的风险。

//一般初始化函数,主要是配置Flash访问时间
voidIAP_ConfigAccessFlashTime(uint32_taccessTime);
//进入ROMIAP的入口函数
staticinlinevoidiap_entry(uint32_t*cmd_param,uint32_t*status_result);
//擦除和写入前准备函数
status_tIAP_PrepareSectorForWrite(uint32_tstartSector,uint32_tendSector);
//擦除函数,按Page/Sector为单位
status_tIAP_ErasePage(uint32_tstartPage,uint32_tendPage,uint32_tsystemCoreClock);
status_tIAP_EraseSector(uint32_tstartSector,uint32_tendSector,uint32_tsystemCoreClock);
//写入函数,长度最大限定为一个Sector
status_tIAP_CopyRamToFlash(uint32_tdstAddr,uint32_t*srcAddr,uint32_tnumOfBytes,uint32_tsystemCoreClock);






审核编辑:刘清

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

    关注

    112

    文章

    16332

    浏览量

    177803
  • 寄存器
    +关注

    关注

    31

    文章

    5336

    浏览量

    120230
  • OTA
    OTA
    +关注

    关注

    7

    文章

    578

    浏览量

    35193
  • NOR flash
    +关注

    关注

    2

    文章

    90

    浏览量

    23003
  • MCU芯片
    +关注

    关注

    3

    文章

    250

    浏览量

    11434

原文标题:为什么说内部Flash驱动是个既冷门又不冷门的话题 | LPC Flash IAP

文章出处:【微信号:pzh_mcu,微信公众号:痞子衡嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    各经销商现提供LPC800开发板

    半导体(纳斯达克代码:NXPI)近日宣布正通过其主要产品经销商提供LPC810和LPC812微控制器的评估样品。LPC800
    发表于 03-06 15:43 2093次阅读

    LPC55S16 MCU获得了PSA 2级和SESIP 2级保证认证

    LPC55S16 MCU属于EdgeVerse™计算和安全产品组合,是基于Arm® Cortex®-M33内核的通用LPC5500
    发表于 11-21 09:28 1754次阅读

    8位MCU P89LPC982 Demo板

    [size=0.83em]8位MCU P89LPC982 Demo板.jpg(72.79 KB, 下载次数: 0)下载附件[color=rgb(153, 153, 153
    发表于 06-12 14:11

    i.MX RTxxx系列MCU的特性

      大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MX RTxxx系列MCU的基本特性。  
    发表于 11-04 07:08

    基于ARM968核的全新LPC292x系列微控制器

    基于ARM968核的全新LPC292x系列微控制器 半导体(NXP Semicon
    发表于 10-13 08:47 956次阅读

    推出基于Cortex-M0微控制LPC1100微控制器

    推出基于Cortex-M0微控制LPC1100微控制器系列 半导体(NXP Sem
    发表于 11-18 09:04 1509次阅读

    LPC2200_flash内部Flash和外部Flash分散加载

    LPC2200_flash内部Flash和外部Flash分散加载示例。
    发表于 05-20 16:08 16次下载

    2009年MCU产品系列总览

    2009年MCU产品系列总览,又需要的下来看看。
    发表于 12-15 15:05 22次下载

    发布新的LPC微控制器系列产品,巩固其在MCU市场的领先地位

    拉斯维加斯 –(CES 2017)– 2017年1月4日 - 半导体NXP Semiconductors N.V.(Nasdaq: NXPI)正以LPC800和LPC54000
    发表于 01-06 15:33 1143次阅读

    无线MCU产品及方案介绍

    无线MCU产品及方案介绍
    发表于 10-16 15:42 9次下载
    <b class='flag-5'>恩</b>智<b class='flag-5'>浦</b>无线<b class='flag-5'>MCU</b>产品及方案<b class='flag-5'>介绍</b>

    关于LPC产品系列的关键功能的介绍(三)

    我们将带您了解LPC800和LPC1100产品系列的关键功能,以及这些低功耗、低成本MCU如何带来与8位架构相比的诸多优势。在本次会议中,我们将探讨如何利用
    的头像 发表于 06-28 19:50 3731次阅读

    关于高性能智能搅拌机的技术介绍

    采用LPC MCU和NFC技术的高性能智能搅拌机
    的头像 发表于 06-28 17:34 4661次阅读

    对比系列MCU的GPIO电平中断设计差异

    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是系列MCU(包含Kinetis,
    的头像 发表于 02-07 09:01 1436次阅读

    新款首发!一站网罗MCU应用程序-AppCodeHub

    内部 MCU 专家们开发的各种应用笔记配套代码(AN SW),通用代码片段,应用软件包(SW Pack)和综合参考例程(Demo),涵盖
    的头像 发表于 08-17 08:45 536次阅读
    新款首发!一站网罗<b class='flag-5'>恩</b>智<b class='flag-5'>浦</b><b class='flag-5'>MCU</b>应用程序-AppCodeHub

    ACH拉近您与MCU专家的距离

    这个 ACH 将会汇聚内部 MCU 专家们开发的各种应用笔记配套代码(AN SW),通用代码片段,应用软件包(SW Pack)和综合参考例程(Demo),涵盖
    的头像 发表于 08-17 15:18 729次阅读
    ACH拉近您与<b class='flag-5'>恩</b>智<b class='flag-5'>浦</b><b class='flag-5'>MCU</b>专家的距离