soft_flash.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "soft_flash.h"
  2. #include "string.h"
  3. #include "main.h"
  4. #include "config.h"
  5. #include "usart_data_handle.h"
  6. #include "soft_crc.h"
  7. #include "soft_version.h"
  8. bool write_flash_flag = false;
  9. flash_data stor_par;
  10. flash_data cur_par;
  11. uint32_t sectStartAddr[12]=
  12. {
  13. 0x08000000,//0
  14. 0x08004000,//1
  15. 0x08008000,//2
  16. 0x0800c000,//3
  17. 0x08010000,//4
  18. 0x08020000,//5
  19. 0x08040000,//6
  20. 0x08060000, //7
  21. 0x08080000, //8
  22. 0x080A0000, //9
  23. 0x080C0000, //10
  24. 0x080E0000, //11
  25. };
  26. int GetSectorFromAddress(uint32_t address)
  27. {
  28. int sect = 0;
  29. if( address < 0x08000000 || address > 0x08100000 )
  30. return -1;
  31. for( int i=0; i<8; i++ )
  32. {
  33. if( address >= sectStartAddr[i] && address < sectStartAddr[i+1] )
  34. {
  35. sect = i;
  36. break;
  37. }
  38. }
  39. return sect;
  40. }
  41. /**
  42. * @file ReadFlashNBtye
  43. * @brief 读flash
  44. * @param none
  45. * @details
  46. * @author Zhang Sir
  47. **/
  48. void ReadFlashNBtye(uint32_t addr, uint8_t *pdata, uint16_t size)
  49. {
  50. if(addr + size >= 0x8010400) //65kb
  51. {
  52. return;
  53. }
  54. for (size_t i = 0; i < size; i++)
  55. {
  56. *(pdata + i) = *((__IO uint8_t *)addr + i);
  57. }
  58. }
  59. /**
  60. * @file WriteFlashNBtye
  61. * @brief 写flash
  62. * @param none
  63. * @details
  64. * @author Zhang Sir
  65. **/
  66. HAL_StatusTypeDef WriteFlashNBtye(uint32_t addr, uint8_t *pdata, uint16_t size)
  67. {
  68. HAL_StatusTypeDef write_status = HAL_OK;
  69. __disable_irq();
  70. HAL_FLASH_Unlock();
  71. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  72. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
  73. uint32_t sector = 10;
  74. sector = GetSectorFromAddress(addr);//获取地址所在的扇区
  75. FLASH_Erase_Sector(sector,FLASH_VOLTAGE_RANGE_3);//擦除指定的闪存扇区(0~11)
  76. //写flash 每次写2字节
  77. uint16_t TempBuf = 0;
  78. for(uint16_t i = 0; i < (size % 2 == 0? size/2 : size/2 +1); i++ )
  79. {
  80. TempBuf = *(pdata + 2 * i) + (*(pdata + 2 * i + 1) << 8);
  81. write_status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + i * 2, TempBuf);
  82. }
  83. HAL_FLASH_Lock();
  84. __enable_irq();
  85. return write_status;
  86. }
  87. int plane_flash_par_check( int *par, int pardef, int parmin, int parmax )
  88. {
  89. //参数超出范围报告参数异常,暂用默认值
  90. if ( *par < parmin || *par > parmax )
  91. {
  92. return pardef;
  93. }
  94. return *par;
  95. }
  96. void par_check(void)
  97. {
  98. stor_par.uavtype = plane_flash_par_check(&stor_par.uavtype,0,0,20);
  99. stor_par.abnormal_outage_flag = plane_flash_par_check(&stor_par.abnormal_outage_flag,0,0,1);
  100. stor_par.voltage = plane_flash_par_check(&stor_par.voltage,0,-50,50);
  101. }
  102. void par_copy(void)
  103. {
  104. memcpy(&cur_par,&stor_par,sizeof(flash_data));
  105. Int2String(cur_par.pmu_serial,dev_pmu.sn,9); //设置sn重新写入
  106. }
  107. /**
  108. * @file write_flash_function
  109. * @brief 把参数写入内存
  110. * @param none
  111. * @details
  112. * @author Zhang Sir
  113. **/
  114. void write_flash_function(void)
  115. {
  116. if(write_flash_flag == true)
  117. {
  118. if(HAL_OK == WriteFlashNBtye( FLASH_PAR_ADDR, ( uint8_t * )&stor_par, sizeof(flash_data) ))
  119. {
  120. ReadFlashNBtye( FLASH_PAR_ADDR, ( uint8_t * )&stor_par, sizeof( flash_data ) );
  121. par_check();
  122. par_copy();
  123. write_flash_flag = false;
  124. }
  125. }
  126. }
  127. /**
  128. * @file get_chip_id
  129. * @brief 获取芯片id
  130. * @param none
  131. * @details
  132. * @author Zhang Sir
  133. **/
  134. uint32_t chip_id[3] = {0};
  135. uint16_t get_chip_id(void)
  136. {
  137. for(uint8_t i = 0;i < 3; i++)
  138. {
  139. chip_id[i] = *((__IO uint32_t *)(FLASH_ID_ADDR + (4 * i)));
  140. }
  141. return Get_Crc16((uint8_t *)&chip_id[0], sizeof(chip_id));
  142. }
  143. /**
  144. * @file load_default_param
  145. * @brief 加载默认参数
  146. * @param none
  147. * @details
  148. * @author Zhang Sir
  149. **/
  150. void load_default_param(void)
  151. {
  152. stor_par.flash_flag = PAR_FALG;
  153. stor_par.pmu_serial = PMU_SERIAL;
  154. stor_par.uavtype = 0;
  155. stor_par.abnormal_outage_flag = 0;
  156. stor_par.voltage = 0;
  157. stor_par.chip_passid = get_chip_id();
  158. WriteFlashNBtye(FLASH_PAR_ADDR,(uint8_t *)&stor_par,sizeof(flash_data));
  159. }
  160. /**
  161. * @file flash_init
  162. * @brief flash初始化
  163. * @param none
  164. * @details
  165. * @author Zhang Sir
  166. **/
  167. bool Check_Chip_Verified = false; //检查当前芯片是否通过验证
  168. void flash_init(void)
  169. {
  170. ReadFlashNBtye( FLASH_PAR_ADDR, ( uint8_t * )&stor_par, sizeof( flash_data ) );
  171. if(stor_par.flash_flag != PAR_FALG)
  172. {
  173. //加载默认参数
  174. load_default_param();
  175. }
  176. //检查当前芯片是否通过验证
  177. if(get_chip_id() == stor_par.chip_passid)
  178. Check_Chip_Verified = true;
  179. par_check();
  180. par_copy();
  181. }