1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
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 "littlefs.h"
17 #include "flash.h"
18 #include "los_config.h"
19 #include "hdf_log.h"
20 #include "hdf_device_desc.h"
21 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
22 #include "hcs_macro.h"
23 #include "hdf_config_macro.h"
24 #else
25 #include "device_resource_if.h"
26 #endif
27 struct fs_cfg {
28 char *mount_point;
29 struct lfs_config lfs_cfg;
30 };
31
32 static struct fs_cfg fs[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
33 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
34 #define DISPLAY_MISC_FS_LITTLEFS_CONFIG HCS_NODE(HCS_NODE(HCS_NODE(HCS_ROOT, misc), fs_config), littlefs_config)
FsGetResource(struct fs_cfg * fs)35 static uint32_t FsGetResource(struct fs_cfg *fs)
36 {
37 int32_t num = HCS_ARRAYS_SIZE(HCS_NODE(DISPLAY_MISC_FS_LITTLEFS_CONFIG, mount_points));
38 if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
39 HDF_LOGE("%s: invalid mount_points num %d", __func__, num);
40 return HDF_FAILURE;
41 }
42 char * mount_points[] = HCS_ARRAYS(HCS_NODE(DISPLAY_MISC_FS_LITTLEFS_CONFIG, mount_points));
43 uint32_t partitions[] = HCS_ARRAYS(HCS_NODE(DISPLAY_MISC_FS_LITTLEFS_CONFIG, partitions));
44 uint32_t block_size[] = HCS_ARRAYS(HCS_NODE(DISPLAY_MISC_FS_LITTLEFS_CONFIG, block_size));
45 uint32_t block_count[] = HCS_ARRAYS(HCS_NODE(DISPLAY_MISC_FS_LITTLEFS_CONFIG, block_count));
46 for (int32_t i = 0; i < num; i++) {
47 fs[i].mount_point = mount_points[i];
48 fs[i].lfs_cfg.context = partitions[i];
49 fs[i].lfs_cfg.block_size = block_size[i];
50 fs[i].lfs_cfg.block_count = block_count[i];
51
52 HDF_LOGD("%s: fs[%d] mount_point=%s, partition=%u, block_size=%u, block_count=%u", __func__, i,
53 fs[i].mount_point, (uint32_t)fs[i].lfs_cfg.context, fs[i].lfs_cfg.block_size, fs[i].lfs_cfg.block_count);
54 }
55 return HDF_SUCCESS;
56 }
57 #else
FsGetResource(struct fs_cfg * fs,const struct DeviceResourceNode * resourceNode)58 static uint32_t FsGetResource(struct fs_cfg *fs, const struct DeviceResourceNode *resourceNode)
59 {
60 struct DeviceResourceIface *resource = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
61 if (resource == NULL) {
62 HDF_LOGE("Invalid DeviceResourceIface");
63 return HDF_FAILURE;
64 }
65 int32_t num = resource->GetElemNum(resourceNode, "mount_points");
66 if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
67 HDF_LOGE("%s: invalid mount_points num %d", __func__, num);
68 return HDF_FAILURE;
69 }
70 for (int32_t i = 0; i < num; i++) {
71 if (resource->GetStringArrayElem(resourceNode, "mount_points", i, &fs[i].mount_point, NULL) != HDF_SUCCESS) {
72 HDF_LOGE("%s: failed to get mount_points", __func__);
73 return HDF_FAILURE;
74 }
75 if (resource->GetUint32ArrayElem(resourceNode, "partitions", i, (uint32_t *)&fs[i].lfs_cfg.context, 0) != HDF_SUCCESS) {
76 HDF_LOGE("%s: failed to get partitions", __func__);
77 return HDF_FAILURE;
78 }
79 if (resource->GetUint32ArrayElem(resourceNode, "block_size", i, &fs[i].lfs_cfg.block_size, 0) != HDF_SUCCESS) {
80 HDF_LOGE("%s: failed to get block_size", __func__);
81 return HDF_FAILURE;
82 }
83 if (resource->GetUint32ArrayElem(resourceNode, "block_count", i, &fs[i].lfs_cfg.block_count, 0) != HDF_SUCCESS) {
84 HDF_LOGE("%s: failed to get block_count", __func__);
85 return HDF_FAILURE;
86 }
87 HDF_LOGD("%s: fs[%d] mount_point=%s, partition=%u, block_size=%u, block_count=%u", __func__, i,
88 fs[i].mount_point, (uint32_t)fs[i].lfs_cfg.context, fs[i].lfs_cfg.block_size, fs[i].lfs_cfg.block_count);
89 }
90 return HDF_SUCCESS;
91 }
92 #endif
FsDriverInit(struct HdfDeviceObject * object)93 static int32_t FsDriverInit(struct HdfDeviceObject *object)
94 {
95 if (object == NULL) {
96 return HDF_FAILURE;
97 }
98 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
99 if (FsGetResource(fs) != HDF_SUCCESS) {
100 HDF_LOGE("%s: FsGetResource failed", __func__);
101 return HDF_FAILURE;
102 }
103 #else
104 if (object->property) {
105 if (FsGetResource(fs, object->property) != HDF_SUCCESS) {
106 HDF_LOGE("%s: FsGetResource failed", __func__);
107 return HDF_FAILURE;
108 }
109 }
110 #endif
111
112 for (int i = 0; i < sizeof(fs) / sizeof(fs[0]); i++) {
113 if (fs[i].mount_point == NULL)
114 continue;
115
116 fs[i].lfs_cfg.read = littlefs_block_read;
117 fs[i].lfs_cfg.prog = littlefs_block_write;
118 fs[i].lfs_cfg.erase = littlefs_block_erase;
119 fs[i].lfs_cfg.sync = littlefs_block_sync;
120
121 fs[i].lfs_cfg.read_size = 256;
122 fs[i].lfs_cfg.prog_size = 256;
123 fs[i].lfs_cfg.cache_size = 256;
124 fs[i].lfs_cfg.lookahead_size = 16;
125 fs[i].lfs_cfg.block_cycles = 1000;
126
127 SetDefaultMountPath(i, fs[i].mount_point);
128 int ret = mount(NULL, fs[i].mount_point, "littlefs", 0, &fs[i].lfs_cfg);
129 HDF_LOGI("%s: mount fs on '%s' %s\n", __func__, fs[i].mount_point, (ret == 0) ? "succeed" : "failed");
130 }
131 return HDF_SUCCESS;
132 }
133
FsDriverBind(struct HdfDeviceObject * device)134 static int32_t FsDriverBind(struct HdfDeviceObject *device)
135 {
136 (void)device;
137 return HDF_SUCCESS;
138 }
139
FsDriverRelease(struct HdfDeviceObject * device)140 static void FsDriverRelease(struct HdfDeviceObject *device)
141 {
142 (void)device;
143 }
144
145 static struct HdfDriverEntry g_fsDriverEntry = {
146 .moduleVersion = 1,
147 .moduleName = "HDF_FS_LITTLEFS",
148 .Bind = FsDriverBind,
149 .Init = FsDriverInit,
150 .Release = FsDriverRelease,
151 };
152
153 HDF_INIT(g_fsDriverEntry);
154