美文网首页
ST官方模拟EEPROM模块的使用

ST官方模拟EEPROM模块的使用

作者: tianxiaoMCU | 来源:发表于2019-05-05 18:15 被阅读0次

原项目使用了一颗AT24C02来存储系统配置参数,为了降低成本,需要把这颗料砍掉,将配置参数保存到MCU内部的Flash上。这个改动其实简单,也就是读写内部flash而已,但是如果需要考虑擦写平衡这些特性,自己写就比较麻烦。而ST官方提供了一个使用内部Flash模拟EEPROM的模块,叫X-CUBE-EEPROM,包括了这些特性,实用性更强。
下面是从‘EEPROM emulation in STM32L4 series microcontrollers' (AN4894)中摘抄的特性介绍,更详细的说明还是看文档吧:

  • Lightweight implementation and reduced footprint
  • Simple API that consists of a few functions to format, initialize, read and write data, and clean up Flash memory pages
  • At least two Flash memory pages to be used for internal data management
  • Clean-up simplified for the user (background page erase)
  • Wear leveling algorithm to increase emulated EEPROM cycling capability
  • Robust against asynchronous resets and power failures.

轻量级其实是相对的,对于最简单擦写,1个page就可以了,比这个还轻量。使用这个模块看重无非是最后两点,毕竟Flash和EEPROM的特性是不一样的。

EEPROM_Emul的结构

EEPROM_Emul还是挺轻量的,没几个文件,就两部分核心实现和flash接口。使用前还需要做些额外的工作:

  • eeprom_emul_conf_template.h拷贝到自己的应用程序路径下,重命名为eeprom_emul_conf.h。我这里就直接重命名了。
  • 修改flash_interface.c里的GetBankNumber函数,我使用的是STM32L431,只有一个bank,所以直接return FLASH_BANK_1;。别的型号可能不需要改这部分。
EEPROM_Emul的配置

在AN4894文档的4.1.3节详细介绍了eeprom_emul_conf.h中各个宏。

这里我只改动NB_OF_VARIABLES和START_PAGE_ADDRESS。
  • NB_OF_VARIABLES设置为256;AT24C02也就256B,够用了。
  • 重点讲一下怎么确定START_PAGE_ADDRESS。在eeprom_emul.h里有这么一个宏PAGES_NUMBER
#define PAGES_NUMBER            (((((NB_OF_VARIABLES + NB_MAX_ELEMENTS_BY_PAGE) / NB_MAX_ELEMENTS_BY_PAGE) * 2U) * CYCLES_NUMBER) + GUARD_PAGES_NUMBER)

表示共使用了多少个PAGE来模拟EEPROM,它的值取决于配置和移植的多个宏。所以在配置好除START_PAGE_ADDRESS外的宏后,根据配置去计算PAGES_NUMBER的值。START_PAGE_ADDRESS到flash结尾的空间必须 ≥ (PAGES_NUMBERPAGE_SIZE),否则在初始化时会出现Hardfault。*

EEPROM_Emul的使用
  • 1、调用EE_Init(VirtAddVarTab, EE_FORCED_ERASE);进行初始化;
    VirtAddVarTab是一个数组,保存到是虚拟EEPROM的地址,这个地址可以是连续的也可以是不连续的,但不能是0x0000或者0xFFFF。
    EE_FORCED_ERASE是默认使用参数,如果能保证在擦写的时候是安全的(不会复位或者掉电),那也可以用EE_CONDITIONAL_ERASE这个参数。
  • 2、重写原来的EEPROM写接口,这里在触发clean时使用查询模式,EE_CleanUp();
    void EEPROM_WriteData(uint8_t Reg, uint8_t Value)
    {
      EE_Status ee_status = EE_OK;
    
      /* Unlock the Flash Program Erase controller */
      HAL_FLASH_Unlock();
    
      ee_status = EE_WriteVariable8bits(VirtAddVarTab[Reg], Value);
    
      /* Start cleanup polling mode, if cleanup is needed */
      if ((ee_status & EE_STATUSMASK_CLEANUP) == EE_STATUSMASK_CLEANUP)
      {
        ee_status |= EE_CleanUp();
      }
    
      /* Lock the Flash Program Erase controller */
      HAL_FLASH_Lock();
    
      if (ee_status != EE_OK)
      {
        printf("Write EEPROM_EMUL failed at addr %x\r\n", Reg);
      }
    }
    
  • 3、重写原来的EEPROM读接口;
    uint8_t EEPROM_ReadData(uint8_t Reg)
    {
      EE_Status ee_status = EE_OK;
      uint8_t value = 0;
    
      ee_status = EE_ReadVariable8bits(VirtAddVarTab[Reg], &value);
    
      if (ee_status != EE_OK)
      {
        printf("Read EEPROM_EMUL failed at addr %x\r\n", Reg);
      }
    
      return value;
    }
    

相关文章

网友评论

      本文标题:ST官方模拟EEPROM模块的使用

      本文链接:https://www.haomeiwen.com/subject/dmlhoqtx.html