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

懒惰不会让你一下子跌到 但会在不知不觉中减少你的收获; 勤奋也不会让你一夜成功 但会在不知不觉中积累你的成果 越努力,越幸运。
原文地址:https://www.cnblogs.com/Rainingday/p/6873028.html