• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 GOODIX.
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 #include <sys/mount.h>
16 #include <los_fs.h>
17 #include "los_config.h"
18 #include "hdf_log.h"
19 #include "hdf_device_desc.h"
20 #include "device_resource_if.h"
21 #include "lfs_adapter.h"
22 #include "gr55xx_hal.h"
23 #include "hal_flash.h"
24 
25 #define LFS_CFG_READ_SIZE       16
26 #define LFS_CFG_PROG_SIZE       16
27 #define LFS_CFG_CACHE_SIZE      16
28 #define LFS_CFG_LOOKAHEAD_SIZE  32
29 #define LFS_CFG_BLOCK_CYCLES    500
30 #define LFS_CFG_BLOCK_SIZE      4096
31 #define LFS_CFG_BLOCK_COUNT     75
32 
33 #define LITTLEFS_PHYS_ADDR (0x10b4000)
34 #define LITTLEFS_PHYS_SIZE (300 * 1024)
35 
36 struct fs_cfg {
37     char *mount_point;
38     struct lfs_config lfs_cfg;
39 };
40 
littlefs_block_read(int partition,uint32_t * offset,uint8_t * buf,uint32_t size)41 static int littlefs_block_read(int partition, uint32_t *offset, uint8_t *buf, uint32_t size)
42 {
43     hal_flash_read(LITTLEFS_PHYS_ADDR + *offset, buf, size);
44     return LFS_ERR_OK;
45 }
46 
littlefs_block_write(int partition,uint32_t * offset,const uint8_t * buf,uint32_t size)47 static int littlefs_block_write(int partition, uint32_t *offset, const uint8_t *buf, uint32_t size)
48 {
49     hal_flash_write(LITTLEFS_PHYS_ADDR + *offset, (unsigned char *)buf, size);
50     return LFS_ERR_OK;
51 }
52 
littlefs_block_erase(int partition,uint32_t offset,uint32_t size)53 static int littlefs_block_erase(int partition, uint32_t offset, uint32_t size)
54 {
55     hal_flash_erase(LITTLEFS_PHYS_ADDR + offset, LFS_CFG_BLOCK_SIZE);
56     return LFS_ERR_OK;
57 }
58 
59 static struct fs_cfg fs[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
60 
FsGetResource(struct fs_cfg * fs,const struct DeviceResourceNode * resourceNode)61 static uint32_t FsGetResource(struct fs_cfg *fs, const struct DeviceResourceNode *resourceNode)
62 {
63     struct DeviceResourceIface *resource = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
64     if (resource == NULL) {
65         HDF_LOGE("Invalid DeviceResourceIface");
66         return HDF_FAILURE;
67     }
68     int32_t num = resource->GetElemNum(resourceNode, "mount_points");
69     if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
70         HDF_LOGE("%s: invalid mount_points num %d", __func__, num);
71         return HDF_FAILURE;
72     }
73     for (int32_t i = 0; i < num; i++) {
74         if (resource->GetStringArrayElem(resourceNode, "mount_points", i, &fs[i].mount_point, NULL) != HDF_SUCCESS) {
75             HDF_LOGE("%s: failed to get mount_points", __func__);
76             return HDF_FAILURE;
77         }
78         if (resource->GetUint32ArrayElem(resourceNode, "partitions", i,
79                                          (uint32_t *)&fs[i].lfs_cfg.context, 0) != HDF_SUCCESS) {
80             HDF_LOGE("%s: failed to get partitions", __func__);
81             return HDF_FAILURE;
82         }
83         if (resource->GetUint32ArrayElem(resourceNode, "block_size", i, &fs[i].lfs_cfg.block_size, 0) != HDF_SUCCESS) {
84             HDF_LOGE("%s: failed to get block_size", __func__);
85             return HDF_FAILURE;
86         }
87         if (resource->GetUint32ArrayElem(resourceNode, "block_count", i,
88                                          &fs[i].lfs_cfg.block_count, 0) != HDF_SUCCESS) {
89             HDF_LOGE("%s: failed to get block_count", __func__);
90             return HDF_FAILURE;
91         }
92         HDF_LOGD("%s: fs[%d] mount_point=%s, partition=%u, block_size=%u, block_count=%u", __func__, i,
93                  fs[i].mount_point, (uint32_t)fs[i].lfs_cfg.context, fs[i].lfs_cfg.block_size,
94                  fs[i].lfs_cfg.block_count);
95     }
96     return HDF_SUCCESS;
97 }
98 
PartitionsInit(void)99 void PartitionsInit(void)
100 {
101     int lengthArray[LOSCFG_LFS_MAX_MOUNT_SIZE];
102     int addrArray[LOSCFG_LFS_MAX_MOUNT_SIZE];
103     int nextAddr = 0;
104 
105     for (int i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) {
106         lengthArray[i] = fs[i].lfs_cfg.block_count * fs[i].lfs_cfg.block_size;
107         addrArray[i] = nextAddr;
108         nextAddr += lengthArray[i];
109     }
110 
111     (VOID) LOS_DiskPartition("flash0", "littlefs", lengthArray, addrArray, LOSCFG_LFS_MAX_MOUNT_SIZE);
112 }
113 
FsDriverInit(struct HdfDeviceObject * object)114 static int32_t FsDriverInit(struct HdfDeviceObject *object)
115 {
116     struct FileOpInfo *fileOpInfo = NULL;
117 
118     if (object == NULL) {
119         return HDF_FAILURE;
120     }
121     if (object->property) {
122         if (FsGetResource(fs, object->property) != HDF_SUCCESS) {
123             HDF_LOGE("%s: FsGetResource failed", __func__);
124             return HDF_FAILURE;
125         }
126     }
127 
128     PartitionsInit();
129 
130     struct PartitionCfg partCfg = {.readSize = LFS_CFG_READ_SIZE,
131         .writeSize = LFS_CFG_PROG_SIZE,
132         .cacheSize = LFS_CFG_CACHE_SIZE,
133         .partNo = 0,
134         .blockCycles = LFS_CFG_BLOCK_CYCLES,
135         .lookaheadSize = LFS_CFG_LOOKAHEAD_SIZE,
136         .readFunc = littlefs_block_read,
137         .writeFunc = littlefs_block_write,
138         .eraseFunc = littlefs_block_erase};
139 
140     for (int i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) {
141         if (fs[i].mount_point == NULL) {
142             continue;
143         }
144 
145         partCfg.blockSize = fs[i].lfs_cfg.block_size;
146         partCfg.blockCount = fs[i].lfs_cfg.block_count;
147 
148         int ret = mount(NULL, fs[i].mount_point, "littlefs", 0, &partCfg);
149         HDF_LOGI("%s: mount fs on '%s' %s\n", __func__, fs[i].mount_point, (ret == 0) ? "succeed" : "failed");
150         if (ret == 0) {
151             ret = mkdir(fs[i].mount_point, S_IRWXU | S_IRWXG | S_IRWXO);
152             if (ret == 0) {
153                 HDF_LOGI("create root dir success.");
154             } else if (errno == EEXIST) {
155                 HDF_LOGI("root dir exist.");
156             } else {
157                 HDF_LOGI("create root dir failed.");
158             }
159         }
160     }
161 
162     return HDF_SUCCESS;
163 }
164 
FsDriverBind(struct HdfDeviceObject * device)165 static int32_t FsDriverBind(struct HdfDeviceObject *device)
166 {
167     (void)device;
168     return HDF_SUCCESS;
169 }
170 
FsDriverRelease(struct HdfDeviceObject * device)171 static void FsDriverRelease(struct HdfDeviceObject *device)
172 {
173     (void)device;
174 }
175 
176 static struct HdfDriverEntry g_fsDriverEntry = {
177     .moduleVersion = 1,
178     .moduleName = "HDF_FS_LITTLEFS",
179     .Bind = FsDriverBind,
180     .Init = FsDriverInit,
181     .Release = FsDriverRelease,
182 };
183 
184 HDF_INIT(g_fsDriverEntry);
185