flashbdev.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013-2018 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdint.h>
  27. #include <string.h>
  28. #include "py/obj.h"
  29. #include "py/mperrno.h"
  30. #include "led.h"
  31. #include "flash.h"
  32. #include "storage.h"
  33. #if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE
  34. // Here we try to automatically configure the location and size of the flash
  35. // pages to use for the internal storage. We also configure the location of the
  36. // cache used for writing.
  37. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)
  38. #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
  39. #define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM
  40. #define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1
  41. #define FLASH_MEM_SEG1_NUM_BLOCKS (224) // sectors 1,2,3,4: 16k+16k+16k+64k=112k
  42. // enable this to get an extra 64k of storage (uses the last sector of the flash)
  43. #if 0
  44. #define FLASH_MEM_SEG2_START_ADDR (0x080e0000) // sector 11
  45. #define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 11: 128k
  46. #endif
  47. #elif defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx)
  48. STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k
  49. #define CACHE_MEM_START_ADDR (&flash_cache_mem[0])
  50. #define FLASH_SECTOR_SIZE_MAX (0x4000) // 16k max due to size of cache buffer
  51. #define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1
  52. #define FLASH_MEM_SEG1_NUM_BLOCKS (128) // sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k
  53. #elif defined(STM32F429xx)
  54. #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
  55. #define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM
  56. #define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1
  57. #define FLASH_MEM_SEG1_NUM_BLOCKS (224) // sectors 1,2,3,4: 16k+16k+16k+64k=112k
  58. #elif defined(STM32F439xx)
  59. #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
  60. #define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM
  61. #define FLASH_MEM_SEG1_START_ADDR (0x08100000) // sector 12
  62. #define FLASH_MEM_SEG1_NUM_BLOCKS (384) // sectors 12,13,14,15,16,17: 16k+16k+16k+16k+64k+64k(of 128k)=192k
  63. #define FLASH_MEM_SEG2_START_ADDR (0x08140000) // sector 18
  64. #define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 18: 64k(of 128k)
  65. #elif defined(STM32F746xx) || defined(STM32F767xx) || defined(STM32F769xx)
  66. // The STM32F746 doesn't really have CCRAM, so we use the 64K DTCM for this.
  67. #define CACHE_MEM_START_ADDR (0x20000000) // DTCM data RAM, 64k
  68. #define FLASH_SECTOR_SIZE_MAX (0x08000) // 32k max
  69. #define FLASH_MEM_SEG1_START_ADDR (0x08008000) // sector 1
  70. #define FLASH_MEM_SEG1_NUM_BLOCKS (192) // sectors 1,2,3: 32k+32k+32=96k
  71. #elif defined(STM32H743xx)
  72. // The STM32H743 flash sectors are 128K
  73. #define CACHE_MEM_START_ADDR (0x20000000) // DTCM data RAM, 128k
  74. #define FLASH_SECTOR_SIZE_MAX (0x20000) // 128k max
  75. #define FLASH_MEM_SEG1_START_ADDR (0x08020000) // sector 1
  76. #define FLASH_MEM_SEG1_NUM_BLOCKS (256) // Sector 1: 128k / 512b = 256 blocks
  77. #elif defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L496xx)
  78. // The STM32L475/6 doesn't have CCRAM, so we use the 32K SRAM2 for this, although
  79. // actual location and size is defined by the linker script.
  80. extern uint8_t _flash_fs_start;
  81. extern uint8_t _flash_fs_end;
  82. extern uint8_t _ram_fs_cache_start[]; // size determined by linker file
  83. extern uint8_t _ram_fs_cache_end[];
  84. #define CACHE_MEM_START_ADDR ((uintptr_t)&_ram_fs_cache_start[0])
  85. #define FLASH_SECTOR_SIZE_MAX (&_ram_fs_cache_end[0] - &_ram_fs_cache_start[0]) // 2k max
  86. #define FLASH_MEM_SEG1_START_ADDR ((long)&_flash_fs_start)
  87. #define FLASH_MEM_SEG1_NUM_BLOCKS ((&_flash_fs_end - &_flash_fs_start) / 512)
  88. #else
  89. #error "no internal flash storage support for this MCU"
  90. #endif
  91. #if !defined(FLASH_MEM_SEG2_START_ADDR)
  92. #define FLASH_MEM_SEG2_START_ADDR (0) // no second segment
  93. #define FLASH_MEM_SEG2_NUM_BLOCKS (0) // no second segment
  94. #endif
  95. #define FLASH_FLAG_DIRTY (1)
  96. #define FLASH_FLAG_FORCE_WRITE (2)
  97. #define FLASH_FLAG_ERASED (4)
  98. static __IO uint8_t flash_flags = 0;
  99. static uint32_t flash_cache_sector_id;
  100. static uint32_t flash_cache_sector_start;
  101. static uint32_t flash_cache_sector_size;
  102. static uint32_t flash_tick_counter_last_write;
  103. static void flash_bdev_irq_handler(void);
  104. int32_t flash_bdev_ioctl(uint32_t op, uint32_t arg) {
  105. (void)arg;
  106. switch (op) {
  107. case BDEV_IOCTL_INIT:
  108. flash_flags = 0;
  109. flash_cache_sector_id = 0;
  110. flash_tick_counter_last_write = 0;
  111. return 0;
  112. case BDEV_IOCTL_NUM_BLOCKS:
  113. return FLASH_MEM_SEG1_NUM_BLOCKS + FLASH_MEM_SEG2_NUM_BLOCKS;
  114. case BDEV_IOCTL_IRQ_HANDLER:
  115. flash_bdev_irq_handler();
  116. return 0;
  117. case BDEV_IOCTL_SYNC:
  118. if (flash_flags & FLASH_FLAG_DIRTY) {
  119. flash_flags |= FLASH_FLAG_FORCE_WRITE;
  120. while (flash_flags & FLASH_FLAG_DIRTY) {
  121. NVIC->STIR = FLASH_IRQn;
  122. }
  123. }
  124. return 0;
  125. }
  126. return -MP_EINVAL;
  127. }
  128. static uint8_t *flash_cache_get_addr_for_write(uint32_t flash_addr) {
  129. uint32_t flash_sector_start;
  130. uint32_t flash_sector_size;
  131. uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
  132. if (flash_sector_size > FLASH_SECTOR_SIZE_MAX) {
  133. flash_sector_size = FLASH_SECTOR_SIZE_MAX;
  134. }
  135. if (flash_cache_sector_id != flash_sector_id) {
  136. flash_bdev_ioctl(BDEV_IOCTL_SYNC, 0);
  137. memcpy((void*)CACHE_MEM_START_ADDR, (const void*)flash_sector_start, flash_sector_size);
  138. flash_cache_sector_id = flash_sector_id;
  139. flash_cache_sector_start = flash_sector_start;
  140. flash_cache_sector_size = flash_sector_size;
  141. }
  142. flash_flags |= FLASH_FLAG_DIRTY;
  143. led_state(PYB_LED_RED, 1); // indicate a dirty cache with LED on
  144. flash_tick_counter_last_write = HAL_GetTick();
  145. return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
  146. }
  147. static uint8_t *flash_cache_get_addr_for_read(uint32_t flash_addr) {
  148. uint32_t flash_sector_start;
  149. uint32_t flash_sector_size;
  150. uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
  151. if (flash_cache_sector_id == flash_sector_id) {
  152. // in cache, copy from there
  153. return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
  154. }
  155. // not in cache, copy straight from flash
  156. return (uint8_t*)flash_addr;
  157. }
  158. static uint32_t convert_block_to_flash_addr(uint32_t block) {
  159. if (block < FLASH_MEM_SEG1_NUM_BLOCKS) {
  160. return FLASH_MEM_SEG1_START_ADDR + block * FLASH_BLOCK_SIZE;
  161. }
  162. if (block < FLASH_MEM_SEG1_NUM_BLOCKS + FLASH_MEM_SEG2_NUM_BLOCKS) {
  163. return FLASH_MEM_SEG2_START_ADDR + (block - FLASH_MEM_SEG1_NUM_BLOCKS) * FLASH_BLOCK_SIZE;
  164. }
  165. // can add more flash segments here if needed, following above pattern
  166. // bad block
  167. return -1;
  168. }
  169. static void flash_bdev_irq_handler(void) {
  170. if (!(flash_flags & FLASH_FLAG_DIRTY)) {
  171. return;
  172. }
  173. // This code uses interrupts to erase the flash
  174. /*
  175. if (flash_erase_state == 0) {
  176. flash_erase_it(flash_cache_sector_start, flash_cache_sector_size / 4);
  177. flash_erase_state = 1;
  178. return;
  179. }
  180. if (flash_erase_state == 1) {
  181. // wait for erase
  182. // TODO add timeout
  183. #define flash_erase_done() (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) == RESET)
  184. if (!flash_erase_done()) {
  185. return;
  186. }
  187. flash_erase_state = 2;
  188. }
  189. */
  190. // This code erases the flash directly, waiting for it to finish
  191. if (!(flash_flags & FLASH_FLAG_ERASED)) {
  192. flash_erase(flash_cache_sector_start, flash_cache_sector_size / 4);
  193. flash_flags |= FLASH_FLAG_ERASED;
  194. return;
  195. }
  196. // If not a forced write, wait at least 5 seconds after last write to flush
  197. // On file close and flash unmount we get a forced write, so we can afford to wait a while
  198. if ((flash_flags & FLASH_FLAG_FORCE_WRITE) || HAL_GetTick() - flash_tick_counter_last_write >= 5000) {
  199. // sync the cache RAM buffer by writing it to the flash page
  200. flash_write(flash_cache_sector_start, (const uint32_t*)CACHE_MEM_START_ADDR, flash_cache_sector_size / 4);
  201. // clear the flash flags now that we have a clean cache
  202. flash_flags = 0;
  203. // indicate a clean cache with LED off
  204. led_state(PYB_LED_RED, 0);
  205. }
  206. }
  207. bool flash_bdev_readblock(uint8_t *dest, uint32_t block) {
  208. // non-MBR block, get data from flash memory, possibly via cache
  209. uint32_t flash_addr = convert_block_to_flash_addr(block);
  210. if (flash_addr == -1) {
  211. // bad block number
  212. return false;
  213. }
  214. uint8_t *src = flash_cache_get_addr_for_read(flash_addr);
  215. memcpy(dest, src, FLASH_BLOCK_SIZE);
  216. return true;
  217. }
  218. bool flash_bdev_writeblock(const uint8_t *src, uint32_t block) {
  219. // non-MBR block, copy to cache
  220. uint32_t flash_addr = convert_block_to_flash_addr(block);
  221. if (flash_addr == -1) {
  222. // bad block number
  223. return false;
  224. }
  225. uint8_t *dest = flash_cache_get_addr_for_write(flash_addr);
  226. memcpy(dest, src, FLASH_BLOCK_SIZE);
  227. return true;
  228. }
  229. #endif // MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE