luat_fs.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #include <stdio.h>
  2. #include "luat_fs.h"
  3. #define LUAT_LOG_TAG "luat.fs"
  4. #include "luat_log.h"
  5. #include "lfs.h"
  6. #include "pico/stdlib.h"
  7. #include "hardware/flash.h"
  8. #include "string.h"
  9. #define LFS_START_ADDR 0x101E0000
  10. #define FLASH_FS_REGION_SIZE (1024 * 256)
  11. /***************************************************
  12. *************** MACRO ******************
  13. ***************************************************/
  14. #define LFS_BLOCK_DEVICE_READ_SIZE (256)
  15. #define LFS_BLOCK_DEVICE_PROG_SIZE (256)
  16. #define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
  17. #define LFS_BLOCK_DEVICE_ERASE_SIZE (4096) // one sector 4KB
  18. #define LFS_BLOCK_DEVICE_TOTOAL_SIZE (FLASH_FS_REGION_SIZE)
  19. #define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
  20. /***************************************************
  21. ******* FUNCTION FORWARD DECLARTION ********
  22. ***************************************************/
  23. // Read a block
  24. static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
  25. lfs_off_t off, void *buffer, lfs_size_t size);
  26. // Program a block
  27. //
  28. // The block must have previously been erased.
  29. static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
  30. lfs_off_t off, const void *buffer, lfs_size_t size);
  31. // Erase a block
  32. //
  33. // A block must be erased before being programmed. The
  34. // state of an erased block is undefined.
  35. static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block);
  36. // Sync the block device
  37. static int block_device_sync(const struct lfs_config *cfg);
  38. // utility functions for traversals
  39. //static int lfs_statfs_count(void *p, lfs_block_t b);
  40. /************************************************************/
  41. static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
  42. lfs_off_t off, void *buffer, lfs_size_t size)
  43. {
  44. int ret;
  45. // buffer = (uint8_t *)(block * 4096 + off + LFS_START_ADDR+XIP_BASE);
  46. memcpy(buffer, LFS_START_ADDR+block*4096+off, size);
  47. // flash_read(&spi, LFS_START_ADDR+block*4096+off, buffer, size);
  48. //LLOGD("block_device_read ,block = %d, off = %d, size = %d",block, off, size);
  49. // ret = tls_fls_read(block * 4096 + off + LFS_START_ADDR, (u8 *)buffer, size);
  50. // //LLOGD("block_device_read return val : %d",ret);
  51. // if (ret != TLS_FLS_STATUS_OK)
  52. // {
  53. // return -1;
  54. // }
  55. return LFS_ERR_OK;
  56. }
  57. static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
  58. lfs_off_t off, const void *buffer, lfs_size_t size)
  59. {
  60. int ret;
  61. //LLOGD("block_device_prog ,block = %d, off = %d, size = %d",block, off, size);
  62. flash_range_program(block * 4096 + off + LFS_START_ADDR, (uint8_t *)buffer, size);
  63. // flash_page_program(&spi, block * 4096 + off + LFS_START_ADDR, (uint8_t *)buffer);
  64. //LLOGD("block_device_prog return val : %d",ret);
  65. // if (ret != TLS_FLS_STATUS_OK)
  66. // {
  67. // return -1;
  68. // }
  69. return LFS_ERR_OK;
  70. }
  71. static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block)
  72. {
  73. int ret;
  74. flash_range_erase(LFS_START_ADDR + block * 4096, 4096);
  75. // flash_sector_erase(&spi, LFS_START_ADDR + block * 4096);
  76. return LFS_ERR_OK;
  77. }
  78. static int block_device_sync(const struct lfs_config *cfg)
  79. {
  80. return LFS_ERR_OK;
  81. }
  82. /***************************************************
  83. *************** GLOBAL VARIABLE *****************
  84. ***************************************************/
  85. // variables used by the filesystem
  86. static lfs_t lfs;
  87. #ifdef LFS_THREAD_SAFE_MUTEX
  88. static osMutexId_t lfs_mutex;
  89. #endif
  90. static char lfs_read_buf[256];
  91. static char lfs_prog_buf[256];
  92. //static __ALIGNED(4) char lfs_lookahead_buf[LFS_BLOCK_DEVICE_LOOK_AHEAD];
  93. //__align(4) static char lfs_lookahead_buf[LFS_BLOCK_DEVICE_LOOK_AHEAD];
  94. static char __attribute__((aligned(4))) lfs_lookahead_buf[LFS_BLOCK_DEVICE_LOOK_AHEAD];
  95. // configuration of the filesystem is provided by this struct
  96. static struct lfs_config lfs_cfg =
  97. {
  98. .context = NULL,
  99. // block device operations
  100. .read = block_device_read,
  101. .prog = block_device_prog,
  102. .erase = block_device_erase,
  103. .sync = block_device_sync,
  104. // block device configuration
  105. .read_size = LFS_BLOCK_DEVICE_READ_SIZE,
  106. .prog_size = LFS_BLOCK_DEVICE_PROG_SIZE,
  107. .block_size = LFS_BLOCK_DEVICE_ERASE_SIZE,
  108. .block_count = LFS_BLOCK_DEVICE_TOTOAL_SIZE / LFS_BLOCK_DEVICE_ERASE_SIZE,
  109. .block_cycles = 200,
  110. .cache_size = LFS_BLOCK_DEVICE_CACHE_SIZE,
  111. .lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD,
  112. .read_buffer = lfs_read_buf,
  113. .prog_buffer = lfs_prog_buf,
  114. .lookahead_buffer = lfs_lookahead_buf,
  115. .name_max = 63,
  116. .file_max = 0,
  117. .attr_max = 0};
  118. FILE *luat_fs_fopen(const char *filename, const char *mode)
  119. {
  120. ////LLOGD("fopen %s %s", filename, mode);
  121. int ret;
  122. char *t = (char *)mode;
  123. int flags = 0;
  124. lfs_file_t *lfsfile = NULL;
  125. for (int i = 0; i < strlen(mode); i++)
  126. {
  127. switch (*(t++))
  128. {
  129. case 'w':
  130. flags |= LFS_O_RDWR;
  131. break;
  132. case 'r':
  133. flags |= LFS_O_RDONLY;
  134. break;
  135. case 'a':
  136. flags |= LFS_O_APPEND;
  137. break;
  138. case 'b':
  139. break;
  140. case '+':
  141. break;
  142. default:
  143. break;
  144. }
  145. }
  146. lfsfile = malloc(sizeof(lfs_file_t));
  147. if (!lfsfile)
  148. {
  149. return lfsfile;
  150. }
  151. ret = lfs_file_open(&lfs, lfsfile, filename, flags);
  152. if (ret != 0)
  153. {
  154. return NULL;
  155. }
  156. return lfsfile;
  157. }
  158. int luat_fs_getc(FILE *stream)
  159. {
  160. return getc(stream);
  161. }
  162. int luat_fs_fseek(FILE *stream, long int offset, int origin)
  163. {
  164. int ret;
  165. ret = lfs_file_seek(&lfs, stream, offset, origin);
  166. if (ret < 0)
  167. {
  168. return -1;
  169. }
  170. return ret;
  171. }
  172. int luat_fs_ftell(FILE *stream)
  173. {
  174. return ftell(stream);
  175. }
  176. int luat_fs_fclose(FILE *stream)
  177. {
  178. int ret;
  179. ret = lfs_file_close(&lfs, (lfs_dir_t *)stream);
  180. if (ret != 0)
  181. {
  182. return 1;
  183. }
  184. free(stream);
  185. return 0;
  186. }
  187. int luat_fs_feof(FILE *stream)
  188. {
  189. return feof(stream);
  190. }
  191. int luat_fs_ferror(FILE *stream)
  192. {
  193. return ferror(stream);
  194. }
  195. size_t luat_fs_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  196. {
  197. int ret;
  198. ret = lfs_file_read(&lfs, stream,ptr, size * nmemb);
  199. if (ret < 0)
  200. {
  201. return 0;
  202. }
  203. return ret;
  204. }
  205. size_t luat_fs_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  206. {
  207. int ret;
  208. ret = lfs_file_write(&lfs,stream, ptr, size * nmemb);
  209. if (ret < 0)
  210. {
  211. return 0;
  212. }
  213. return ret;
  214. }
  215. int luat_fs_remove(const char *filename)
  216. {
  217. int ret;
  218. ret = lfs_remove(&lfs,filename);
  219. if(ret != 0)
  220. {
  221. return 1;
  222. }
  223. return 0;
  224. }
  225. int luat_fs_rename(const char *old_filename, const char *new_filename)
  226. {
  227. int ret;
  228. ret = lfs_rename(&lfs, old_filename,new_filename);
  229. if (ret != 0)
  230. {
  231. return 1;
  232. }
  233. return 0;
  234. }
  235. int luat_fs_fexist(const char *filename)
  236. {
  237. FILE *fd = luat_fs_fopen(filename, "rb");
  238. if (fd)
  239. {
  240. luat_fs_fclose(fd);
  241. return 1;
  242. }
  243. return 0;
  244. }
  245. size_t luat_fs_fsize(const char *filename)
  246. {
  247. FILE *fd;
  248. size_t size = 0;
  249. fd = luat_fs_fopen(filename, "rb");
  250. if (fd)
  251. {
  252. luat_fs_fseek(fd, 0, SEEK_END);
  253. size = luat_fs_ftell(fd);
  254. luat_fs_fclose(fd);
  255. }
  256. return size;
  257. }
  258. int luat_fs_init(void)
  259. {
  260. // mount the filesystem
  261. int err = lfs_mount(&lfs, &lfs_cfg);
  262. //LLOGD("lfs_mount return val : %d",err);
  263. // reformat if we can't mount the filesystem
  264. // this should only happen on the first boot
  265. if (err)
  266. {
  267. err = lfs_format(&lfs, &lfs_cfg);
  268. //LLOGD("lfs_format return val : %d",err);
  269. if (err)
  270. return err;
  271. err = lfs_mount(&lfs, &lfs_cfg);
  272. //LLOGD("lfs_mount return val : %d",err);
  273. if (err)
  274. return err;
  275. }
  276. }