luat_fs_idf5.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include "luat_base.h"
  2. #include "luat_fs.h"
  3. #include "luat_msgbus.h"
  4. #include "luat_ota.h"
  5. #include "luat_timer.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/unistd.h>
  9. #include <sys/stat.h>
  10. #include "esp_log.h"
  11. #include "esp_err.h"
  12. #include "esp_spiffs.h"
  13. #include "esp_system.h"
  14. #include "esp_partition.h"
  15. #include "esp_flash.h"
  16. #include "spi_flash_mmap.h"
  17. #define LUAT_LOG_TAG "fs"
  18. #include "luat_log.h"
  19. #include "luat_ota.h"
  20. #include <sys/types.h>
  21. #include <dirent.h>
  22. #ifdef LUAT_USE_LVGL
  23. static void lvgl_fs_codec_init(void);
  24. #endif
  25. extern const struct luat_vfs_filesystem vfs_fs_spiffs;
  26. extern const struct luat_vfs_filesystem vfs_fs_luadb;
  27. extern const struct luat_vfs_filesystem vfs_fs_romfs;
  28. extern const struct luat_vfs_filesystem vfs_fs_lfs2;
  29. static const void *map_ptr;
  30. static spi_flash_mmap_handle_t map_handle;
  31. const esp_partition_t * luadb_partition;
  32. extern const unsigned char bin2c_romfs_bin[3072];
  33. extern size_t luat_luadb_act_size;
  34. // 文件系统初始化函数
  35. static const esp_vfs_spiffs_conf_t spiffs_conf = {
  36. .base_path = "/spiffs",
  37. .partition_label = NULL,
  38. .max_files = 10,
  39. .format_if_mount_failed = true
  40. };
  41. #include "luat_romfs.h"
  42. int idf5_romfs_read(void* userdata, char* buff, size_t offset, size_t len) {
  43. // LLOGD("idf5_romfs_read %p %04X %04X", buff, offset, len);
  44. if (luadb_partition == NULL)
  45. return -1;
  46. esp_err_t ret = esp_partition_read(luadb_partition, offset, buff, len);
  47. if (ret != 0) {
  48. LLOGE("esp_partition_read ret %d", ret);
  49. //luat_timer_mdelay(3000);
  50. }
  51. return ret;
  52. }
  53. int idf5_romfs_read2(void* userdata, char* buff, size_t offset, size_t len) {
  54. // LLOGD("idf5_romfs_read2 %p %p %04X %04X", userdata, buff, offset, len);
  55. memcpy(buff, ((char*)userdata) + offset, len);
  56. return 0;
  57. }
  58. const luat_romfs_ctx idf5_romfs = {
  59. .read = idf5_romfs_read,
  60. .userdata = NULL
  61. };
  62. const luat_romfs_ctx idf5_romfs2 = {
  63. .read = idf5_romfs_read2,
  64. .userdata = (void*)bin2c_romfs_bin
  65. };
  66. int luat_fs_init(void) {
  67. esp_err_t ret = esp_vfs_spiffs_register(&spiffs_conf);
  68. if (ret) {
  69. LLOGW("spiffs register ret %d %s", ret, esp_err_to_name(ret));
  70. }
  71. // vfs进行必要的初始化
  72. luat_vfs_init(NULL);
  73. // 注册vfs for spiffs 实现
  74. luat_vfs_reg(&vfs_fs_spiffs);
  75. luat_fs_conf_t conf = {
  76. .busname = "",
  77. .type = "spiffs",
  78. .filesystem = "spiffs",
  79. .mount_point = "",
  80. };
  81. luat_fs_mount(&conf);
  82. // 先注册luadb
  83. luat_fs_conf_t conf2 = {0};
  84. // luat_timer_mdelay(3000);
  85. // LLOGD("spiffs_conf %p", &spiffs_conf);
  86. luadb_partition = esp_partition_find_first(0x5A, 0x5A, "script");
  87. if (luadb_partition != NULL) {
  88. char tmp[8] = {0};
  89. // 读取前32字节,判断脚本区的类型
  90. ret = esp_partition_read(luadb_partition, 0, tmp, 8);
  91. // TODO 判断ret,虽然不太可能有问题
  92. // 如果是romfs
  93. if (!memcmp(tmp, "-rom1fs-", 8)) {
  94. LLOGI("script zone as romfs");
  95. const luat_romfs_ctx* rfs = &idf5_romfs;
  96. conf2.busname = (char*)rfs;
  97. conf2.type = "romfs";
  98. conf2.filesystem = "romfs";
  99. conf2.mount_point = "/luadb/";
  100. luat_vfs_reg(&vfs_fs_romfs);
  101. }
  102. // 如果还是luadb
  103. else {
  104. esp_partition_mmap(luadb_partition, 0, luadb_partition->size, SPI_FLASH_MMAP_DATA, &map_ptr, &map_handle);
  105. if (map_ptr == NULL) {
  106. LLOGE("luadb mmap failed, it is bug, try to build a small script zone Firmware");
  107. return -1;
  108. }
  109. luat_luadb_act_size = luadb_partition->size;
  110. conf2.busname = (char*)map_ptr;
  111. LLOGI("script zone as luadb");
  112. conf2.type = "luadb",
  113. conf2.filesystem = "luadb",
  114. conf2.mount_point = "/luadb/",
  115. luat_vfs_reg(&vfs_fs_luadb);
  116. }
  117. luat_fs_mount(&conf2);
  118. }
  119. else {
  120. LLOGE("script partition NOT Found !!!");
  121. }
  122. // 注册lfs2
  123. #ifdef LUAT_USE_SFUD
  124. luat_vfs_reg(&vfs_fs_lfs2);
  125. #endif
  126. #ifdef LUAT_USE_LVGL
  127. lvgl_fs_codec_init();
  128. #endif
  129. return 0;
  130. }
  131. FILE* luat_vfs_spiffs_fopen(void* userdata, const char *filename, const char *mode) {
  132. char path[256] = {0};
  133. if (filename == NULL || strlen(filename) > 240) return NULL;
  134. if (filename[0] == '/')
  135. sprintf(path, "/spiffs%s", filename);
  136. else
  137. sprintf(path, "/spiffs/%s", filename);
  138. FILE* fd = fopen(path, mode);
  139. //LLOGD("fopen %s %s %s %p", filename, path, mode, fd);
  140. return fd;
  141. }
  142. int luat_vfs_spiffs_getc(void* userdata, FILE* stream) {
  143. int ret = getc(stream);
  144. return ret;
  145. }
  146. int luat_vfs_spiffs_fseek(void* userdata, FILE* stream, long int offset, int origin) {
  147. return fseek(stream, offset, origin);
  148. }
  149. int luat_vfs_spiffs_ftell(void* userdata, FILE* stream) {
  150. return ftell(stream);
  151. }
  152. int luat_vfs_spiffs_fclose(void* userdata, FILE* stream) {
  153. return fclose(stream);
  154. }
  155. int luat_vfs_spiffs_feof(void* userdata, FILE* stream) {
  156. return feof(stream);
  157. }
  158. int luat_vfs_spiffs_ferror(void* userdata, FILE *stream) {
  159. return ferror(stream);
  160. }
  161. size_t luat_vfs_spiffs_fread(void* userdata, void *ptr, size_t size, size_t nmemb, FILE *stream) {
  162. int ret = fread(ptr, size, nmemb, stream);
  163. //LLOGD("fread %d %d %d", size, nmemb, ret);
  164. if (ret > 0)
  165. return size * ret;
  166. return 0;
  167. }
  168. size_t luat_vfs_spiffs_fwrite(void* userdata, const void *ptr, size_t size, size_t nmemb, FILE *stream) {
  169. int ret = fwrite(ptr, size, nmemb, stream);
  170. //LLOGD("fwrite %d %d %d", size, nmemb, ret);
  171. if (ret > 0)
  172. return size * ret;
  173. return 0;
  174. }
  175. int luat_vfs_spiffs_remove(void* userdata, const char *filename) {
  176. char path[256] = {0};
  177. if (filename == NULL || strlen(filename) > 240) return 0;
  178. if (filename[0] == '/')
  179. sprintf(path, "/spiffs%s", filename);
  180. else
  181. sprintf(path, "/spiffs/%s", filename);
  182. return remove(path);
  183. }
  184. int luat_vfs_spiffs_rename(void* userdata, const char *old_filename, const char *new_filename) {
  185. char path[256] = {0};
  186. char path2[256] = {0};
  187. if (old_filename == NULL || strlen(old_filename) > 240) return -1;
  188. if (new_filename == NULL || strlen(new_filename) > 240) return -1;
  189. if (old_filename[0] == '/')
  190. sprintf(path, "/spiffs%s", old_filename);
  191. else
  192. sprintf(path, "/spiffs/%s", old_filename);
  193. if (new_filename[0] == '/')
  194. sprintf(path2, "/spiffs%s", new_filename);
  195. else
  196. sprintf(path2, "/spiffs/%s", new_filename);
  197. return rename(path, path2);
  198. }
  199. int luat_vfs_spiffs_fexist(void* userdata, const char *filename) {
  200. FILE* fd = luat_vfs_spiffs_fopen(userdata, filename, "rb");
  201. if (fd) {
  202. luat_vfs_spiffs_fclose(userdata, fd);
  203. return 1;
  204. }
  205. return 0;
  206. }
  207. size_t luat_vfs_spiffs_fsize(void* userdata, const char *filename) {
  208. FILE *fd;
  209. size_t size = 0;
  210. fd = luat_vfs_spiffs_fopen(userdata, filename, "rb");
  211. if (fd) {
  212. luat_vfs_spiffs_fseek(userdata, fd, 0, SEEK_END);
  213. size = luat_vfs_spiffs_ftell(userdata, fd);
  214. luat_vfs_spiffs_fclose(userdata, fd);
  215. }
  216. return size;
  217. }
  218. int luat_vfs_spiffs_mkfs(void* userdata, luat_fs_conf_t *conf) {
  219. return -1;
  220. }
  221. int luat_vfs_spiffs_mount(void** userdata, luat_fs_conf_t *conf) {
  222. return 0;
  223. }
  224. int luat_vfs_spiffs_umount(void* userdata, luat_fs_conf_t *conf) {
  225. return 0;
  226. }
  227. int luat_vfs_spiffs_mkdir(void* userdata, char const* dir) {
  228. char path[256] = {0};
  229. if (dir == NULL || strlen(dir) > 240) return -1;
  230. if (dir[0] == '/')
  231. sprintf(path, "/spiffs%s", dir);
  232. else
  233. sprintf(path, "/spiffs/%s", dir);
  234. return mkdir(path, 0);
  235. }
  236. int luat_vfs_spiffs_rmdir(void* userdata, char const* dir) {
  237. char path[256] = {0};
  238. if (dir == NULL || strlen(dir) > 240) return -1;
  239. if (dir[0] == '/')
  240. sprintf(path, "/spiffs%s", dir);
  241. else
  242. sprintf(path, "/spiffs/%s", dir);
  243. return remove(path);
  244. }
  245. int luat_vfs_spiffs_info(void* userdata, const char* path, luat_fs_info_t *conf) {
  246. memcpy(conf->filesystem, "spiffs", strlen("spiffs")+1);
  247. size_t total_bytes = 0;
  248. size_t used_bytes = 0;
  249. if (esp_spiffs_info(NULL, &total_bytes, &used_bytes) == 0) {
  250. conf->type = 0;
  251. conf->total_block = total_bytes / 512;
  252. conf->block_used = used_bytes / 512;
  253. conf->block_size = 512;
  254. }
  255. else {
  256. conf->type = 0;
  257. conf->total_block = 0;
  258. conf->block_used = 0;
  259. conf->block_size = 512;
  260. }
  261. return 0;
  262. }
  263. int luat_vfs_spiffs_lsdir(void* fsdata, char const* dir, luat_fs_dirent_t* ents, size_t offset, size_t len) {
  264. DIR *dp;
  265. struct dirent *ep;
  266. int index = 0;
  267. char path[256] = {0};
  268. if (dir == NULL || strlen(dir) > 240) return 0;
  269. if (dir[0] == '/')
  270. sprintf(path, "/spiffs%s", dir);
  271. else
  272. sprintf(path, "/spiffs/%s", dir);
  273. dp = opendir (path);
  274. if (dp != NULL)
  275. {
  276. while ((ep = readdir (dp)) != NULL) {
  277. //LLOGW("offset %d len %d", offset, len);
  278. if (offset > 0) {
  279. offset --;
  280. continue;
  281. }
  282. if (len > 0) {
  283. memcpy(ents[index].d_name, ep->d_name, strlen(ep->d_name) + 1);
  284. ents[index].d_type = 0;
  285. index++;
  286. len --;
  287. }
  288. else {
  289. break;
  290. }
  291. }
  292. (void) closedir (dp);
  293. return index;
  294. }
  295. else {
  296. LLOGW("opendir file %s", dir);
  297. }
  298. return 0;
  299. }
  300. #define T(name) .name = luat_vfs_spiffs_##name
  301. const struct luat_vfs_filesystem vfs_fs_spiffs = {
  302. .name = "spiffs",
  303. .opts = {
  304. .mkfs = NULL,
  305. T(mount),
  306. T(umount),
  307. T(mkdir),
  308. T(rmdir),
  309. T(lsdir),
  310. T(remove),
  311. T(rename),
  312. T(fsize),
  313. T(fexist),
  314. T(info)
  315. },
  316. .fopts = {
  317. T(fopen),
  318. T(getc),
  319. T(fseek),
  320. T(ftell),
  321. T(fclose),
  322. T(feof),
  323. T(ferror),
  324. T(fread),
  325. T(fwrite)
  326. }
  327. };
  328. #ifdef LUAT_USE_LVGL
  329. #include "lvgl.h"
  330. #include "luat_lvgl.h"
  331. #include "lv_sjpg.h"
  332. void luat_lv_fs_init(void);
  333. void lv_bmp_init(void);
  334. void lv_png_init(void);
  335. void lv_split_jpeg_init(void);
  336. static void lvgl_fs_codec_init(void) {
  337. luat_lv_fs_init();
  338. #ifdef LUAT_USE_LVGL_BMP
  339. lv_bmp_init();
  340. #endif
  341. #ifdef LUAT_USE_LVGL_PNG
  342. lv_png_init();
  343. #endif
  344. #ifdef LUAT_USE_LVGL_JPG
  345. lv_split_jpeg_init();
  346. #endif
  347. }
  348. #endif