fal_norflash_port.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include <fal.h>
  2. #include "fal_def.h"
  3. #define FLASH_SECTOR_SIZE ( 4 * 1024 )
  4. #define FLASH_START_ADDR 0U
  5. #define FLASH_END_ADDR 0x01000000U // 16*1024*1024
  6. #define FLASH_PROGRAM_MIN_SIZE 256 // 256 bytes
  7. //每次对falsh写入时 底层可以写入的最大字节数为 FLASH_PAGE_SIZE
  8. #define FLASH_PAGE_SIZE FLASH_PROGRAM_MIN_SIZE // 256 bytes
  9. /**
  10. * @brief 需要实现以下函数
  11. */
  12. extern int norflash_init( void );
  13. extern void norflash_read( uint8_t* pbuf, uint32_t addr, uint16_t datalen );
  14. extern void norflash_write_page( uint8_t* pbuf, uint32_t addr, uint16_t datalen );
  15. extern void norflash_erase_sector( uint32_t saddr );
  16. static int init( void );
  17. static int read( long offset, uint8_t* buf, size_t size );
  18. static int write( long offset, const uint8_t* buf, size_t size );
  19. static int erase( long offset, size_t size );
  20. #define FAL_ALIGN_UP( size, align ) \
  21. ( ( ( size ) + ( align ) - 1 ) - ( ( ( size ) + ( align ) - 1 ) % ( align ) ) )
  22. #define FAL_ALIGN_DOWN( size, align ) ( ( ( size ) / ( align ) ) * ( align ) )
  23. static int32_t get_sector( uint32_t address )
  24. {
  25. uint32_t sector = 0;
  26. if ( address < FLASH_END_ADDR && address >= FLASH_START_ADDR ) {
  27. address -= FLASH_START_ADDR;
  28. sector = address / FLASH_SECTOR_SIZE;
  29. return sector;
  30. }
  31. return -1;
  32. }
  33. static int init( void )
  34. {
  35. norflash_init();
  36. return 0;
  37. }
  38. static int read( long offset, uint8_t* buf, size_t size )
  39. {
  40. norflash_read( buf, offset + FLASH_START_ADDR, size );
  41. return size;
  42. }
  43. static uint32_t judge_whether_erase( uint8_t* sector_buf, uint16_t len )
  44. {
  45. uint8_t* p = sector_buf;
  46. for ( size_t i = 0; i < len; i++ ) {
  47. if ( p[ i ] != 0xFF ) {
  48. return 1;
  49. }
  50. }
  51. return 0;
  52. }
  53. /**
  54. * @brief
  55. *
  56. * @param offset 绝对地址
  57. * @param buf 读出来的扇区数据缓存
  58. * @param size 从扇区开始要写的长度 小于扇区大小
  59. * @return int
  60. */
  61. static int write_sector( long offset, const uint8_t* buf, size_t size )
  62. {
  63. uint32_t addr = FLASH_START_ADDR + offset;
  64. uint32_t addr_up = FAL_ALIGN_UP( addr, FLASH_PAGE_SIZE );
  65. uint32_t addr_down = FAL_ALIGN_DOWN( addr, FLASH_PAGE_SIZE );
  66. uint32_t addr_end = addr + size;
  67. uint32_t addr_end_up = FAL_ALIGN_UP( addr_end, FLASH_PAGE_SIZE );
  68. uint32_t addr_end_down = FAL_ALIGN_DOWN( addr_end, FLASH_PAGE_SIZE );
  69. uint32_t cur_addr = addr_down;
  70. uint32_t max_write_len = 0;
  71. uint32_t write_len = 0;
  72. while ( cur_addr < addr_end_up ) {
  73. if ( cur_addr < addr ) {
  74. max_write_len = ( addr_up - addr );
  75. write_len = size >= max_write_len ? max_write_len : size;
  76. norflash_write_page( buf, addr, write_len );
  77. buf += write_len;
  78. }
  79. else if ( cur_addr == addr_end_down ) {
  80. max_write_len = FLASH_PAGE_SIZE;
  81. write_len = addr_end - cur_addr;
  82. write_len = write_len >= max_write_len ? max_write_len : write_len;
  83. norflash_write_page( buf, cur_addr, write_len );
  84. }
  85. else {
  86. norflash_write_page( buf, cur_addr, FLASH_PAGE_SIZE );
  87. buf += FLASH_PAGE_SIZE;
  88. }
  89. cur_addr += FLASH_PAGE_SIZE;
  90. }
  91. return size;
  92. }
  93. static int write( long offset, const uint8_t* buf, size_t size )
  94. {
  95. uint32_t addr = FLASH_START_ADDR + offset;
  96. uint32_t addr_up = FAL_ALIGN_UP( addr, FLASH_SECTOR_SIZE );
  97. uint32_t addr_down = FAL_ALIGN_DOWN( addr, FLASH_SECTOR_SIZE );
  98. uint32_t addr_end = addr + size;
  99. uint32_t addr_end_up = FAL_ALIGN_UP( addr_end, FLASH_SECTOR_SIZE );
  100. uint32_t addr_end_down = FAL_ALIGN_DOWN( addr_end, FLASH_SECTOR_SIZE );
  101. uint32_t cur_addr = addr_down;
  102. uint32_t max_write_len = 0;
  103. uint32_t write_len = 0;
  104. if ( addr_end_up > FLASH_END_ADDR || ( int )addr_end_down < FLASH_START_ADDR ) return -1;
  105. //如果不使用内存分配可以定义一个static FLASH_SECTOR_SIZE 长度的buf
  106. uint8_t* read_sector_buf = FAL_MALLOC( FLASH_SECTOR_SIZE );
  107. if ( read_sector_buf == RT_NULL ) {
  108. return -2;
  109. }
  110. while ( cur_addr < addr_end_up ) {
  111. // 首次扇区写
  112. if ( cur_addr < addr ) {
  113. read( cur_addr - FLASH_START_ADDR, read_sector_buf, FLASH_SECTOR_SIZE );
  114. max_write_len = ( addr_up - addr );
  115. write_len = size >= max_write_len ? max_write_len : size;
  116. if ( judge_whether_erase( read_sector_buf + addr - cur_addr, write_len ) ){
  117. norflash_erase_sector( get_sector( cur_addr ) );
  118. FAL_MEMCPY( read_sector_buf + ( addr - cur_addr ), buf, write_len );
  119. write_sector( cur_addr, read_sector_buf, FLASH_SECTOR_SIZE );
  120. }
  121. else {
  122. write_sector( addr, buf, write_len );
  123. }
  124. buf += write_len;
  125. }
  126. //最后一次扇区写
  127. else if ( cur_addr == addr_end_down ) {
  128. read( cur_addr - FLASH_START_ADDR, read_sector_buf, FLASH_SECTOR_SIZE );
  129. max_write_len = FLASH_SECTOR_SIZE;
  130. write_len = addr_end - cur_addr;
  131. write_len = write_len >= max_write_len ? max_write_len : write_len;
  132. if ( judge_whether_erase( read_sector_buf, write_len ) ) {
  133. FAL_MEMCPY( read_sector_buf, buf, write_len );
  134. norflash_erase_sector( get_sector( cur_addr ) );
  135. write_sector( cur_addr, read_sector_buf, FLASH_SECTOR_SIZE );
  136. }
  137. else {
  138. write_sector( cur_addr, buf, write_len );
  139. }
  140. }
  141. //中间扇区写 直接擦除
  142. else {
  143. norflash_erase_sector( get_sector( cur_addr ) );
  144. write_sector( cur_addr, buf, FLASH_SECTOR_SIZE );
  145. buf += FLASH_SECTOR_SIZE;
  146. }
  147. cur_addr += FLASH_SECTOR_SIZE;
  148. }
  149. FAL_FREE( read_sector_buf );
  150. return size;
  151. }
  152. static int erase( long offset, size_t size )
  153. {
  154. int32_t cur_erase_sector;
  155. uint32_t addr = FLASH_START_ADDR + offset;
  156. uint32_t addr_down = FAL_ALIGN_DOWN( addr, FLASH_SECTOR_SIZE );
  157. uint32_t addr_end = addr + size;
  158. uint32_t addr_end_up = FAL_ALIGN_UP( addr_end, FLASH_SECTOR_SIZE );
  159. uint32_t cur_addr = addr_down;
  160. while ( cur_addr < addr_end_up ) {
  161. cur_erase_sector = get_sector( cur_addr );
  162. if ( cur_erase_sector == -1 ) {
  163. return cur_addr - addr;
  164. }
  165. norflash_erase_sector( cur_erase_sector );
  166. cur_addr += FLASH_SECTOR_SIZE;
  167. }
  168. return size;
  169. }
  170. const struct fal_flash_dev norflash0 = {
  171. .name = "norflash0",
  172. .addr = FLASH_START_ADDR,
  173. .len = FLASH_END_ADDR - FLASH_START_ADDR,
  174. .blk_size = FLASH_SECTOR_SIZE,
  175. .ops = { init, read, write, erase },
  176. .write_gran = 1,
  177. };