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

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

3天内不再提示

你是否真的会在Flash上存数据?

硬件攻城狮 来源:工程师的废纸篓 作者:工程师的废纸篓 2022-09-20 14:17 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在应用编程(IAP)应该是MCU使用过程中常见的一种功能,MCU厂商为了加速用户的产品开发,都会在其SDK中添加相关示例,而且也有不少用户只需要简单的集成,就完成了该功能并实现产品的量产。但你是否真的会在Flash上存数据?

首先我们需要从片内和片外存储谈起,MCU内部的非易失性存储器绝大多数都是基于FLASH的(也有少部分是EEPROM的,比如NXP LPC80x系列),MCU外部的非易失性存储器可以有FLASH,EEPROM,其中EEPROM比较常见的是I2C接口,FLASH有NAND, NOR, SPI NOR等等。

实际应该过程中,我们到底应该怎么选择呢?需要存储的数据量大小是首要问题,我们可以根据它来大致设定规则

7b84d120-38aa-11ed-ba43-dac502259ad0.png
  1. 当数据量大于128MB时,NAND FLASH或者SD(TF)卡是常见的选择,但考虑到NAND FLASH会有坏块的问题,编写存储软件时需要考虑磨损均衡已经坏块管理的问题,想要做的非常可靠并不容易。

  2. 当数据量小于128MB,大于2MB时,可以选择NOR FLASH或EEPROM,EEPROM技术上的优势是耐久性好,可以反复多次编程,最高可达100W次的擦写循环,NOR FLASH相比EEPROM容量会更大,平均成本更好,但是寿命会少个0,最大只能到10W次的擦写循环。

    EEPROM(AT24C02)

    7bb1fba0-38aa-11ed-ba43-dac502259ad0.png

    FLASH(IS25WP032)

    7bf6657e-38aa-11ed-ba43-dac502259ad0.png
  3. 当数据量小于2MB时,就可以考虑将其放入MCU内部的FLASH中,一旦决定把数据放MCU内部FLASH时,就面临两个问题:

    (1)MCU片内FLASH承诺的寿命更短,一般可能是1~5W次,好像也有几百次的,鉴于大佬已经停线,这里就不点名了。关于这个参数切记要参考手册,不同厂家的参数不一样,同一厂家的不同系列也可能有差异

    NXP Kinetis系列MCU

    7c1b6d9c-38aa-11ed-ba43-dac502259ad0.png

    STM32 F103xx

    7c36996e-38aa-11ed-ba43-dac502259ad0.png

    (2) 擦写过程可能需要关闭中断,虽然这个不是必须的,但除非MCU的Datasheet明确有写支持,绝大多数MCU都是有这方面的要求,并且IAP编程的函数需要运行于RAM或ROM中,因为擦写过程中,如果MCU没有特殊的设计(比如下图NXP KinetisK64系列带有双Block flash是可以支持WWR),该过程是无法进行取指的,关中断的目的是防止外部中断触发运行于FLASH上的ISR,如果用户不希望关中断,则必须要将可能发生中断的函数Relocate到RAM中

    7c54676e-38aa-11ed-ba43-dac502259ad0.png
    //RAM中执行的编程函数
    static status_t flash_command_sequence(flash_config_t *config)
    {
        uint8_t registerValue;
    
    __set_PRIMASK(1);
    
    #if FLASH_DRIVER_IS_FLASH_RESIDENT
        /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
        FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
    
        status_t returnCode = flash_check_execute_in_ram_function_info(config);
        if (kStatus_FLASH_Success != returnCode)
        {
        __set_PRIMASK(0);
            return returnCode;
        }
    
        /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using
         * pre-processed MICRO sentences or operating global variable in flash_run_comamnd()
         * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */
        callFlashRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT));
    __set_PRIMASK(0);
    #else
        /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */
        FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK;
    
        /* clear CCIF bit */
        FTFx->FSTAT = FTFx_FSTAT_CCIF_MASK;
    
        /* Check CCIF bit of the flash status register, wait till it is set.
         * IP team indicates that this loop will always complete. */
        while (!(FTFx->FSTAT & FTFx_FSTAT_CCIF_MASK))
        {
        }
    #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */
    
        /* Check error bits */
        /* Get flash status register value */
        registerValue = FTFx->FSTAT;
    
        /* checking access error */
        if (registerValue & FTFx_FSTAT_ACCERR_MASK)
        {
        __set_PRIMASK(0);
            return kStatus_FLASH_AccessError;
        }
        /* checking protection error */
        else if (registerValue & FTFx_FSTAT_FPVIOL_MASK)
        {
        __set_PRIMASK(0);
            return kStatus_FLASH_ProtectionViolation;
        }
        /* checking MGSTAT0 non-correctable error */
        else if (registerValue & FTFx_FSTAT_MGSTAT0_MASK)
        {
        __set_PRIMASK(0);
            return kStatus_FLASH_CommandFailure;
        }
        else
        {
        __set_PRIMASK(0);
            return kStatus_FLASH_Success;
        }
    }
    

    (3) 擦写时间对系统的影响,之前讲过擦写过程是不能执行FLASH code的,所以势必会让系统pending住,而这个pending时间可以在Datasheet中寻找答案,一般擦除是按照sector/block大小来的,编程时按照word或者page大小来的,擦除时间一般更长,对系统影响更大。用户需要考虑的是系统是否可以接受每个控制周期,等待1个擦除最小单位的编程时间,这是由于有可能需要编程的数据比较大,如果同一时间更新势必会影响到控制周期,但如果把擦写任务分配到每个控制周期,就可以将影响降低到最小,以NXPKinetis,擦除一个Sector典型值是14ms,每次写入Longword(8字节)所需要的时间是65us,当需要升级的时候,在接收到升级命令的第一帧处理时,增加sector删除命令,本次运算周期会增加14ms的pending时间,然后每周期编程8字节数据。如果系统需要将数据存在内部flash上,就必须接受某一个周期增加14ms的pending,随着flash写入次数的增多,14ms还会增大到114ms

    7c7f3b88-38aa-11ed-ba43-dac502259ad0.png

在确定了上述问题之后就可以完成存储设备的选型,但软件处理还需要注意以下几个要点,这些问题MCU厂家一般是不会提供解决方案的,需要用户根据自己的需求来完成:

  1. 冗余备份:有些时候用户需要更新正在使用的参数/固件,考虑到更新失败的情况下,需要支持参数/固件版本回退,所以需要两片备份区进行冗余备份。

    7c982d14-38aa-11ed-ba43-dac502259ad0.png
  2. Magic number or 校验码:Magic number一般就是在FLASH编程结束时候,写一个位数较高的(64bit)值到固定地址,使用加载数据时,先判断Magic number是否正确,以此判断编程过程是否完整,切记Magic number要在编程时先擦后写(第一个擦,最后一个写),否则无法起到验证效果。这种验证方式比较初级,对于可靠性要求更高的场合,一般会使用校验码的方式(CRC或者MD5),特别是参数文件通过通信的方式传输到MCU中,虽然通信过程可能也有校验(比如Modbus RTU的CRC),但是无法保证数据在RAM缓冲区不发生位翻转的情况,大多数MCU都不支持ECC功能,在这种情况下是无法纠错的,如果对端设备会将文件的校验码发过来进行校验,就可以避免该问题的发生,虽然RAM出现位翻转的概率非常低,但是如果发生位翻转的参数是设备的保护点或者PWM死区值,一旦出现错误,就可能会发生设备故障或损毁,甚至出现安全事故。

    7cd61ad4-38aa-11ed-ba43-dac502259ad0.png
  3. 编程过程掉电或复位:在编程的过程中出现掉电或者复位是经常出现的一种异常情况。比如震动导致电源接触不良,或者系统异常导致看门狗无法喂狗都有可能出现,还有使用POE电源对端设备直接断电都有可能造成这种异常。所有一定要考虑在这种情况下的异常处理,比如上电加载数据的时候,如果校验失败,可以使用一组安全数据或者更新前的数据。对于带操作系统的应用,建议硬件添加系统掉电检测电路,在检测到掉电事件(如24V掉电)发生时,如果当前没有写入Flash,则lock住写入进程,如果当前正在写入Flash,则立即调用sync函数,尽快将数据从缓存写入Flash(硬件上MCU VDD加个稍微大点的电容,多扛一段时间),不要等待系统后台写入。

    7d10bdb0-38aa-11ed-ba43-dac502259ad0.png
  4. 二次编程:有些MCU内部的Flash是带有校验机制的,对于同一地址在擦除完成后,只能进行一次编程,如果进行二次编程写入不同数值进去,可能会除非校验失败,导致该地址无法正常读写。

总结,这里列了一个表格,当需要IAP的时候,可以根据所选芯片的参数判断是否满足自身系统的需求(下表已经填入示例数据):

NVM 擦除编程最小单元 擦除编程所用时间 擦除编程寿命 编程过程是否需要关中断 编程数据的校验 编程过程中掉电/复位
EEPROM 不需要擦,可以按字节或者Page写入 写周期5ms 1000000 不需要 软件添加 软件添加
NOR FLASH Sector = 4K, 最小写入Page = 256B Sector擦70ms,Page写0.2ms 100000 不需要 软件添加 软件添加
MCU FLASH Sector = 2KB, 最小写入8Byte Sector擦14ms,写65us 50000 需要 软件添加 软件添加
审核编辑 :李倩

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

    关注

    147

    文章

    18646

    浏览量

    388320
  • FlaSh
    +关注

    关注

    10

    文章

    1718

    浏览量

    154785
  • 数据
    +关注

    关注

    8

    文章

    7316

    浏览量

    94046

原文标题:你真的会在Flash上存数据么

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    针对CW32芯片内部flash用户数据吗?

    针对CW32芯片,内部flash用户数据吗?就是如果不想加外部的flash,内部多余的flash能给外部使用吗?有相关的示例么?写入也需
    发表于 12-09 08:13

    的企业网络,是否真的“跟得上”数字化转型的脚步?

    前言在数字化转型的浪潮中,您的企业是否也面临这样的网络困境:分公司访问云端系统频繁卡顿,视频会议屡屡中断成为沟通的常态;跨地域数据传输缓慢,严重影响项目交付进度;尽管已投入大量成本部署多条专线,网络
    的头像 发表于 11-26 10:02 1096次阅读
    <b class='flag-5'>你</b>的企业网络,<b class='flag-5'>是否</b><b class='flag-5'>真的</b>“跟得上”数字化转型的脚步?

    使用J-Flash来编程CW32 MCU

    (可选): 编程完成后,J-Flash提供了验证选项,用于检查闪存内容是否与原始固件文件一致。 执行验证步骤以确保编程成功且没有数据损坏。 9.断开连接: 编程和验证完成后,可以断开
    发表于 11-25 07:00

    请问flashdb的flash操作接口是否可以异步?

    flash实际操作任务 这个任务设置优先级最低 这样是否会造成flashdb内核的数据不一致情况产生导致崩溃呢?
    发表于 09-19 08:21

    NAND Flash的基本原理和结构

    NAND Flash是什么?NAND Flash(闪存)是一种非易失性存储器技术,主要用于数据存储。与传统的DRAM或SRAM不同,NAND Flash在断电后仍能保存
    的头像 发表于 09-08 09:51 5933次阅读
    NAND <b class='flag-5'>Flash</b>的基本原理和结构

    TLE9893是否支持在FLASH1运行代码来擦除和编程FLASH1?

    芯片TLE9893是否支持在FLASH1运行代码来擦除和编程FLASH1。在NVM-PROG_UCODE中,代码在FLASH1
    发表于 08-13 08:14

    干扰可以提高测量精度,是真的吗?

    一、前言 水可以引燃蜡烛,是真的吗?是真的! 蛇怕雄黄,是真的吗?是假的! 上述两个现象,已经由央视 财经频道《是真的吗?》揭秘。 今天要探讨的是: 干扰可以提高测量精度,是
    的头像 发表于 08-04 09:28 556次阅读
    干扰可以提高测量精度,是<b class='flag-5'>真的</b>吗?

    FLASH模拟EEPROM

    的片 FLASH 模拟EEPROM 功能。 1 FLASH 与 EEPROM 简介 FLASH 和 EEPROM 都为非易失性存储器,在断电后
    发表于 07-16 15:13

    请问flashdb的flash操作接口是否可以异步?

    实现 feed_dog(); } } HAL_FLASH_Lock(); on_ic_write_cnt++; return size; } 这个函数内将数据使用消息队列的形式抛给flash实际操作任务 这个任务设置优先
    发表于 06-11 07:13

    MCU片Flash

        MCU片Flash是微控制器内部集成的非易失性存储器,主要用于存储程序代码、常量数据及系统配置信息。其核心特性与功能如下: 一、定义与类型‌ 片
    的头像 发表于 05-06 14:26 887次阅读

    STM32L476 Flash擦除失败的原因?

    开发板MCU型号:STM32L476RG 同样的固件在开发板中flash读写擦除操作都没问题,但在产品中擦除函数返回成功,但flash中的数据其实并没有擦除。 这两款MCU在Flash
    发表于 04-23 08:26

    S32K311如何在Flash测试ECC?

    我有一些与目标 S32K311 Flash ECC 相关的问题 - ERM 是否负责 Code Flash 和 Data Flash
    发表于 04-14 08:47

    GD3162 INTB引脚是否会在启动后变为低电平?

    嗨、NXP、这是关于栅极驱动器的 INTB 引脚的。如果栅极驱动器在初始电后出现故障,那么 INTB 引脚是否会在启动后变为低电平?在这种情况下、INTB 引脚的转换不会发生、并且不会调用 ISR
    发表于 04-10 07:35

    请问FPGA在启动的时候是否有对于Flash的任何故障检测机制呢?

    请问FPGA在启动的时候是否有对于Flash的任何故障检测机制呢? 以及在载入资料时,如何确保数据的一致性,有相关检测机制吗? 另外DLPComposer是否有Checksum 或相
    发表于 02-20 06:14

    谷歌 Gemini 2.0 Flash 系列 AI 模型

    谷歌旗下 AI 大模型 Gemini 系列全面上新,正式版 Gemini 2.0 Flash、Gemini 2.0 Flash-Lite 以及新一代旗舰大模型 Gemini 2.0 Pro 实验
    的头像 发表于 02-07 15:07 1106次阅读