flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /*
  2. * Flash-based Non-Volatile Memory (NVM)
  3. *
  4. * This file supports storing and loading persistent configuration based on
  5. * the STM32 builtin flash memory.
  6. *
  7. * The STM32F405xx has 12 flash sectors of heterogeneous size. We use the last
  8. * two sectors for configuration data. These pages have a size of 128kB each.
  9. * Setting any bit in these sectors to 0 is always possible, but setting them
  10. * to 1 requires erasing the whole sector.
  11. *
  12. * We consider each sector as an array of 64-bit fields except the first N bytes, which we
  13. * instead use as an allocation block. The allocation block is a compact bit-field (2 bit per entry)
  14. * that keeps track of the state of each field (erased, invalid, valid).
  15. *
  16. * One sector is always considered the valid (read) sector and the other one is the
  17. * target for the next write access: they can be considered to be ping-pong or double buffred.
  18. *
  19. * When writing a block of data, instead of always erasing the whole writable sector the
  20. * new data is appended in the erased area. This presumably increases flash life span.
  21. * The writable sector is only erased if there is not enough space for the new data.
  22. *
  23. * On startup, if there is exactly one sector
  24. * whose last non-erased value has the state "valid" that sector is considered
  25. * the valid sector. In any other case the selection is undefined.
  26. *
  27. *
  28. * To write a new block of data atomically we first mark all associated fields
  29. * as "invalid" (in the allocation table) then write the data and then mark the
  30. * fields as "valid" (in the direction of increasing address).
  31. */
  32. #include <string.h>
  33. #include <stdbool.h>
  34. //#include <types.h>
  35. #include "flash.h"
  36. #include "stm32f405xx.h"
  37. #include "stm32f4xx_board.h"
  38. #include "can.h"
  39. //#include "main.h"
  40. //#include "tim.h"
  41. //#include "gpio.h"
  42. #define K(v) (v<<10)
  43. static uint32_t sectors_size[12] = {K(16), K(16), K(16), K(16), K(64), K(128), K(128), K(128), K(128), K(128), K(128), K(128)};
  44. static const uint32_t FLASH_ERR_FLAGS =
  45. #if defined(FLASH_FLAG_EOP)
  46. FLASH_FLAG_EOP |
  47. #endif
  48. #if defined(FLASH_FLAG_OPERR)
  49. FLASH_FLAG_OPERR |
  50. #endif
  51. #if defined(FLASH_FLAG_WRPERR)
  52. FLASH_FLAG_WRPERR |
  53. #endif
  54. #if defined(FLASH_FLAG_PGAERR)
  55. FLASH_FLAG_PGAERR |
  56. #endif
  57. #if defined(FLASH_FLAG_PGSERR)
  58. FLASH_FLAG_PGSERR |
  59. #endif
  60. #if defined(FLASH_FLAG_PGPERR)
  61. FLASH_FLAG_PGPERR |
  62. #endif
  63. 0;
  64. void HAL_FLASH_ClearError() {
  65. __HAL_FLASH_CLEAR_FLAG(FLASH_ERR_FLAGS);
  66. }
  67. static uint32_t _sector_frame_address(uint32_t Address)
  68. {
  69. uint32_t sector = 0;
  70. if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  71. {
  72. sector = FLASH_SECTOR_0;
  73. }
  74. else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  75. {
  76. sector = FLASH_SECTOR_1;
  77. }
  78. else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  79. {
  80. sector = FLASH_SECTOR_2;
  81. }
  82. else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  83. {
  84. sector = FLASH_SECTOR_3;
  85. }
  86. else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  87. {
  88. sector = FLASH_SECTOR_4;
  89. }
  90. else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  91. {
  92. sector = FLASH_SECTOR_5;
  93. }
  94. else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  95. {
  96. sector = FLASH_SECTOR_6;
  97. }
  98. else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  99. {
  100. sector = FLASH_SECTOR_7;
  101. }
  102. else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  103. {
  104. sector = FLASH_SECTOR_8;
  105. }
  106. else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  107. {
  108. sector = FLASH_SECTOR_9;
  109. }
  110. else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  111. {
  112. sector = FLASH_SECTOR_10;
  113. }else {
  114. sector = FLASH_SECTOR_11;
  115. }
  116. return sector;
  117. }
  118. void flash_unlock(void)
  119. {
  120. /* Authorize the FLASH Registers access */
  121. WRITE_REG(FLASH->KEYR, FLASH_KEY1);
  122. WRITE_REG(FLASH->KEYR, FLASH_KEY2);
  123. }
  124. /**
  125. * @brief Locks the FLASH control register access
  126. * @retval HAL Status
  127. */
  128. void flash_lock(void)
  129. {
  130. /* Set the LOCK Bit to lock the FLASH Registers access */
  131. FLASH->CR |= FLASH_CR_LOCK;
  132. }
  133. void flash_wait_ready(uint32_t Timeout)
  134. {
  135. uint32_t tickstart = 0U;
  136. tickstart = HAL_GetTick();
  137. while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
  138. {
  139. // wdog_reload();
  140. if(Timeout != HAL_MAX_DELAY)
  141. {
  142. if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
  143. {
  144. return;
  145. }
  146. }
  147. }
  148. /* Check FLASH End of Operation flag */
  149. if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
  150. {
  151. /* Clear FLASH End of Operation pending bit */
  152. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  153. }
  154. }
  155. void flash_erase_sector(uint32_t Sector)
  156. {
  157. uint32_t tmp_psize = 0U;
  158. uint8_t VoltageRange = FLASH_VOLTAGE_RANGE_3;
  159. if (VoltageRange == FLASH_VOLTAGE_RANGE_1)
  160. {
  161. tmp_psize = FLASH_PSIZE_BYTE;
  162. }
  163. else if (VoltageRange == FLASH_VOLTAGE_RANGE_2)
  164. {
  165. tmp_psize = FLASH_PSIZE_HALF_WORD;
  166. }
  167. else if (VoltageRange == FLASH_VOLTAGE_RANGE_3)
  168. {
  169. tmp_psize = FLASH_PSIZE_WORD;
  170. }
  171. else
  172. {
  173. tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  174. }
  175. /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
  176. if (Sector > FLASH_SECTOR_11)
  177. {
  178. Sector += 4U;
  179. }
  180. /* If the previous operation is completed, proceed to erase the sector */
  181. CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  182. FLASH->CR |= tmp_psize;
  183. CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
  184. FLASH->CR |= FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos);
  185. FLASH->CR |= FLASH_CR_STRT;
  186. flash_wait_ready(2000);
  187. CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));
  188. }
  189. static void flash_write_word(uint32_t Address, uint32_t Data)
  190. {
  191. /* If the previous operation is completed, proceed to program the new data */
  192. CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  193. FLASH->CR |= FLASH_PSIZE_WORD;
  194. FLASH->CR |= FLASH_CR_PG;
  195. *(__IO uint32_t*)Address = Data;
  196. flash_wait_ready(10);
  197. FLASH->CR &= (~FLASH_CR_PG);
  198. }
  199. //不能用
  200. static void flash_write_byte(uint32_t Address, uint8_t Data)
  201. {
  202. /* If the previous operation is completed, proceed to program the new data */
  203. CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
  204. FLASH->CR |= FLASH_PSIZE_BYTE;
  205. FLASH->CR |= FLASH_CR_PG;
  206. *(__IO uint8_t*)Address = Data;
  207. flash_wait_ready(10);
  208. FLASH->CR &= (~FLASH_CR_PG);
  209. }
  210. // @brief Erases a flash sector. This sets all bits in the sector to 1.
  211. // The sector's current index is reset to the minimum value (n_reserved).
  212. // @returns 0 on success or a non-zero error code otherwise
  213. int flash_erase_page(uint32_t address) {
  214. // wdog_reload();
  215. flash_unlock();
  216. HAL_FLASH_ClearError();
  217. flash_erase_sector(_sector_frame_address(address));
  218. flash_lock();
  219. // wdog_reload();
  220. return 0;
  221. }
  222. int flash_erase_pages(uint32_t address, uint32_t size) {
  223. for (; size > 0; ) {
  224. flash_erase_page(address);
  225. uint8_t sector = _sector_frame_address(address);
  226. address += sectors_size[sector];
  227. size -= sectors_size[sector];;
  228. }
  229. return 0;
  230. }
  231. int flash_erase_app(uint8_t app_num) {
  232. if(app_num == 1) {
  233. app_status_set(1,false);
  234. //total = 16+64+128+128=336k
  235. flash_erase_page(ADDR_FLASH_SECTOR_3);//16k
  236. flash_erase_page(ADDR_FLASH_SECTOR_4);//64k
  237. flash_erase_page(ADDR_FLASH_SECTOR_5);//128k
  238. flash_erase_page(ADDR_FLASH_SECTOR_6);//128k
  239. }
  240. else if(app_num == 2) {
  241. app_status_set(2,false);
  242. //total = 128+128+128=384k
  243. flash_erase_page(ADDR_FLASH_SECTOR_7);//128k
  244. flash_erase_page(ADDR_FLASH_SECTOR_8);//128k
  245. flash_erase_page(ADDR_FLASH_SECTOR_9);//128k
  246. }
  247. return 0;
  248. }
  249. void app_status_set(uint8_t app_num,bool status) {
  250. uint8_t app_ok_flag[2];
  251. if(app_num == 1) {
  252. app_ok_flag[0] = status;
  253. app_ok_flag[1] = *(volatile uint8_t*)(CONFIG_IAP_INFO_ADDR+1);
  254. flash_erase_page(CONFIG_IAP_INFO_ADDR);
  255. flash_write_page(CONFIG_IAP_INFO_ADDR, app_ok_flag, 2, false);
  256. }
  257. else if(app_num == 2) {
  258. app_ok_flag[0] = *(volatile uint8_t*)(CONFIG_IAP_INFO_ADDR);
  259. app_ok_flag[1] = status;
  260. flash_erase_page(CONFIG_IAP_INFO_ADDR);
  261. flash_write_page(CONFIG_IAP_INFO_ADDR, app_ok_flag, 2, false);
  262. }
  263. }
  264. int flash_write_page(uint32_t target_addr, uint8_t *data, uint32_t length, bool erase) {
  265. uint32_t offset = target_addr & 0x3;
  266. target_addr -= offset;
  267. if (erase && flash_erase_page(target_addr) != 0) {
  268. return -1;
  269. }
  270. // wdog_reload();
  271. flash_unlock();
  272. HAL_FLASH_ClearError();
  273. // handle unaligned start
  274. for (; (offset & 0x3) && length; ++data, ++offset, --length) {
  275. flash_write_byte(target_addr + offset, *data);
  276. }
  277. // write 32-bit values (64-bit doesn't work)
  278. for (; length >= 4; data += 4, offset += 4, length -=4) {
  279. flash_write_word(target_addr + offset, *(uint32_t *)data);
  280. }
  281. // handle unaligned end
  282. for (; length; ++data, ++offset, --length) {
  283. flash_write_byte(target_addr + offset, *data);
  284. }
  285. flash_lock();
  286. return 0;
  287. }
  288. int flash_test(void) {
  289. int reg = 0;
  290. uint8_t buffer[1024];
  291. reg = flash_erase_pages(ADDR_FLASH_SECTOR_2, ADDR_FLASH_SECTOR_10-ADDR_FLASH_SECTOR_2);
  292. memset(buffer, 0x55, sizeof(buffer));
  293. reg = flash_erase_page(ADDR_FLASH_SECTOR_10);
  294. reg = flash_write_page(ADDR_FLASH_SECTOR_10, buffer, sizeof(buffer), false);
  295. memset(buffer, 0xAA, sizeof(buffer));
  296. reg = flash_write_page(ADDR_FLASH_SECTOR_10, buffer, sizeof(buffer), true);
  297. memset(buffer, 0x55, sizeof(buffer));
  298. reg = flash_erase_page(ADDR_FLASH_SECTOR_11);
  299. reg = flash_write_page(ADDR_FLASH_SECTOR_11, buffer, sizeof(buffer), false);
  300. memset(buffer, 0xAA, sizeof(buffer));
  301. reg = flash_write_page(ADDR_FLASH_SECTOR_11, buffer, sizeof(buffer), true);
  302. return reg;
  303. }
  304. #if 1
  305. //APP1_ADRESS 内容复制到 APP2_ADRESS
  306. void app1_copy_to_app2(void) {
  307. uint8_t data[1];
  308. //1、擦除APP2的flash和完整性标志位
  309. flash_erase_app(2);
  310. //2、从APP1_ADDRESS读出APP2_ADDRESS - APP1_ADDRESS个数据,复制写入到APP2_ADDRESS
  311. for (uint32_t i = 0; i < APP2_ADDRESS - APP1_ADDRESS; i++) {
  312. data[0] = *(volatile uint8_t*)(APP1_ADDRESS + i);
  313. flash_write_page(APP2_ADDRESS + i, data, 1, false);
  314. }
  315. }
  316. void app2_copy_to_app1(void) {
  317. uint8_t data[1];
  318. //1、擦除APP1的flash和完整性标志位
  319. flash_erase_app(1);
  320. //2、从APP2_ADDRESS读出APP2_ADDRESS - APP1_ADDRESS个数据,复制写入到APP1_ADDRESS
  321. for (uint32_t i = 0; i < APP2_ADDRESS - APP1_ADDRESS; i++) {
  322. data[0] = *(volatile uint8_t*)(APP2_ADDRESS + i);
  323. flash_write_page(APP1_ADDRESS + i, data, 1, false);
  324. }
  325. }
  326. #else
  327. //使用字(32位)为单位批量复制,提效不大
  328. void app1_copy_to_app2(void) {
  329. uint32_t app_size = APP2_ADDRESS - APP1_ADDRESS;
  330. // 1. 擦除APP2区域
  331. flash_erase_app(2);
  332. // 2. 一次性读取较多数据,批量写入
  333. uint32_t buffer[256]; // 1KB缓冲区
  334. uint32_t offset = 0;
  335. while (offset < app_size) {
  336. // 计算本次复制的数据量(不超过缓冲区大小)
  337. uint32_t copy_size = app_size - offset;
  338. if (copy_size > sizeof(buffer)) {
  339. copy_size = sizeof(buffer);
  340. }
  341. // 按字(32位)读取
  342. uint32_t word_count = (copy_size + 3) / 4; // 向上取整到4字节
  343. for (uint32_t i = 0; i < word_count; i++) {
  344. buffer[i] = *(volatile uint32_t*)(APP1_ADDRESS + offset + i * 4);
  345. }
  346. // 批量写入
  347. flash_write_page(APP2_ADDRESS + offset, (uint8_t*)buffer, copy_size, false);
  348. offset += copy_size;
  349. }
  350. }
  351. #endif
  352. void jump_to_app(uint32_t app_addr)
  353. {
  354. __disable_irq();
  355. // 3. 清除所有中断挂起位(非常重要!)
  356. for (int i = 0; i < 8; i++) {
  357. NVIC->ICPR[i] = 0xFFFFFFFF; // 清除挂起
  358. NVIC->ICER[i] = 0xFFFFFFFF; // 禁用中断
  359. }
  360. SysTick->CTRL = 0;
  361. HAL_CAN_DeInit(&hcan1);
  362. HAL_DeInit();
  363. __set_MSP(REG32(app_addr));
  364. // SCB->VTOR = app_addr;
  365. ((void (*)(void))(REG32(app_addr + 4)))();
  366. }
  367. #if 0
  368. void flash_write_magic(uint32_t magic) {
  369. uint32_t buffer[16];
  370. if (magic == REG32(CONFIG_IAP_INFO_ADDR + 8)) {
  371. return;
  372. }
  373. memcpy(buffer, (void *)CONFIG_IAP_INFO_ADDR, sizeof(buffer));
  374. buffer[2] = magic;
  375. flash_write_page(CONFIG_IAP_INFO_ADDR, (u8 *)buffer, sizeof(buffer), true);
  376. }
  377. uint32_t flash_read_magic(void) {
  378. return REG32(CONFIG_IAP_INFO_ADDR + 8);
  379. }
  380. #endif