• STM32的flash数据页转存过程分析!


    stm32模拟eeprom要实现flash数据页转存,实现函数为

     1 /**
     2 * @brief Transfers last updated variables data from the full Page to
     3 * an empty one.
     4 * @param VirtAddress: 16 bit virtual address of the variable
     5 * @param Data: 16 bit data to be written as variable value
     6 * @retval Success or error status:
     7 * - FLASH_COMPLETE: on success
     8 * - PAGE_FULL: if valid page is full
     9 * - NO_VALID_PAGE: if no valid page was found
    10 * - Flash error code: on write Flash error
    11 */
    12 uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)

    这个函数的过程为:

    1. 得到当前可读有效页,并设置其为oldPage,另一页为NewPage。

    2. 给NewPage设置RECEIVE_DATA状态

    3.初始化写地址 切换到接收页

    4. 写一个当前要保存的数据,如果单纯发起一次转存,则随意保存一个数据。

    5. 读出除第三步保存过的所有要保存的变量数据,保存到NewPage中。

    6. 擦除OldPage(执行时间15ms-2s,根据扇区大小而定(1K~128K))

    7. 给NewPage设置VALID_PAGE状态。

    第5步中 Get the valid Page end Address 

    1 if((PageStatus0 == RECEIVE_DATA)||(PageStatus1 == RECEIVE_DATA))//当页传输的时候把valid Page end Address切换到可读有效页的最后
    2 {
    3      Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
    4  }
    5  else
    6  {
    7      Address=CurWrAddress-2;
    8  }

    转存完成后的各页的状态:NewPage:VALID_PAGE;

                 OldPage:ERASED;

    但是在转存过程中系统断电,则各页的状态可能出现

    1.NewPage:ERASED; OldPage:VALID_PAGE; 这种情况发生在EE_PageTransfer函数执行到第二步之前系统掉电。那么这次转存过程就当没有发生过,要保存的那个数据变量也得不到保存。

    2.NewPage:RECEIVE_DATA; OldPage:VALID_PAGE; 这种情况发生在EE_PageTransfer函数执行到第六步之前系统掉电。

    3.NewPage:RECEIVE_DATA; OldPage:ERASED; 这种情况发生第六步执行过程中系统掉电。

    主要讨论第2、3中情况下开机初始化eeprom的时候处 

     1 //NewPage:RECEIVE_DATA; OldPage:VALID_PAGE; 2 InitCurrWrAddress();//初始化写地址
    2 //这里NewPage为PAGE1 OldPage为Page0
    3
    4 /* Transfer data from Page0 to Page1 */ 5 for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) 6 { 7 if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) 8 { 9 x = VarIdx; 10 } 11 if (VarIdx != x) 12 { 13 /* Read the last variables' updates */ 14 ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar); 15 /* In case variable corresponding to the virtual address was found */ 16 if (ReadStatus != 0x1) 17 { 18   /* Transfer the variable to the Page1 */ 19    EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar); 20 /* If program operation was failed, a Flash error code is returned */ 21 if (EepromStatus != FLASH_COMPLETE) 22 { 23      return EepromStatus; 24 } 25 } 26 } 27 }//for (VarIdx... 28 /* Mark Page1 as valid */ 29 FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE); 30 /* If program operation was failed, a Flash error code is returned */ 31 if (FlashStatus != FLASH_COMPLETE) 32 { 33 return FlashStatus; 34 } 35 /* Erase Page0 */ 36 FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE); 37 /* If erase operation was failed, a Flash error code is returned */ 38 if (FlashStatus != FLASH_COMPLETE) 39 { 40 return FlashStatus; 41 }

    过程:

    1.读出除第一个位置保存过的所有要保存的变量数据,保存到NewPage中。

    2. 把RECEIVE_DATA状态改为VALID_PAGE

    3. 擦除OldPage。

     1   //NewPage:RECEIVE_DATA; OldPage:ERASED;OldPage:Page0 NewPage:Page1
     2   /* Erase Page0 */
     3   FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE);
     4   /* If erase operation was failed, a Flash error code is returned */
     5   if (FlashStatus != FLASH_COMPLETE)
     6   {
     7      return FlashStatus;
     8   }
     9   /* Mark Page1 as valid */
    10  FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS,VALID_PAGE);
    11  /* If program operation was failed, a Flash error code is returned */
    12  if (FlashStatus != FLASH_COMPLETE)
    13  {
    14     return FlashStatus;
    15  }

    第三种情况下

    1. 擦除OldPage

    2. 把RECEIVE_DATA状态改为VALID_PAGE

    懒惰不会让你一下子跌到 但会在不知不觉中减少你的收获; 勤奋也不会让你一夜成功 但会在不知不觉中积累你的成果 越努力,越幸运。
  • 相关阅读:
    LIst判断是否为空
    SYBASE数据库基本操作
    Java内部类详解--成员内部类,局部内部类,匿名内部类,静态内部类
    String转jsonarry:字符串:[{"result":"20"},{"result":"21"},{"result":"20"},{"result":"22"}]
    使用HttpURLConnection发送POST请求
    Java 定义字符串数组
    JSP 解决illegal to have multiple occurrences of contentType with different values错误
    javascript 获取url参数值
    外键为','(逗号)拼接ID,连接查询外键表ID
    excel、csv、txt文件数据读取
  • 原文地址:https://www.cnblogs.com/Rainingday/p/6873028.html
Copyright © 2020-2023  润新知