flash(2639).c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. // 进入临界区 挂起所有任务
  65. vTaskSuspendAll();
  66. // 解锁Flash
  67. HAL_FLASH_Unlock();
  68. // 逐个字节写入数据
  69. for (uint32_t i = 0; i < length; i++)
  70. {
  71. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i]) == HAL_OK)
  72. {
  73. // 验证写入的数据
  74. if (*(uint32_t*)address != data[i])
  75. {
  76. status = HAL_ERROR;
  77. break;
  78. }
  79. address += 4; // 更新地址(一个字的大小)
  80. }
  81. else
  82. {
  83. status = HAL_ERROR;
  84. break;
  85. }
  86. }
  87. // 锁定Flash
  88. HAL_FLASH_Lock();
  89. // 退出临界区 恢复任务调度
  90. xTaskResumeAll();
  91. return status; // 返回写入操作的状态
  92. }
  93. /**
  94. * @brief 写参数区数据
  95. * @param none
  96. * @return HAL_StatusTypeDef
  97. */
  98. void Write_paramArea(void){
  99. // 擦除和写入参数
  100. uint32_t start_address = PARAM_ADDRESS; // Flash起始地址
  101. uint32_t number_of_pages = 1; // 假设我们只擦除1页
  102. // 调用擦除函数
  103. if (FLASH_Erase(start_address, number_of_pages) != HAL_OK) {
  104. // 擦除失败的处理
  105. }
  106. // 准备写入的数据
  107. uint32_t data_to_write[] = {0x01000000, 0x8040C00U}; // 示例数据数组
  108. uint32_t length_of_data = sizeof(data_to_write) / sizeof(uint32_t); // 数据数组长度
  109. // 调用写入函数
  110. if (FLASH_Write(start_address, data_to_write, length_of_data) != HAL_OK) {
  111. // 写入失败的处理
  112. }
  113. }
  114. /**
  115. * @brief 参数区数据读取
  116. * @param NONE
  117. * @return HAL_StatusTypeDef
  118. */
  119. void Read_ParamArea(void) {
  120. // 读取结构体中前两个字的数据
  121. FLASH_Read(PARAM_ADDRESS, (uint32_t*)&s_param_boot, sizeof(param_boot) / sizeof(uint32_t));
  122. }
  123. /**
  124. * @brief 向量重映射
  125. * @param NONE
  126. * @return HAL_StatusTypeDef
  127. */
  128. void Remap_Vector_Table(void) {
  129. __disable_irq();
  130. Read_ParamArea();
  131. SCB->VTOR = s_param_boot.jumpAddr;
  132. __enable_irq();
  133. }