S32K模拟EEPROM实现单字节和多字节的写入,并实现在一个地址处更新刷写次数

最近打算写EEPROM,本着单使用官方手册就搞定这个模拟EEPROM,最后还是借鉴了官方的例程

一、先来看一下我们要操作的内存空间的大小和可操作的地址在哪里?

 

S32K模拟EEPROM实现单字节和多字节的写入,并实现在一个地址处更新刷写次数_第1张图片

 1)从上图可知S32K148的FlexRAM 的最大空间为4k,所以说他可模拟的EEPROM最大为4k(S32K的EEPROM按字节读取的是由FlexRAM模拟最大4K,S32K的EEPROM按最小扇区2K读取的是由FlexNvm模拟最大64K)

2)从上面两张图可以看出来我们要操作的EEPROM的首地址是在0X14000000

二、了解最基本的内存知识后,下来我们看一下操作FLASH寄存器的具体步骤

这个流程图是关于Flash操作寄存器的通用步骤,这个你可以仔细看S32DS生成的驱动代码,都是按照这个流程图。

三、基本常识就是这些,然后借鉴一下Main.c代码对Flash的操作流程

/* Including necessary module. Cpu.h contains other modules needed for compiling.*/
#include "Cpu.h"

  volatile int exit_code = 0;

/* User includes (#include below this line is not maintained by Processor Expert) */

  /*
   * Flash选配内存空间分段
   * */

#define  BUFFER_SIZE         0x20u                   /* Size of data source */
#define  FLASHaddNUM_ERASE   0

#define bool	_Bool
#define true	1
#define false	0

#define _Bool	bool

 flash_ssd_config_t   flashSSDConfig;
 uint8_t sourceBuffer[BUFFER_SIZE]={1,2,3,4,0,0,7};
 uint8_t sourceReadBuffer[BUFFER_SIZE]={1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0};
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
  void CCIF_Handler(void);


  START_FUNCTION_DECLARATION_RAMSECTION

  void CCIF_Callback(void)

  END_FUNCTION_DECLARATION_RAMSECTION
 /* 2020.03.17
  * 使用FlexRAM模仿EEPROM
  * 可以最大分区出4k的EEPROM空间,并且内存可按照单个字节进行读取
  *
  * */
int main(void)
{
  /* Write your local variable definition here */
   status_t ret;        /* Store the driver APIs return code */
   uint32_t address;
   uint32_t size;
   uint32_t failAddr;

   flash_callback_t pCallBack;



  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  #ifdef PEX_RTOS_INIT
    PEX_RTOS_INIT();                   /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of Processor Expert internal initialization.                    ***/
   CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,
                   g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
   CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);


  /* Install interrupt for Flash Command Complete event */
      INT_SYS_InstallHandler(FTFC_IRQn, CCIF_Handler, (isr_t*) 0);     //CCIF_Handler代表了一个形参为void,返回值为void的函数
      INT_SYS_EnableIRQ(FTFC_IRQn);


  /* Enable global interrupt */
      INT_SYS_EnableIRQGlobal();


      ret =FLASH_DRV_Init(&Flash1_InitConfig0,&flashSSDConfig);
      DEV_ASSERT(STATUS_SUCCESS == ret);


#if 0
      /*檫除EEPROM的存储空间*/
      ret = FLASH_DRV_EraseAllBlock(&flashSSDConfig);    //实现写命令的流程图中的步骤,将之前刷写的内存全部删除
      DEV_ASSERT(STATUS_SUCCESS == ret);

  /* Verify the erase operation at margin level value of 1 */

      ret = FLASH_DRV_VerifyAllBlock(&flashSSDConfig, 1u);
      DEV_ASSERT(ret == STATUS_SUCCESS );



      FLASH_DRV_Init(&Flash1_InitConfig0,&flashSSDConfig);
#endif


    /* 2020.03.17 分区这个函数必须使用
     * 选配分出内存分区段
     * uEEEDataSizeCode              FCCOB4  0X2选择4K 的EEPROM空间
     * uDEPartitionCode              FCCOB5  0x8选择64K 的EEPROM空间
     * uCSEcKeySize                  FCCOB1  CSEc加密服务选项  无
     * uSFE                          FCCOB2  仅验证属性关闭
     * flexRamEnableLoadEEEData      FCCOB3  0 复位期间是否加载数据  加载
     * */
     ret=FLASH_DRV_DEFlashPartition(&flashSSDConfig,0x2,0x4,0x0,false,true);
      DEV_ASSERT(STATUS_SUCCESS==ret);

      FLASH_DRV_Init(&Flash1_InitConfig0,&flashSSDConfig);

      /* 2020.03.17
           * 选配分出内存分区段
           * flexRamFuncCode   FCCOB1   EEE_ENABLE 使能FlexRAM 模拟EEPROM
           * byteOfQuickWrite  FCCOB4 FCCOB5
           * pEEPROMStatus     EEPROM状态  结构体中三个状态
           * */
      FLASH_DRV_SetFlexRamFunction(&flashSSDConfig,EEE_ENABLE,0x00,NULL);
      DEV_ASSERT(STATUS_SUCCESS==ret);


#if 1

       /**尝试写单个字节到EEPROM的内存中**/
      /* Try to write data to EEPROM if FlexRAM is configured as EEPROM */
          if (flashSSDConfig.EEESize != 0u)
          {
              address = flashSSDConfig.EERAMBase;     //1400 0000
              size = sizeof(uint32_t);
              //sourceBuffer[0u] = 0x01;
              ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, 1, sourceBuffer);
              DEV_ASSERT(STATUS_SUCCESS == ret);


#if 1
              /* Verify the written data */
              if(sourceBuffer[0] != *((uint8_t *)address))
              {
                  /* Failed to write data to EEPROM */
                  exit_code = 1u;
                  return exit_code;
              }
#endif

#if 0
              /* Try to update one byte in an EEPROM address which isn't aligned */
              address = flashSSDConfig.EERAMBase + 1u;
              size = sizeof(uint8_t);
              //sourceBuffer[1u] = 0x11u;
              ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, 1, sourceBuffer+1);
              DEV_ASSERT(STATUS_SUCCESS == ret);



              /* Then verify */
              if (sourceBuffer[1u] != *(uint8_t *)address)
              {
                  /* Failed to update data to EEPROM */
                  exit_code = 1u;
                  return exit_code;
              }
#endif

              /**实现向FlexRAM模拟EEPROM的第四个字节实现刷写更新**/

              address = flashSSDConfig.EERAMBase+4;     //1400 0000
              size = sizeof(uint32_t);
              //sourceBuffer[2u] = 0x22u;
              /*如果地址读出的数据   不等于sourceBuffer5的数据 则更新数据*/
              if (sourceBuffer[4u] != *(uint8_t *)address)
              {
            	  sourceBuffer[4u]=(*(uint8_t *)address)+1;
            	  sourceReadBuffer[4]=sourceBuffer[4u];
              }
              else if(0==*(uint8_t *)address)
              {
            	  sourceBuffer[4u]=(*(uint8_t *)address)+1;
            	  sourceReadBuffer[4]=sourceBuffer[4u];
              }

              ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, 1, sourceBuffer+4);
              DEV_ASSERT(STATUS_SUCCESS == ret);

#if 1
              /* Verify the written data */
              if (sourceReadBuffer[4] != *(uint8_t *)address)
              {
                  /* Failed to write data to EEPROM */
                  exit_code = 1u;
                  return exit_code;
              }
#endif

              /**尝试写多个字节到EEPROM的内存中**/
#if 1
              address = flashSSDConfig.EERAMBase+0x10;     //1400 0000
              size = sizeof(sourceReadBuffer)/sizeof(sourceReadBuffer[0]);
              ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address, size, sourceReadBuffer);
              DEV_ASSERT(STATUS_SUCCESS == ret);


              /* Verify the written data */
              if (sourceReadBuffer[0u] != *(uint8_t *)address)
              {
                  /* Failed to write data to EEPROM */
                  exit_code = 1u;
                  return exit_code;
              }
#endif
          }
#endif



  /* Write your code here */


  /* For example: for(;;) { } */

  /*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;) {
    if(exit_code != 0) {
      break;
    }
  }
  return exit_code;
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/


START_FUNCTION_DEFINITION_RAMSECTION
  void CCIF_Callback(void)
  {
      /* Enable interrupt for Flash Command Complete */
      if ((FTFx_FCNFG & FTFx_FCNFG_CCIE_MASK) == 0u)
      {
          FTFx_FCNFG |= FTFx_FCNFG_CCIE_MASK;
      }
  }
  END_FUNCTION_DEFINITION_RAMSECTION


void CCIF_Handler(void)
{
    /* Disable Flash Command Complete interrupt */  // 禁用 flash命令完成中断
    FTFx_FCNFG &= (~FTFx_FCNFG_CCIE_MASK);

    return;
}
/* END main */
/*!
** @}
*/

主要还是借鉴了S32KDS生成的Demo例程中的具体操作流程。然后就可以实现指定的内存读写,效果如下。

第一次刷写   可以看到0x14000005 数据为00  (这个内存空间的读取是从右往左,低字节到高字节)

S32K模拟EEPROM实现单字节和多字节的写入,并实现在一个地址处更新刷写次数_第2张图片

第二次刷写  可以看到0x14000005 数据为01

S32K模拟EEPROM实现单字节和多字节的写入,并实现在一个地址处更新刷写次数_第3张图片

 

 

 

 

你可能感兴趣的:(S32K144)