flash(3637).c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* includes ----------------------------------------------------------*/
  2. #include "flash.h"
  3. /* typedef -----------------------------------------------------------*/
  4. typedef struct{
  5. uint8_t updateFlag; // 更新标志
  6. uint8_t a; // 预留
  7. uint16_t b; // 预留
  8. uint32_t jumpAddr; // 跳转地址
  9. }param_boot;
  10. param_boot s_param_boot = {
  11. .jumpAddr = 0x8040C00U,
  12. };
  13. /* define ------------------------------------------------------------*/
  14. /* macro -------------------------------------------------------------*/
  15. /* variables ---------------------------------------------------------*/
  16. /* function prototypes -----------------------------------------------*/
  17. /**
  18. * @brief flash读数据
  19. * @param address:读数据的起始地址
  20. read_buf:数据存储区
  21. length:读取的数据长度
  22. * @return HAL_StatusTypeDef
  23. */
  24. void FLASH_Read(uint32_t address, uint32_t *read_buf, uint32_t length)
  25. {
  26. for (uint32_t i = 0; i < length; i++)
  27. {
  28. read_buf[i] = *(volatile uint32_t*)(address + (i * 4)); // 以字(32位)为单位读取
  29. }
  30. }
  31. /**
  32. * @brief flash按页擦除
  33. * @param app_address address to jump
  34. number_of_pages:擦除页的页数
  35. * @return HAL_StatusTypeDef
  36. */
  37. HAL_StatusTypeDef FLASH_Erase(uint32_t start_address, uint32_t number_of_pages)
  38. {
  39. HAL_StatusTypeDef status = HAL_ERROR;
  40. FLASH_EraseInitTypeDef EraseInitStruct;
  41. uint32_t PageError = 0;
  42. // 解锁Flash
  43. HAL_FLASH_Unlock();
  44. // 设置擦除参数
  45. EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  46. EraseInitStruct.PageAddress = start_address;
  47. EraseInitStruct.NbPages = number_of_pages;
  48. // 擦除Flash
  49. status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
  50. // 锁定Flash
  51. HAL_FLASH_Lock();
  52. return status; // 返回擦除操作的状态
  53. }
  54. /**
  55. * @brief flash按字写入
  56. * @param address:写入地址
  57. data:数据
  58. length:长度
  59. * @return HAL_StatusTypeDef
  60. */
  61. HAL_StatusTypeDef FLASH_Write(uint32_t address, uint32_t *data, uint32_t length)
  62. {
  63. HAL_StatusTypeDef status = HAL_ERROR;
  64. // 解锁Flash
  65. HAL_FLASH_Unlock();
  66. // 逐个字节写入数据
  67. for (uint32_t i = 0; i < length; i++)
  68. {
  69. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i]) == HAL_OK)
  70. {
  71. // 验证写入的数据
  72. if (*(uint32_t*)address != data[i])
  73. {
  74. status = HAL_ERROR;
  75. break;
  76. }
  77. address += 4; // 更新地址(一个字的大小)
  78. }
  79. else
  80. {
  81. status = HAL_ERROR;
  82. break;
  83. }
  84. }
  85. // 锁定Flash
  86. HAL_FLASH_Lock();
  87. return status; // 返回写入操作的状态
  88. }
  89. /**
  90. * @brief 写参数区数据
  91. * @param none
  92. * @return HAL_StatusTypeDef
  93. */
  94. void Write_paramArea(void){
  95. // 擦除和写入参数
  96. uint32_t start_address = PARAM_ADDRESS; // Flash起始地址
  97. uint32_t number_of_pages = 1; // 假设我们只擦除1页
  98. // 调用擦除函数
  99. if (FLASH_Erase(start_address, number_of_pages) != HAL_OK) {
  100. // 擦除失败的处理
  101. }
  102. // 准备写入的数据
  103. uint32_t data_to_write[] = {0x01000000, 0x8040C00U}; // 示例数据数组
  104. uint32_t length_of_data = sizeof(data_to_write) / sizeof(uint32_t); // 数据数组长度
  105. // 调用写入函数
  106. if (FLASH_Write(start_address, data_to_write, length_of_data) != HAL_OK) {
  107. // 写入失败的处理
  108. }
  109. }
  110. /**
  111. * @brief 参数区数据读取
  112. * @param NONE
  113. * @return HAL_StatusTypeDef
  114. */
  115. void Read_ParamArea(void) {
  116. // 读取结构体中前两个字的数据
  117. FLASH_Read(PARAM_ADDRESS, (uint32_t*)&s_param_boot, sizeof(param_boot) / sizeof(uint32_t));
  118. }
  119. /**
  120. * @brief 向量重映射
  121. * @param NONE
  122. * @return HAL_StatusTypeDef
  123. */
  124. void Remap_Vector_Table(void) {
  125. __disable_irq();
  126. Read_ParamArea();
  127. SCB->VTOR = s_param_boot.jumpAddr;
  128. __enable_irq();
  129. }