• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Hunan OpenValley Digital Industry Development Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <string.h>
17 #include <dirent.h>
18 #include <sys/mount.h>
19 #include "sys/stat.h"
20 #include "fcntl.h"
21 #include "littlefs.h"
22 #include "lfs.h"
23 #include "los_memory.h"
24 #include "los_task.h"
25 #include "los_compiler.h"
26 #include "los_fs.h"
27 #include "ohos_init.h"
28 #include "ohos_types.h"
29 
30 
31 const char LITTLEFS_MOUNT_POINT[] = { "/Openvalley" };
32 static const char TAG[] = { "Littlefs" };
33 
34 #define LFS_LOG printf
35 #define RAM_BUF_SIZE   (22*1024)   /* 可以被擦除的块数量,实际大小=BLOCK_SIZE*BLOCK_COUNT字节 */
36 #define READ_SIZE      32    /* 最小读取字节数,所有的读取操作字节数必须是它的倍数(影响内存消耗) */
37 #define PROG_SIZE      READ_SIZE    /* 最小写入字节数,所有的写入操作字节数必须是它的倍数(影响内存消耗) */
38 #define BLOCK_SIZE     128  /* 擦除块字节数,不会影响内存消耗,每个文件至少占用一个块,必须是READ_SIZE/PROG_SIZE的倍数 */
39 #define CACHE_SIZE     READ_SIZE    /* 块缓存的大小,缓存越大磁盘访问越小,性能越高,必须是READ_SIZE/PROG_SIZE的倍数,且是BLOCK_SIZE的因数 */
40 #define LOOKAHEAD_SIZE 16    /* 块分配预测深度,分配块时每次步进多少个块,必须为8的整数倍,对于内存消耗影响不大 */
41 #define BLOCK_CYCLES   (-1)    /* 逐出元数据日志并将元数据移动到另一个块之前的擦除周期数,值越大性能越好,但磨损越不均匀,-1将禁用块级磨损均衡 */
42 
43 
44 /* lfs配置变量,必须是全局内存或静态内存 */
45 static char LittlefsRamBuf[RAM_BUF_SIZE];
46 
47 /* lfs读接口 */
littlefs_block_read(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,char * buffer,lfs_size_t size)48 int littlefs_block_read(const struct lfs_config *cfg, lfs_block_t block,
49                         lfs_off_t off, char *buffer, lfs_size_t size)
50 {
51     int ret;
52     off = cfg->block_size * block + off;
53     if ((off + size) > RAM_BUF_SIZE) {
54         return LOS_NOK;
55     }
56     ret = memcpy_s(buffer, size, (char*)cfg->context + off, size);
57     if (ret != 0) {
58         return LOS_NOK;
59     }
60     return LOS_OK;
61 }
62 
63 /* lfs写接口 */
littlefs_block_write(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,const void * buffer,lfs_size_t size)64 int littlefs_block_write(const struct lfs_config *cfg, lfs_block_t block,
65                         lfs_off_t off, const void *buffer, lfs_size_t size)
66 {
67     int ret;
68     off = cfg->block_size * block + off;
69     if ((off + size) > RAM_BUF_SIZE) {
70         return LOS_NOK;
71     }
72     ret = memcpy_s((char*)cfg->context + off, size, buffer, size);
73     if (ret != 0) {
74         return LOS_NOK;
75     }
76     return LOS_OK;
77 }
78 
79 /* lfs擦除接口 */
littlefs_block_erase(const struct lfs_config * cfg,lfs_block_t block)80 int littlefs_block_erase(const struct lfs_config *cfg, lfs_block_t block)
81 {
82     lfs_off_t off = cfg->block_size * block;
83     if ((off + cfg->block_size) > RAM_BUF_SIZE) {
84         return LOS_NOK;
85     }
86     int ret = memset_s((char*)cfg->context + off, cfg->block_size, 0xFF, cfg->block_size);
87     if (ret != 0) {
88         return LOS_NOK;
89     }
90     return LOS_OK;
91 }
92 
93 // /* lfs同步接口 */
littlefs_block_sync(const struct lfs_config * c)94 int littlefs_block_sync(const struct lfs_config *c)
95 {
96     (void)c;
97     return 0;
98 }
99 
GetLittlefsMountPoint(void)100 const char *GetLittlefsMountPoint(void)
101 {
102     return LITTLEFS_MOUNT_POINT;
103 }
104 
littlefs_config(struct PartitionCfg * pCfg)105 static int littlefs_config(struct PartitionCfg *pCfg)
106 {
107     int ret;
108     pCfg->partNo = (void*)LittlefsRamBuf;
109     ret = memset_s(LittlefsRamBuf, RAM_BUF_SIZE, 0xFF, RAM_BUF_SIZE);
110     if (ret != 0) {
111         return LOS_NOK;
112     }
113     pCfg->blockCount = RAM_BUF_SIZE / BLOCK_SIZE;
114     pCfg->readSize = READ_SIZE;
115     pCfg->writeSize = PROG_SIZE;
116     pCfg->cacheSize = CACHE_SIZE;
117     pCfg->blockCycles = BLOCK_CYCLES;
118     pCfg->lookaheadSize = LOOKAHEAD_SIZE;
119     pCfg->blockSize = BLOCK_SIZE;
120     pCfg->readFunc = NULL;
121     pCfg->writeFunc = NULL;
122     pCfg->eraseFunc = NULL;
123     return LOS_OK;
124 }
125 // /* lfs初始化 */
LittlefsInit(void)126 static INT32 LittlefsInit(void)
127 {
128     int err, ret;
129     DIR* dir;
130     struct PartitionCfg cfg  = {0};
131     if (littlefs_config(&cfg) == LOS_NOK) {
132         return LOS_NOK;
133     }
134     /* 设置挂载Littlefs */
135     err = mount(NULL, LITTLEFS_MOUNT_POINT, "littlefs", 0, &cfg);
136     if (err != LOS_OK) {
137         LFS_LOG("Error %s.mount=0x%X\n", TAG, err);
138         return LOS_NOK;
139     }
140     mkdir(LITTLEFS_MOUNT_POINT, S_IRUSR | S_IWUSR);
141     return LOS_OK;
142 }
143 
144 SYS_FEATURE_INIT(LittlefsInit);
145