1 /*
2 * Copyright (c) 2022 FuZhou Lockzhiner Electronic 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 <string.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 "osal_mem.h"
22 #include "lfs.h"
23 #include "lfs_adapter.h"
24
25 #include "lz_hardware.h"
26
27 #define PRINT_ERR(fmt, args...) do { \
28 printf("%s, %d, error: "fmt, __func__, __LINE__, ##args); \
29 } while (0)
30
31 #define PRINT_WARR(fmt, args...) do { \
32 if (1) printf("%s, %d, warr: "fmt, __func__, __LINE__, ##args); \
33 } while (0)
34
35 #define PRINT_LOG(fmt, args...) do { \
36 if (1) printf("%s, %d, log: "fmt, __func__, __LINE__, ##args); \
37 } while (0)
38
39 /* 分配给用户的Flash空间为4M ~ 8MB */
40 #define FLASH_ADDRESS_USER_START (0x400000)
41 #define FLASH_ADDRESS_USER_END (0x800000)
42
43 struct fs_cfg {
44 char *mount_point;
45 uint32_t block_start;
46 struct lfs_config lfs_cfg;
47 };
48
49 static struct fs_cfg m_fs_cfg[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
50
51 /* 定义lfs_cfg的相关参数 */
52 #define LFSCFG_READSIZE_MAX 4
53 #define LFSCFG_PROGSIZE_MAX 4
54 #define LFSCFG_CACHESIZE_MAX 256
55 #define LFSCFG_LOCKAHEADSIZE_MAX 64
56 #define LFSCFG_BLOCKCYCLES_MAX 1000
57
fs_get_partition(void *str, uint32_t *partition)58 static int32_t fs_get_partition(void *str, uint32_t *partition)
59 {
60 int i;
61 char *src = (char *)str;
62
63 for (i = 0; i < (sizeof(m_fs_cfg) / sizeof(struct fs_cfg)); i++) {
64 if (strcmp(m_fs_cfg[i].mount_point, src) == 0) {
65 *partition = i;
66 return HDF_SUCCESS;
67 }
68 }
69
70 return HDF_ERR_NOT_SUPPORT;
71 }
72
fs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *dst, lfs_size_t size)73 static int32_t fs_read(const struct lfs_config *c,
74 lfs_block_t block,
75 lfs_off_t off,
76 void *dst,
77 lfs_size_t size)
78 {
79 int32_t ret;
80 struct fs_cfg *fs;
81 uint32_t addr;
82 uint32_t partition_offset;
83 unsigned char *str;
84
85 if (c == NULL) {
86 PRINT_ERR("c is null\n");
87 return LFS_ERR_INVAL;
88 }
89 if ((block * c->block_size + off) >= (c->block_size * c->block_count)) {
90 PRINT_ERR("read_start(%d) >= block_count(%d)\n", (block * c->block_size + off),
91 (c->block_size * c->block_count));
92 return LFS_ERR_INVAL;
93 }
94 if ((block * c->block_size + off + size) > (c->block_size * c->block_count)) {
95 PRINT_ERR("read_end(%d) > maxsize(%d)\n", (block * c->block_size + off + size),
96 (c->block_size * c->block_count));
97 return LFS_ERR_INVAL;
98 }
99 if (dst == NULL) {
100 PRINT_ERR("dst is null\n");
101 return LFS_ERR_INVAL;
102 }
103
104 ret = fs_get_partition(c->context, &partition_offset);
105 if (ret != HDF_SUCCESS) {
106 PRINT_ERR("c->context(%s) is not support\n", c->context);
107 return LFS_ERR_INVAL;
108 }
109
110 fs = &m_fs_cfg[partition_offset];
111 addr = ((fs->block_start + block) * c->block_size) + off;
112 str = (unsigned char *)dst;
113
114 ret = (unsigned int)FlashRead(addr, size, str);
115 if (ret != LZ_HARDWARE_SUCCESS) {
116 PRINT_ERR("FlashRead failed(%d)\n", ret);
117 return LFS_ERR_IO;
118 }
119
120 return LFS_ERR_OK;
121 }
122
fs_write(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *src, lfs_size_t size)123 static int32_t fs_write(const struct lfs_config *c,
124 lfs_block_t block,
125 lfs_off_t off,
126 const void *src,
127 lfs_size_t size)
128 {
129 unsigned int res;
130 int32_t ret;
131 struct fs_cfg *fs;
132 uint32_t addr;
133 uint32_t partition_offset;
134 unsigned char *buffer;
135 uint32_t buffer_length;
136 uint32_t block_size;
137 uint32_t block_start, block_offset, block_end;
138 uint32_t flash_block_address;
139 unsigned char *str;
140 uint32_t str_offset;
141 uint32_t write_offset, write_length;
142
143 if (c == NULL) {
144 PRINT_ERR("c is null\n");
145 return LFS_ERR_INVAL;
146 }
147 if ((c->block_size * block + off) >= (c->block_size * c->block_count)) {
148 PRINT_ERR("write_start(%d) >= maxsize(%d)\n", (c->block_size * block + off),
149 (c->block_size * c->block_count));
150 return LFS_ERR_INVAL;
151 }
152 if ((c->block_size * block + off + size) > (c->block_size * c->block_count)) {
153 PRINT_ERR("write_end(%d) > maxsize(%d)\n", (c->block_size * block + off + size),
154 (c->block_size * c->block_count));
155 return LFS_ERR_INVAL;
156 }
157 if (src == NULL) {
158 PRINT_ERR("src is null\n");
159 return LFS_ERR_INVAL;
160 }
161
162 ret = fs_get_partition(c->context, &partition_offset);
163 if (ret != HDF_SUCCESS) {
164 PRINT_ERR("c->context(%s) is not support\n", c->context);
165 return LFS_ERR_INVAL;
166 }
167
168 block_size = c->block_size;
169 addr = ((m_fs_cfg[partition_offset].block_start + block) * block_size) + off;
170 block_start = addr / block_size;
171 block_end = (addr + size) / block_size;
172 if (((addr + size) % block_size) != 0) {
173 block_end++;
174 }
175
176 buffer = (unsigned char *)malloc(sizeof(unsigned char) * block_size);
177 if (buffer == NULL) {
178 PRINT_ERR("malloc failed\n");
179 return LFS_ERR_NOMEM;
180 }
181
182 str = (unsigned char *)src;
183 str_offset = 0;
184
185 for (block_offset = block_start; block_offset < block_end; block_offset++) {
186 if (block_offset == block_start) {
187 /* 开头特殊处理 */
188 flash_block_address = block_offset * block_size;
189 write_offset = (addr - flash_block_address);
190 write_length = block_size - write_offset;
191 /* 读取整块数据,擦除整块数据,修改部分数据,最后写入Flash */
192 res = FlashRead(flash_block_address, block_size, buffer);
193 if (res != LZ_HARDWARE_SUCCESS) {
194 PRINT_ERR("FlashRead(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
195 return LFS_ERR_IO;
196 }
197 res = FlashErase(flash_block_address, block_size);
198 if (res != LZ_HARDWARE_SUCCESS) {
199 PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
200 return LFS_ERR_IO;
201 }
202 memcpy_s(&buffer[write_offset], block_size - write_offset, &src[str_offset], write_length);
203 res = FlashWrite(flash_block_address, block_size, buffer, 0);
204 if (res != LZ_HARDWARE_SUCCESS) {
205 PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
206 return LFS_ERR_IO;
207 }
208 str_offset += write_length;
209 } else if (block_offset == (block_end - 1)) {
210 /* 结尾特殊处理 */
211 flash_block_address = block_offset * block_size;
212 write_offset = 0;
213 write_length = (addr + size) - flash_block_address;
214 /* 读取整块数据,擦除整块数据,修改部分数据,最后写入Flash */
215 res = FlashRead(flash_block_address, block_size, buffer);
216 if (res != LZ_HARDWARE_SUCCESS) {
217 PRINT_ERR("FlashRead(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
218 return LFS_ERR_IO;
219 }
220 res = FlashErase(flash_block_address, block_size);
221 if (res != LZ_HARDWARE_SUCCESS) {
222 PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
223 return LFS_ERR_IO;
224 }
225 memcpy_s(&buffer[write_offset], block_size - write_offset, &src[str_offset], write_length);
226 res = FlashWrite(flash_block_address, block_size, buffer, 0);
227 if (res != LZ_HARDWARE_SUCCESS) {
228 PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
229 return LFS_ERR_IO;
230 }
231 str_offset += write_length;
232 } else {
233 /* 中间的部分数据,整块处理 */
234 flash_block_address = block_offset * block_size;
235 write_offset = 0;
236 write_length = block_size;
237 /* 读取整块数据,擦除整块数据,最后写入Flash */
238 res = FlashErase(flash_block_address, block_size);
239 if (res != LZ_HARDWARE_SUCCESS) {
240 PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
241 return LFS_ERR_IO;
242 }
243 res = FlashWrite(flash_block_address, block_size, &src[str_offset], 0);
244 if (res != LZ_HARDWARE_SUCCESS) {
245 PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
246 return LFS_ERR_IO;
247 }
248 str_offset += write_length;
249 }
250 }
251
252 if (buffer != NULL) {
253 free(buffer);
254 buffer = NULL;
255 }
256
257 return LFS_ERR_OK;
258 }
259
fs_erase(const struct lfs_config *c, lfs_block_t block)260 static int32_t fs_erase(const struct lfs_config *c, lfs_block_t block)
261 {
262 int32_t ret;
263 struct fs_cfg *fs;
264 uint32_t addr;
265 uint32_t partition_offset;
266
267 if (c == NULL) {
268 PRINT_ERR("c is null\n");
269 return LFS_ERR_INVAL;
270 }
271 if (block >= c->block_count) {
272 PRINT_ERR("block(%d) >= block_count(%d)\n", block, c->block_count);
273 return LFS_ERR_INVAL;
274 }
275
276 ret = fs_get_partition(c->context, &partition_offset);
277 if (ret != HDF_SUCCESS) {
278 PRINT_ERR("c->context(%s) is not support\n", c->context);
279 return LFS_ERR_INVAL;
280 }
281
282 fs = &m_fs_cfg[partition_offset];
283 addr = ((fs->block_start + block) * c->block_size);
284 FlashErase(addr, c->block_size);
285
286 return LFS_ERR_OK;
287 }
288
fs_sync(const struct lfs_config *c)289 static int32_t fs_sync(const struct lfs_config *c)
290 {
291 return LFS_ERR_OK;
292 }
293
fsdrv_readdrs(const struct DeviceResourceNode *node, struct fs_cfg *fs)294 static uint32_t fsdrv_readdrs(const struct DeviceResourceNode *node, struct fs_cfg *fs)
295 {
296 int32_t ret;
297 struct DeviceResourceIface *iface = NULL;
298 int32_t num = 0;
299 uint32_t block_size = FlashGetBlockSize();
300 uint32_t address_start, address_end;
301
302 if (node == NULL) {
303 PRINT_ERR("node is null\n");
304 return HDF_ERR_INVALID_PARAM;
305 }
306 if (fs == NULL) {
307 PRINT_ERR("fs is null\n");
308 return HDF_ERR_INVALID_PARAM;
309 }
310
311 iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
312 if (iface == NULL) {
313 PRINT_ERR("iface is null\n");
314 return HDF_ERR_INVALID_PARAM;
315 }
316 if (iface->GetElemNum == NULL) {
317 PRINT_ERR("GetElemNum is null\n");
318 return HDF_ERR_INVALID_PARAM;
319 }
320 if (iface->GetStringArrayElem == NULL) {
321 PRINT_ERR("GetStringArrayElem is null\n");
322 return HDF_ERR_INVALID_PARAM;
323 }
324 if (iface->GetUint32ArrayElem == NULL) {
325 PRINT_ERR("GetStringArrayElem is null\n");
326 return HDF_ERR_INVALID_PARAM;
327 }
328
329 num = iface->GetElemNum(node, "mount_points");
330 if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
331 PRINT_ERR("invalid mount_points num %d", num);
332 return HDF_FAILURE;
333 }
334
335 for (int32_t i = 0; i < num; i++) {
336 ret = iface->GetStringArrayElem(node, "mount_points", i, &fs[i].mount_point, NULL);
337 if (ret != HDF_SUCCESS) {
338 PRINT_ERR("failed to get mount_points");
339 return HDF_FAILURE;
340 }
341
342 fs[i].lfs_cfg.context = (void *)fs[i].mount_point;
343
344 ret = iface->GetUint32ArrayElem(node, "block_size", i, &fs[i].lfs_cfg.block_size, NULL);
345 if (ret != HDF_SUCCESS) {
346 PRINT_ERR("failed to get block_size");
347 return HDF_FAILURE;
348 }
349
350 ret = iface->GetUint32ArrayElem(node, "block_count", i, &fs[i].lfs_cfg.block_count, NULL);
351 if (ret != HDF_SUCCESS) {
352 PRINT_ERR("failed to get block_count");
353 return HDF_FAILURE;
354 }
355
356 ret = iface->GetUint32ArrayElem(node, "block_start", i, &fs[i].block_start, NULL);
357 if (ret != HDF_SUCCESS) {
358 PRINT_ERR("failed to get block_start");
359 return HDF_FAILURE;
360 }
361 }
362
363 /* 检查相关参数是否正确 */
364 for (int32_t i = 0; i < num; i++) {
365 if (fs[i].mount_point == NULL) {
366 break;
367 }
368
369 PRINT_LOG("fs[%d]:\n", i);
370 PRINT_LOG(" mount_points = %s\n", fs[i].mount_point);
371 PRINT_LOG(" context = %s\n", (char *)fs[i].lfs_cfg.context);
372 PRINT_LOG(" block_size = %d\n", fs[i].lfs_cfg.block_size);
373 PRINT_LOG(" block_count = %d\n", fs[i].lfs_cfg.block_count);
374 PRINT_LOG(" block_start = %d\n", fs[i].block_start);
375
376 /* 检查 */
377 if (fs[i].lfs_cfg.block_size != block_size) {
378 PRINT_ERR("littefs[%d].lfs_cfg.block_size(%d) != flash_block_size(%d)\n",
379 i, fs[i].lfs_cfg.block_size, block_size);
380 return HDF_ERR_INVALID_PARAM;
381 }
382
383 address_start = (uint32_t)(fs[i].block_start * fs[i].lfs_cfg.block_size);
384 if (address_start < FLASH_ADDRESS_USER_START) {
385 PRINT_ERR("partition[%d].address_start(%d) < FLASH_ADDRESS_USER_START(%d)\n",
386 i, address_start, FLASH_ADDRESS_USER_START);
387 return HDF_FAILURE;
388 }
389
390 address_end = (uint32_t)((fs[i].block_start + fs[i].lfs_cfg.block_count) * fs[i].lfs_cfg.block_size);
391 if (address_end > FLASH_ADDRESS_USER_END) {
392 PRINT_ERR("partition[%d].address_end(%d) < FLASH_ADDRESS_USER_END(%d)\n",
393 i, address_end, FLASH_ADDRESS_USER_END);
394 return HDF_FAILURE;
395 }
396 }
397
398 return HDF_SUCCESS;
399 }
400
fsdrv_init(struct HdfDeviceObject *device)401 static int32_t fsdrv_init(struct HdfDeviceObject *device)
402 {
403 int result;
404 int32_t ret;
405 struct FileOpInfo *file_op_info = NULL;
406
407 if (device == NULL) {
408 PRINT_ERR("device is null\n");
409 return HDF_ERR_INVALID_OBJECT;
410 }
411 if (device->property == NULL) {
412 PRINT_ERR("device is null\n");
413 return HDF_ERR_INVALID_OBJECT;
414 }
415
416 /* Flash设备初始化 */
417 FlashInit();
418
419 ret = fsdrv_readdrs(device->property, &m_fs_cfg[0]);
420 if (ret != HDF_SUCCESS) {
421 PRINT_ERR("%s: fsdrv_readdrs failed(%d)\n", __func__, ret);
422 return ret;
423 }
424
425 for (int i = 0; i < sizeof(m_fs_cfg) / sizeof(m_fs_cfg[0]); i++) {
426 if (m_fs_cfg[i].mount_point == NULL) {
427 PRINT_LOG("m_fs_cfg[%d].mount_point is null\n", i);
428 continue;
429 }
430
431 m_fs_cfg[i].lfs_cfg.read = fs_read;
432 m_fs_cfg[i].lfs_cfg.prog = fs_write;
433 m_fs_cfg[i].lfs_cfg.erase = fs_erase;
434 m_fs_cfg[i].lfs_cfg.sync = fs_sync;
435
436 m_fs_cfg[i].lfs_cfg.read_size = LFSCFG_READSIZE_MAX;
437 m_fs_cfg[i].lfs_cfg.prog_size = LFSCFG_PROGSIZE_MAX;
438 m_fs_cfg[i].lfs_cfg.cache_size = LFSCFG_CACHESIZE_MAX;
439 m_fs_cfg[i].lfs_cfg.lookahead_size = LFSCFG_LOCKAHEADSIZE_MAX;
440 m_fs_cfg[i].lfs_cfg.block_cycles = LFSCFG_BLOCKCYCLES_MAX;
441
442 m_fs_cfg[i].lfs_cfg.file_max = LFS_FILE_MAX;
443 m_fs_cfg[i].lfs_cfg.name_max = LFS_NAME_MAX;
444
445 result = mount(NULL, m_fs_cfg[i].mount_point, "littlefs", 0, &m_fs_cfg[i].lfs_cfg);
446 printf("%s: mount fs on '%s' %s\n", __func__, m_fs_cfg[i].mount_point, (result == 0) ? "succeed" : "failed");
447 if (ret == 0) {
448 ret = mkdir(m_fs_cfg[i].mount_point, S_IRWXU | S_IRWXG | S_IRWXO);
449 if (ret == 0) {
450 PRINT_LOG("create root dir(%s) success.\n", m_fs_cfg[i].mount_point);
451 } else if (errno == EEXIST) {
452 PRINT_LOG("root dir(%s) exist.\n", m_fs_cfg[i].mount_point);
453 } else {
454 PRINT_LOG("create root dir(%s) failed.", m_fs_cfg[i].mount_point);
455 }
456 }
457 }
458
459 PRINT_LOG("LittleFS service: %s init success!\n", HdfDeviceGetServiceName(device));
460 return HDF_SUCCESS;
461 }
462
fsdrv_bind(struct HdfDeviceObject *device)463 static int32_t fsdrv_bind(struct HdfDeviceObject *device)
464 {
465 (void)device;
466 return HDF_SUCCESS;
467 }
468
fsdrv_release(struct HdfDeviceObject *device)469 static void fsdrv_release(struct HdfDeviceObject *device)
470 {
471 (void)device;
472 PRINT_LOG("LittleFS service: %s release\n", HdfDeviceGetServiceName(device));
473 }
474
475 static struct HdfDriverEntry g_fsDriverEntry = {
476 .moduleVersion = 1,
477 .moduleName = "HDF_PLATFORM_FS_LITTLEFS",
478 .Bind = fsdrv_bind,
479 .Init = fsdrv_init,
480 .Release = fsdrv_release,
481 };
482
483 HDF_INIT(g_fsDriverEntry);
484