1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #define _GNU_SOURCE 1
33 #include "lfs_adapter.h"
34 #include "los_config.h"
35 #include "los_fs.h"
36 #include "vfs_files.h"
37 #include "vfs_operations.h"
38 #include "vfs_partition.h"
39 #include "vfs_maps.h"
40 #include "vfs_mount.h"
41 #include "securec.h"
42 #include "los_fs.h"
43
44 static struct PartitionCfg g_partitionCfg;
45 static struct DeviceDesc *g_lfsDevice = NULL;
46
LfsGetStartAddr(int partition)47 static uint32_t LfsGetStartAddr(int partition)
48 {
49 if (g_lfsDevice == NULL) {
50 struct DeviceDesc *device = NULL;
51 for (device = getDeviceList(); device != NULL; device = device->dNext) {
52 if (strcmp(device->dFsType, "littlefs") == 0) {
53 g_lfsDevice = device;
54 break;
55 }
56 }
57 }
58
59 if ((g_lfsDevice == NULL) || (partition >= g_lfsDevice->dPartNum)) {
60 return INVALID_DEVICE_ADDR;
61 }
62
63 return (uint32_t)g_lfsDevice->dAddrArray[partition];
64 }
65
littlefs_block_read(const struct lfs_config * c,lfs_block_t block,lfs_off_t off,void * dst,lfs_size_t size)66 WEAK int littlefs_block_read(const struct lfs_config *c, lfs_block_t block,
67 lfs_off_t off, void *dst, lfs_size_t size)
68 {
69 UINT32 addr = c->block_size * block + off;
70 UINT32 startaddr = LfsGetStartAddr((int)c->context);
71 if (startaddr == INVALID_DEVICE_ADDR) {
72 return -1;
73 }
74 addr += startaddr;
75
76 return (g_partitionCfg.readFunc)((int)c->context, &addr, dst, size);
77 }
78
littlefs_block_write(const struct lfs_config * c,lfs_block_t block,lfs_off_t off,const void * dst,lfs_size_t size)79 WEAK int littlefs_block_write(const struct lfs_config *c, lfs_block_t block,
80 lfs_off_t off, const void *dst, lfs_size_t size)
81 {
82 UINT32 addr = c->block_size * block + off;
83 UINT32 startaddr = LfsGetStartAddr((int)c->context);
84 if (startaddr == INVALID_DEVICE_ADDR) {
85 return -1;
86 }
87
88 addr += startaddr;
89
90 return (g_partitionCfg.writeFunc)((int)c->context, &addr, dst, size);
91 }
92
littlefs_block_erase(const struct lfs_config * c,lfs_block_t block)93 WEAK int littlefs_block_erase(const struct lfs_config *c, lfs_block_t block)
94 {
95 UINT32 addr = c->block_size * block;
96 UINT32 startaddr = LfsGetStartAddr((int)c->context);
97 if (startaddr == INVALID_DEVICE_ADDR) {
98 return -1;
99 }
100
101 addr += startaddr;
102
103 return (g_partitionCfg.eraseFunc)((int)c->context, addr, c->block_size);
104 }
105
littlefs_block_sync(const struct lfs_config * c)106 WEAK int littlefs_block_sync(const struct lfs_config *c)
107 {
108 (void)c;
109 return 0;
110 }
111
ConvertFlagToLfsOpenFlag(int oflags)112 static int ConvertFlagToLfsOpenFlag (int oflags)
113 {
114 int lfsOpenFlag = 0;
115
116 if (oflags & O_CREAT) {
117 lfsOpenFlag |= LFS_O_CREAT;
118 }
119
120 if (oflags & O_EXCL) {
121 lfsOpenFlag |= LFS_O_EXCL;
122 }
123
124 if (oflags & O_TRUNC) {
125 lfsOpenFlag |= LFS_O_TRUNC;
126 }
127
128 if (oflags & O_APPEND) {
129 lfsOpenFlag |= LFS_O_APPEND;
130 }
131
132 if (oflags & O_RDWR) {
133 lfsOpenFlag |= LFS_O_RDWR;
134 }
135
136 if (oflags & O_WRONLY) {
137 lfsOpenFlag |= LFS_O_WRONLY;
138 }
139
140 if (oflags == O_RDONLY) {
141 lfsOpenFlag |= LFS_O_RDONLY;
142 }
143
144 return lfsOpenFlag;
145 }
146
LittlefsErrno(int result)147 static int LittlefsErrno(int result)
148 {
149 return (result < 0) ? -result : result;
150 }
151
LfsConfigAdapter(struct PartitionCfg * pCfg,struct lfs_config * lfsCfg)152 void LfsConfigAdapter(struct PartitionCfg *pCfg, struct lfs_config *lfsCfg)
153 {
154 lfsCfg->context = (void *)pCfg->partNo;
155
156 lfsCfg->read_size = pCfg->readSize;
157 lfsCfg->prog_size = pCfg->writeSize;
158 lfsCfg->cache_size = pCfg->cacheSize;
159 lfsCfg->block_cycles = pCfg->blockCycles;
160 lfsCfg->lookahead_size = pCfg->lookaheadSize;
161 lfsCfg->block_size = pCfg->blockSize;
162 lfsCfg->block_count = pCfg->blockCount;
163
164 lfsCfg->read = littlefs_block_read;
165 lfsCfg->prog = littlefs_block_write;
166 lfsCfg->erase = littlefs_block_erase;
167 lfsCfg->sync = littlefs_block_sync;
168
169 g_partitionCfg.readFunc = pCfg->readFunc;
170 g_partitionCfg.writeFunc = pCfg->writeFunc;
171 g_partitionCfg.eraseFunc = pCfg->eraseFunc;
172 }
173
LfsMount(struct MountPoint * mp,unsigned long mountflags,const void * data)174 int LfsMount(struct MountPoint *mp, unsigned long mountflags, const void *data)
175 {
176 int ret;
177 lfs_t *mountHdl = NULL;
178 struct lfs_config *cfg = NULL;
179
180 if ((mp == NULL) || (mp->mPath == NULL) || (data == NULL)) {
181 errno = EFAULT;
182 ret = (int)LOS_NOK;
183 goto errout;
184 }
185
186 if (mountflags & MS_REMOUNT) {
187 errno = ENOSYS;
188 ret = (int)LOS_NOK;
189 goto errout;
190 }
191
192 mountHdl = (lfs_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_t) + sizeof(struct lfs_config));
193 if (mountHdl == NULL) {
194 errno = ENODEV;
195 ret = (int)LOS_NOK;
196 goto errout;
197 }
198 (void)memset_s(mountHdl, sizeof(lfs_t) + sizeof(struct lfs_config), 0, sizeof(lfs_t) + sizeof(struct lfs_config));
199 mp->mData = (void *)mountHdl;
200 cfg = (void *)((UINTPTR)mountHdl + sizeof(lfs_t));
201
202 LfsConfigAdapter((struct PartitionCfg *)data, cfg);
203
204 ret = lfs_mount((lfs_t *)mp->mData, cfg);
205 if (ret != 0) {
206 ret = lfs_format((lfs_t *)mp->mData, cfg);
207 if (ret == 0) {
208 ret = lfs_mount((lfs_t *)mp->mData, cfg);
209 }
210 }
211 if (ret != 0) {
212 LOSCFG_FS_FREE_HOOK(mountHdl);
213 errno = LittlefsErrno(ret);
214 ret = (int)LOS_NOK;
215 }
216
217 errout:
218 return ret;
219 }
220
LfsUmount(struct MountPoint * mp)221 int LfsUmount(struct MountPoint *mp)
222 {
223 int ret;
224
225 if (mp == NULL) {
226 errno = EFAULT;
227 return (int)LOS_NOK;
228 }
229
230 if (mp->mData == NULL) {
231 errno = ENOENT;
232 return (int)LOS_NOK;
233 }
234
235 ret = lfs_unmount((lfs_t *)mp->mData);
236 if (ret != 0) {
237 errno = LittlefsErrno(ret);
238 ret = (int)LOS_NOK;
239 }
240
241 LOSCFG_FS_FREE_HOOK(mp->mData);
242 mp->mData = NULL;
243 return ret;
244 }
245
LfsUnlink(struct MountPoint * mp,const char * fileName)246 int LfsUnlink(struct MountPoint *mp, const char *fileName)
247 {
248 int ret;
249
250 if ((mp == NULL) || (fileName == NULL)) {
251 errno = EFAULT;
252 return (int)LOS_NOK;
253 }
254
255 if (mp->mData == NULL) {
256 errno = ENOENT;
257 return (int)LOS_NOK;
258 }
259
260 ret = lfs_remove((lfs_t *)mp->mData, fileName);
261 if (ret != 0) {
262 errno = LittlefsErrno(ret);
263 ret = (int)LOS_NOK;
264 }
265
266 return ret;
267 }
268
LfsMkdir(struct MountPoint * mp,const char * dirName)269 int LfsMkdir(struct MountPoint *mp, const char *dirName)
270 {
271 int ret;
272
273 if ((dirName == NULL) || (mp == NULL)) {
274 errno = EFAULT;
275 return (int)LOS_NOK;
276 }
277
278 if (mp->mData == NULL) {
279 errno = ENOENT;
280 return (int)LOS_NOK;
281 }
282
283 lfs_t *lfs = (lfs_t *)mp->mData;
284
285 ret = lfs_mkdir(lfs, dirName);
286 if (ret != 0) {
287 errno = LittlefsErrno(ret);
288 ret = (int)LOS_NOK;
289 }
290
291 return ret;
292 }
293
LfsRmdir(struct MountPoint * mp,const char * dirName)294 int LfsRmdir(struct MountPoint *mp, const char *dirName)
295 {
296 int ret;
297 lfs_t *lfs = NULL;
298
299 if (mp == NULL) {
300 errno = EFAULT;
301 return (int)LOS_NOK;
302 }
303
304 if (mp->mData == NULL) {
305 errno = ENOENT;
306 return (int)LOS_NOK;
307 }
308
309 lfs = (lfs_t *)mp->mData;
310
311 if (dirName == NULL) {
312 errno = EFAULT;
313 return (int)LOS_NOK;
314 }
315
316 ret = lfs_remove(lfs, dirName);
317 if (ret != 0) {
318 errno = LittlefsErrno(ret);
319 ret = (int)LOS_NOK;
320 }
321
322 return ret;
323 }
324
LfsOpendir(struct Dir * dir,const char * dirName)325 int LfsOpendir(struct Dir *dir, const char *dirName)
326 {
327 int ret;
328
329 if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
330 errno = EFAULT;
331 return (int)LOS_NOK;
332 }
333
334 lfs_t *lfs = (lfs_t *)dir->dMp->mData;
335 lfs_dir_t *dirInfo = (lfs_dir_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_dir_t));
336 if (dirInfo == NULL) {
337 errno = ENOMEM;
338 return (int)LOS_NOK;
339 }
340
341 (void)memset_s(dirInfo, sizeof(lfs_dir_t), 0, sizeof(lfs_dir_t));
342 ret = lfs_dir_open(lfs, dirInfo, dirName);
343 if (ret != 0) {
344 LOSCFG_FS_FREE_HOOK(dirInfo);
345 errno = LittlefsErrno(ret);
346 goto errout;
347 }
348
349 dir->dData = dirInfo;
350 dir->dOffset = 0;
351
352 return LOS_OK;
353
354 errout:
355 return (int)LOS_NOK;
356 }
357
LfsReaddir(struct Dir * dir,struct dirent * dent)358 int LfsReaddir(struct Dir *dir, struct dirent *dent)
359 {
360 int ret;
361 struct lfs_info lfsInfo;
362
363 if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL) ||
364 (dent == NULL)) {
365 errno = EFAULT;
366 return (int)LOS_NOK;
367 }
368
369 if (dir->dData == NULL) {
370 errno = EBADF;
371 return (int)LOS_NOK;
372 }
373
374 lfs_t *lfs = (lfs_t *)dir->dMp->mData;
375 lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
376
377 ret = lfs_dir_read(lfs, dirInfo, &lfsInfo);
378 if (ret == TRUE) {
379 (void)strncpy_s(dent->d_name, sizeof(dent->d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
380 if (lfsInfo.type == LFS_TYPE_DIR) {
381 dent->d_type = DT_DIR;
382 } else if (lfsInfo.type == LFS_TYPE_REG) {
383 dent->d_type = DT_REG;
384 }
385
386 dent->d_reclen = lfsInfo.size;
387
388 return LOS_OK;
389 }
390
391 if (ret != 0) {
392 errno = LittlefsErrno(ret);
393 }
394
395 return (int)LOS_NOK;
396 }
397
LfsClosedir(struct Dir * dir)398 int LfsClosedir(struct Dir *dir)
399 {
400 int ret;
401
402 if ((dir == NULL) || (dir->dMp == NULL) || (dir->dMp->mData == NULL)) {
403 errno = EFAULT;
404 return (int)LOS_NOK;
405 }
406
407 if (dir->dData == NULL) {
408 errno = EBADF;
409 return (int)LOS_NOK;
410 }
411
412 lfs_t *lfs = (lfs_t *)dir->dMp->mData;
413 lfs_dir_t *dirInfo = (lfs_dir_t *)dir->dData;
414
415 ret = lfs_dir_close(lfs, dirInfo);
416 if (ret != 0) {
417 errno = LittlefsErrno(ret);
418 ret = (int)LOS_NOK;
419 }
420
421 LOSCFG_FS_FREE_HOOK(dirInfo);
422 dir->dData = NULL;
423
424 return ret;
425 }
426
LfsOpen(struct File * file,const char * pathName,int openFlag)427 int LfsOpen(struct File *file, const char *pathName, int openFlag)
428 {
429 int ret;
430 lfs_file_t *lfsHandle = NULL;
431
432 if ((pathName == NULL) || (file == NULL) || (file->fMp == NULL) ||
433 (file->fMp->mData == NULL)) {
434 errno = EFAULT;
435 return (int)LOS_NOK;
436 }
437
438 lfsHandle = (lfs_file_t *)LOSCFG_FS_MALLOC_HOOK(sizeof(lfs_file_t));
439 if (lfsHandle == NULL) {
440 errno = ENOMEM;
441 return (int)LOS_NOK;
442 }
443
444 int lfsOpenFlag = ConvertFlagToLfsOpenFlag(openFlag);
445 ret = lfs_file_open((lfs_t *)file->fMp->mData, lfsHandle, pathName, lfsOpenFlag);
446 if (ret != 0) {
447 LOSCFG_FS_FREE_HOOK(lfsHandle);
448 errno = LittlefsErrno(ret);
449 goto errout;
450 }
451
452 file->fData = (void *)lfsHandle;
453 return ret;
454
455 errout:
456 return INVALID_FD;
457 }
458
LfsRead(struct File * file,char * buf,size_t len)459 int LfsRead(struct File *file, char *buf, size_t len)
460 {
461 int ret;
462 struct MountPoint *mp = NULL;
463 lfs_file_t *lfsHandle = NULL;
464
465 if (buf == NULL) {
466 errno = EFAULT;
467 return (int)LOS_NOK;
468 }
469
470 if ((file == NULL) || (file->fData == NULL)) {
471 errno = EBADF;
472 return (int)LOS_NOK;
473 }
474
475 lfsHandle = (lfs_file_t *)file->fData;
476 mp = file->fMp;
477 if ((mp == NULL) || (mp->mData == NULL)) {
478 errno = EFAULT;
479 return (int)LOS_NOK;
480 }
481
482 ret = lfs_file_read((lfs_t *)mp->mData, lfsHandle, buf, len);
483 if (ret < 0) {
484 errno = LittlefsErrno(ret);
485 ret = (int)LOS_NOK;
486 }
487 return ret;
488 }
489
LfsWrite(struct File * file,const char * buf,size_t len)490 int LfsWrite(struct File *file, const char *buf, size_t len)
491 {
492 int ret;
493 struct MountPoint *mp = NULL;
494 lfs_file_t *lfsHandle = NULL;
495
496 if (buf == NULL) {
497 errno = EFAULT;
498 return (int)LOS_NOK;
499 }
500
501 if ((file == NULL) || (file->fData == NULL)) {
502 errno = EBADF;
503 return (int)LOS_NOK;
504 }
505
506 lfsHandle = (lfs_file_t *)file->fData;
507 mp = file->fMp;
508 if ((mp == NULL) || (mp->mData == NULL)) {
509 errno = EFAULT;
510 return (int)LOS_NOK;
511 }
512
513 ret = lfs_file_write((lfs_t *)mp->mData, lfsHandle, buf, len);
514 if (ret < 0) {
515 errno = LittlefsErrno(ret);
516 ret = (int)LOS_NOK;
517 }
518 return ret;
519 }
520
LfsSeek(struct File * file,off_t offset,int whence)521 off_t LfsSeek(struct File *file, off_t offset, int whence)
522 {
523 off_t ret;
524 struct MountPoint *mp = NULL;
525 lfs_file_t *lfsHandle = NULL;
526
527 if ((file == NULL) || (file->fData == NULL)) {
528 errno = EBADF;
529 return (off_t)LOS_NOK;
530 }
531
532 lfsHandle = (lfs_file_t *)file->fData;
533 mp = file->fMp;
534 if ((mp == NULL) || (mp->mData == NULL)) {
535 errno = EFAULT;
536 return (off_t)LOS_NOK;
537 }
538
539 ret = (off_t)lfs_file_seek((lfs_t *)mp->mData, lfsHandle, offset, whence);
540 if (ret < 0) {
541 errno = LittlefsErrno(ret);
542 ret = (off_t)LOS_NOK;
543 }
544
545 return ret;
546 }
547
LfsClose(struct File * file)548 int LfsClose(struct File *file)
549 {
550 int ret;
551 struct MountPoint *mp = NULL;
552 lfs_file_t *lfsHandle = NULL;
553
554 if ((file == NULL) || (file->fData == NULL)) {
555 errno = EBADF;
556 return (int)LOS_NOK;
557 }
558
559 lfsHandle = (lfs_file_t *)file->fData;
560 mp = file->fMp;
561 if ((mp == NULL) || (mp->mData == NULL)) {
562 errno = EFAULT;
563 return (int)LOS_NOK;
564 }
565
566 ret = lfs_file_close((lfs_t *)mp->mData, lfsHandle);
567 if (ret != 0) {
568 errno = LittlefsErrno(ret);
569 ret = (int)LOS_NOK;
570 }
571
572 LOSCFG_FS_FREE_HOOK(file->fData);
573 file->fData = NULL;
574 return ret;
575 }
576
LfsRename(struct MountPoint * mp,const char * oldName,const char * newName)577 int LfsRename(struct MountPoint *mp, const char *oldName, const char *newName)
578 {
579 int ret;
580
581 if ((mp == NULL) || (oldName == NULL) || (newName == NULL)) {
582 errno = EFAULT;
583 return (int)LOS_NOK;
584 }
585
586 if (mp->mData == NULL) {
587 errno = ENOENT;
588 return (int)LOS_NOK;
589 }
590
591 ret = lfs_rename((lfs_t *)mp->mData, oldName, newName);
592 if (ret != 0) {
593 errno = LittlefsErrno(ret);
594 ret = (int)LOS_NOK;
595 }
596
597 return ret;
598 }
599
LfsStat(struct MountPoint * mp,const char * path,struct stat * buf)600 int LfsStat(struct MountPoint *mp, const char *path, struct stat *buf)
601 {
602 int ret;
603 struct lfs_info info;
604
605 if ((mp == NULL) || (path == NULL) || (buf == NULL)) {
606 errno = EFAULT;
607 return (int)LOS_NOK;
608 }
609
610 if (mp->mData == NULL) {
611 errno = ENOENT;
612 return (int)LOS_NOK;
613 }
614
615 ret = lfs_stat((lfs_t *)mp->mData, path, &info);
616 if (ret == 0) {
617 buf->st_size = info.size;
618 if (info.type == LFS_TYPE_REG) {
619 buf->st_mode = S_IFREG;
620 } else {
621 buf->st_mode = S_IFDIR;
622 }
623 } else {
624 errno = LittlefsErrno(ret);
625 ret = (int)LOS_NOK;
626 }
627
628 return ret;
629 }
630
LfsSync(struct File * file)631 int LfsSync(struct File *file)
632 {
633 int ret;
634 struct MountPoint *mp = NULL;
635
636 if ((file == NULL) || (file->fData == NULL)) {
637 errno = EBADF;
638 return (int)LOS_NOK;
639 }
640
641 if ((file->fMp == NULL) || (file->fMp->mData == NULL)) {
642 errno = EFAULT;
643 return (int)LOS_NOK;
644 }
645
646 mp = file->fMp;
647 ret = lfs_file_sync((lfs_t *)mp->mData, (lfs_file_t *)file->fData);
648 if (ret != 0) {
649 errno = LittlefsErrno(ret);
650 ret = (int)LOS_NOK;
651 }
652 return ret;
653 }
654
LfsFormat(const char * partName,void * privData)655 int LfsFormat(const char *partName, void *privData)
656 {
657 int ret;
658 lfs_t lfs = {0};
659 struct lfs_config cfg = {0};
660
661 (void)partName;
662
663 LfsConfigAdapter((struct PartitionCfg *)privData, &cfg);
664
665 ret = lfs_format(&lfs, &cfg);
666 if (ret != 0) {
667 errno = LittlefsErrno(ret);
668 ret = (int)LOS_NOK;
669 }
670 return ret;
671 }
672
673 static struct MountOps g_lfsMnt = {
674 .mount = LfsMount,
675 .umount = LfsUmount,
676 .umount2 = NULL,
677 .statfs = NULL,
678 };
679
680 static struct FileOps g_lfsFops = {
681 .open = LfsOpen,
682 .close = LfsClose,
683 .read = LfsRead,
684 .write = LfsWrite,
685 .lseek = LfsSeek,
686 .stat = LfsStat,
687 .truncate = NULL,
688 .unlink = LfsUnlink,
689 .rename = LfsRename,
690 .ioctl = NULL, /* not support */
691 .sync = LfsSync,
692 .rmdir = LfsRmdir,
693 .opendir = LfsOpendir,
694 .readdir = LfsReaddir,
695 .closedir = LfsClosedir,
696 .mkdir = LfsMkdir,
697 };
698
699 static struct FsManagement g_lfsMgt = {
700 .fdisk = NULL,
701 .format = LfsFormat,
702 };
703
LfsInit(void)704 void LfsInit(void)
705 {
706 (void)OsFsRegister("littlefs", &g_lfsMnt, &g_lfsFops, &g_lfsMgt);
707 }
708