STM32虚拟EEPROM页面交换无法正常工作,请问是什么问题?

2019-07-14 18:05发布

我在STM32中的虚拟eeprom库在闪存中保存查找表,选择了3kByte的页面大小来保存所有数据,并且在页面已满之前它可以正常工作。但是在写入新数据时调用nonstop,总是会抛出错误。在这个例程中,第1页是有效页面,如果复制到第0页,就会出现失败。重新启动后,EE_Init()函数会抛出错误并且无法恢复,直到完成完全闪存。有谁知道这里有什么不对吗?STM32 EEPROM库中是否有错误?我从eeprom.h库和下面的函数EE_PageTransfer()附加了我的设置。我无法添加整个eeprom.c文件,因为它太大了。如果有人知道如何正确上传源文件,请告诉我。编辑:我第一个想到它可能是什么。首先,正确复制页面0,它似乎传输页面。但是在将1kbyte写入第1页后,PageFull错误再次出现,而不是在3kbyte之后。从那时起,始终会抛出页面完整错误。库中某处有错误吗?编辑2:看起来这个库不是为2kByte以外的页面大小而制作的,但我确信这可以以某种方式改变。我会试着弄清楚如何。2kByte页面大小一切正常。
  1. /* Define to prevent recursive inclusion -------------------------------------*/
  2. #ifndef __EEPROM_H
  3. #define __EEPROM_H

  4. /* Includes ------------------------------------------------------------------*/
  5. #include "stm32f3xx_hal.h"

  6. /* Exported constants --------------------------------------------------------*/
  7. /* EEPROM emulation firmware error codes */
  8. #define EE_OK      (uint32_t)HAL_OK
  9. #define EE_ERROR   (uint32_t)HAL_ERROR
  10. #define EE_BUSY    (uint32_t)HAL_BUSY
  11. #define EE_TIMEOUT (uint32_t)HAL_TIMEOUT

  12. /* Base address of the Flash sectors */
  13. #define ADDR_FLASH_PAGE_0   ((uint32_t)0x08000000) /* Base @ of Page 0, 2 Kbytes */
  14. #define ADDR_FLASH_PAGE_1   ((uint32_t)0x08000800) /* Base @ of Page 1, 2 Kbytes */
  15. #define ADDR_FLASH_PAGE_2   ((uint32_t)0x08001000) /* Base @ of Page 2, 2 Kbytes */
  16. #define ADDR_FLASH_PAGE_3   ((uint32_t)0x08001800) /* Base @ of Page 3, 2 Kbytes */
  17. #define ADDR_FLASH_PAGE_4   ((uint32_t)0x08002000) /* Base @ of Page 4, 2 Kbytes */
  18. #define ADDR_FLASH_PAGE_5   ((uint32_t)0x08002800) /* Base @ of Page 5, 2 Kbytes */
  19. #define ADDR_FLASH_PAGE_6   ((uint32_t)0x08003000) /* Base @ of Page 6, 2 Kbytes */
  20. #define ADDR_FLASH_PAGE_7   ((uint32_t)0x08003800) /* Base @ of Page 7, 2 Kbytes */
  21. #define ADDR_FLASH_PAGE_8   ((uint32_t)0x08004000) /* Base @ of Page 8, 2 Kbytes */
  22. #define ADDR_FLASH_PAGE_9   ((uint32_t)0x08004800) /* Base @ of Page 9, 2 Kbytes */
  23. #define ADDR_FLASH_PAGE_10  ((uint32_t)0x08005000) /* Base @ of Page 10, 2 Kbytes */
  24. #define ADDR_FLASH_PAGE_11  ((uint32_t)0x08005800) /* Base @ of Page 11, 2 Kbytes */
  25. #define ADDR_FLASH_PAGE_12  ((uint32_t)0x08006000) /* Base @ of Page 12, 2 Kbytes */
  26. #define ADDR_FLASH_PAGE_13  ((uint32_t)0x08006800) /* Base @ of Page 13, 2 Kbytes */
  27. #define ADDR_FLASH_PAGE_14  ((uint32_t)0x08007000) /* Base @ of Page 14, 2 Kbytes */
  28. #define ADDR_FLASH_PAGE_15  ((uint32_t)0x08007800) /* Base @ of Page 15, 2 Kbytes */
  29. #define ADDR_FLASH_PAGE_16  ((uint32_t)0x08008000) /* Base @ of Page 16, 2 Kbytes */
  30. #define ADDR_FLASH_PAGE_17  ((uint32_t)0x08008800) /* Base @ of Page 17, 2 Kbytes */
  31. #define ADDR_FLASH_PAGE_18  ((uint32_t)0x08009000) /* Base @ of Page 18, 2 Kbytes */
  32. #define ADDR_FLASH_PAGE_19  ((uint32_t)0x08009800) /* Base @ of Page 19, 2 Kbytes */
  33. #define ADDR_FLASH_PAGE_20  ((uint32_t)0x0800A000) /* Base @ of Page 20, 2 Kbytes */
  34. #define ADDR_FLASH_PAGE_21  ((uint32_t)0x0800A800) /* Base @ of Page 21, 2 Kbytes */
  35. #define ADDR_FLASH_PAGE_22  ((uint32_t)0x0800B000) /* Base @ of Page 22, 2 Kbytes */
  36. #define ADDR_FLASH_PAGE_23  ((uint32_t)0x0800B800) /* Base @ of Page 23, 2 Kbytes */
  37. #define ADDR_FLASH_PAGE_24  ((uint32_t)0x0800C000) /* Base @ of Page 24, 2 Kbytes */
  38. #define ADDR_FLASH_PAGE_25  ((uint32_t)0x0800C800) /* Base @ of Page 25, 2 Kbytes */
  39. #define ADDR_FLASH_PAGE_26  ((uint32_t)0x0800D000) /* Base @ of Page 26, 2 Kbytes */
  40. #define ADDR_FLASH_PAGE_27  ((uint32_t)0x0800D800) /* Base @ of Page 27, 2 Kbytes */
  41. #define ADDR_FLASH_PAGE_28  ((uint32_t)0x0800E000) /* Base @ of Page 28, 2 Kbytes */
  42. #define ADDR_FLASH_PAGE_29  ((uint32_t)0x0800E800) /* Base @ of Page 29, 2 Kbytes */
  43. #define ADDR_FLASH_PAGE_30  ((uint32_t)0x0800F000) /* Base @ of Page 30, 2 Kbytes */
  44. #define ADDR_FLASH_PAGE_31  ((uint32_t)0x0800F800) /* Base @ of Page 31, 2 Kbytes */


  45. /* Define the size of the sectors to be used */
  46. #define PAGE_SIZE               (uint32_t)FLASH_PAGE_SIZE  /* Page size */ //Now 6kByte -> HEX 0x1800

  47. /* EEPROM start address in Flash */
  48. #define EEPROM_START_ADDRESS  ((uint32_t)ADDR_FLASH_PAGE_26) /* EEPROM emulation start address */

  49. /* Pages 0 and 1 base and end addresses */
  50. #define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
  51. #define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))

  52. #define PAGE1_BASE_ADDRESS    ((uint32_t)(ADDR_FLASH_PAGE_29))
  53. #define PAGE1_END_ADDRESS     ((uint32_t)(ADDR_FLASH_PAGE_29 + PAGE_SIZE - 1))

  54. /* Used Flash pages for EEPROM emulation */
  55. #define PAGE0                 ((uint16_t)0)
  56. #define PAGE1                 ((uint16_t)1) /* Page nb between PAGE0_BASE_ADDRESS & PAGE1_BASE_ADDRESS*/

  57. /* No valid page define */
  58. #define NO_VALID_PAGE         ((uint16_t)0x00AB)

  59. /* Page status definitions */
  60. #define ERASED                ((uint16_t)0xFFFF)     /* Page is empty */
  61. #define RECEIVE_DATA          ((uint16_t)0xEEEE)     /* Page is marked to receive data */
  62. #define VALID_PAGE            ((uint16_t)0x0000)     /* Page containing valid data */

  63. /* Valid pages in read and write defines */
  64. #define READ_FROM_VALID_PAGE  ((uint8_t)0x00)
  65. #define WRITE_IN_VALID_PAGE   ((uint8_t)0x01)

  66. /* Page full define */
  67. #define PAGE_FULL             ((uint16_t)0x1800)

  68. /* Variables' number */
  69. #define NB_OF_VAR             ((uint16_t)1536)  //Half a page, since Address will also be safed -> always uint32_t

  70. /* Exported types ------------------------------------------------------------*/
  71. /* Exported macro ------------------------------------------------------------*/
  72. /* Exported functions ------------------------------------------------------- */
  73. uint16_t EE_Init(void);
  74. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
  75. uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);

  76. #endif /* __EEPROM_H */

  77. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
  1. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
  2. {
  3.   HAL_StatusTypeDef flashstatus = HAL_OK;
  4.   uint32_t newpageaddress = EEPROM_START_ADDRESS;
  5.   uint32_t oldpageid = 0;
  6.   uint16_t validpage = PAGE0, varidx = 0;
  7.   uint16_t eepromstatus = 0, readstatus = 0;
  8.   uint32_t page_error = 0;
  9.   FLASH_EraseInitTypeDef s_eraseinit;

  10.   /* Get active Page for read operation */
  11.   validpage = EE_FindValidPage(READ_FROM_VALID_PAGE);

  12.   if (validpage == PAGE1)       /* Page1 valid */
  13.   {
  14.     /* New page address where variable will be moved to */
  15.     newpageaddress = PAGE0_BASE_ADDRESS;

  16.     /* Old page ID where variable will be taken from */
  17.     oldpageid = PAGE1_BASE_ADDRESS;
  18.   }
  19.   else if (validpage == PAGE0)  /* Page0 valid */
  20.   {
  21.     /* New page address  where variable will be moved to */
  22.     newpageaddress = PAGE1_BASE_ADDRESS;

  23.     /* Old page ID where variable will be taken from */
  24.     oldpageid = PAGE0_BASE_ADDRESS;
  25.   }
  26.   else
  27.   {
  28.     return NO_VALID_PAGE;       /* No valid Page */
  29.   }

  30.   /* Set the new Page status to RECEIVE_DATA status */
  31.   flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA);  
  32.   /* If program operation was failed, a Flash error code is returned */
  33.   if (flashstatus != HAL_OK)
  34.   {
  35.     return flashstatus;
  36.   }

  37.   /* Write the variable passed as parameter in the new active page */
  38.   eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  39.   /* If program operation was failed, a Flash error code is returned */
  40.   if (eepromstatus != HAL_OK)
  41.   {
  42.     return eepromstatus;
  43.   }

  44.   /* Transfer process: transfer variables from old to the new active page */
  45.   for (varidx = 0; varidx < NB_OF_VAR; varidx++)
  46.   {
  47.     if (varidx != VirtAddress)  /* Check each variable except the one passed as parameter */
  48.     {
  49.       /* Read the other last variable updates */
  50.       readstatus = EE_ReadVariable(varidx, &DataVar);
  51.       /* In case variable corresponding to the virtual address was found */
  52.       if (readstatus != 0x1)
  53.       {
  54.         /* Transfer the variable to the new active page */
  55.         eepromstatus = EE_VerifyPageFullWriteVariable(varidx, DataVar);
  56.         /* If program operation was failed, a Flash error code is returned */
  57.         if (eepromstatus != HAL_OK)
  58.         {
  59.           return eepromstatus;
  60.         }
  61.       }
  62.     }
  63.   }

  64.   s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
  65.   s_eraseinit.PageAddress = oldpageid;
  66.   s_eraseinit.NbPages     = 1;

  67.   /* Erase the old Page: Set old Page status to ERASED status */
  68.   flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);  
  69.   /* If erase operation was failed, a Flash error code is returned */
  70.   if (flashstatus != HAL_OK)
  71.   {
  72.     return flashstatus;
  73.   }

  74.   /* Set new Page status to VALID_PAGE status */
  75.   flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE);   
  76.   /* If program operation was failed, a Flash error code is returned */
  77.   if (flashstatus != HAL_OK)
  78.   {
  79.     return flashstatus;
  80.   }



  81.   /* Return last operation flash status */
  82.   return flashstatus;
  83. }
复制代码

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。