13d0407baSopenharmony_ci/*
23d0407baSopenharmony_ci * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43d0407baSopenharmony_ci * you may not use this file except in compliance with the License.
53d0407baSopenharmony_ci * You may obtain a copy of the License at
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83d0407baSopenharmony_ci *
93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123d0407baSopenharmony_ci * See the License for the specific language governing permissions and
133d0407baSopenharmony_ci * limitations under the License.
143d0407baSopenharmony_ci */
153d0407baSopenharmony_ci#include <sys/mount.h>
163d0407baSopenharmony_ci#include <string.h>
173d0407baSopenharmony_ci#include "los_config.h"
183d0407baSopenharmony_ci#include "hdf_log.h"
193d0407baSopenharmony_ci#include "hdf_device_desc.h"
203d0407baSopenharmony_ci#include "device_resource_if.h"
213d0407baSopenharmony_ci#include "osal_mem.h"
223d0407baSopenharmony_ci#include "lfs.h"
233d0407baSopenharmony_ci#include "lfs_adapter.h"
243d0407baSopenharmony_ci
253d0407baSopenharmony_ci#include "lz_hardware.h"
263d0407baSopenharmony_ci
273d0407baSopenharmony_ci#define PRINT_ERR(fmt, args...)     do { \
283d0407baSopenharmony_ci    printf("%s, %d, error: "fmt, __func__, __LINE__, ##args); \
293d0407baSopenharmony_ci} while (0)
303d0407baSopenharmony_ci
313d0407baSopenharmony_ci#define PRINT_WARR(fmt, args...)    do { \
323d0407baSopenharmony_ci    if (1) printf("%s, %d, warr: "fmt, __func__, __LINE__, ##args); \
333d0407baSopenharmony_ci} while (0)
343d0407baSopenharmony_ci
353d0407baSopenharmony_ci#define PRINT_LOG(fmt, args...)    do { \
363d0407baSopenharmony_ci    if (1) printf("%s, %d, log: "fmt, __func__, __LINE__, ##args); \
373d0407baSopenharmony_ci} while (0)
383d0407baSopenharmony_ci
393d0407baSopenharmony_ci/* 分配给用户的Flash空间为4M ~ 8MB */
403d0407baSopenharmony_ci#define FLASH_ADDRESS_USER_START       (0x400000)
413d0407baSopenharmony_ci#define FLASH_ADDRESS_USER_END         (0x800000)
423d0407baSopenharmony_ci
433d0407baSopenharmony_cistruct fs_cfg {
443d0407baSopenharmony_ci    char *mount_point;
453d0407baSopenharmony_ci    uint32_t block_start;
463d0407baSopenharmony_ci    struct lfs_config lfs_cfg;
473d0407baSopenharmony_ci};
483d0407baSopenharmony_ci
493d0407baSopenharmony_cistatic struct fs_cfg m_fs_cfg[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
503d0407baSopenharmony_ci
513d0407baSopenharmony_ci/* 定义lfs_cfg的相关参数 */
523d0407baSopenharmony_ci#define LFSCFG_READSIZE_MAX             4
533d0407baSopenharmony_ci#define LFSCFG_PROGSIZE_MAX             4
543d0407baSopenharmony_ci#define LFSCFG_CACHESIZE_MAX            256
553d0407baSopenharmony_ci#define LFSCFG_LOCKAHEADSIZE_MAX        64
563d0407baSopenharmony_ci#define LFSCFG_BLOCKCYCLES_MAX          1000
573d0407baSopenharmony_ci
583d0407baSopenharmony_cistatic int32_t fs_get_partition(void *str, uint32_t *partition)
593d0407baSopenharmony_ci{
603d0407baSopenharmony_ci    int i;
613d0407baSopenharmony_ci    char *src = (char *)str;
623d0407baSopenharmony_ci
633d0407baSopenharmony_ci    for (i = 0; i < (sizeof(m_fs_cfg) / sizeof(struct fs_cfg)); i++) {
643d0407baSopenharmony_ci        if (strcmp(m_fs_cfg[i].mount_point, src) == 0) {
653d0407baSopenharmony_ci            *partition = i;
663d0407baSopenharmony_ci            return HDF_SUCCESS;
673d0407baSopenharmony_ci        }
683d0407baSopenharmony_ci    }
693d0407baSopenharmony_ci
703d0407baSopenharmony_ci    return HDF_ERR_NOT_SUPPORT;
713d0407baSopenharmony_ci}
723d0407baSopenharmony_ci
733d0407baSopenharmony_cistatic int32_t fs_read(const struct lfs_config *c,
743d0407baSopenharmony_ci                       lfs_block_t block,
753d0407baSopenharmony_ci                       lfs_off_t off,
763d0407baSopenharmony_ci                       void *dst,
773d0407baSopenharmony_ci                       lfs_size_t size)
783d0407baSopenharmony_ci{
793d0407baSopenharmony_ci    int32_t ret;
803d0407baSopenharmony_ci    struct fs_cfg *fs;
813d0407baSopenharmony_ci    uint32_t addr;
823d0407baSopenharmony_ci    uint32_t partition_offset;
833d0407baSopenharmony_ci    unsigned char *str;
843d0407baSopenharmony_ci
853d0407baSopenharmony_ci    if (c == NULL) {
863d0407baSopenharmony_ci        PRINT_ERR("c is null\n");
873d0407baSopenharmony_ci        return LFS_ERR_INVAL;
883d0407baSopenharmony_ci    }
893d0407baSopenharmony_ci    if ((block * c->block_size + off) >= (c->block_size * c->block_count)) {
903d0407baSopenharmony_ci        PRINT_ERR("read_start(%d) >= block_count(%d)\n", (block * c->block_size + off),
913d0407baSopenharmony_ci                (c->block_size * c->block_count));
923d0407baSopenharmony_ci        return LFS_ERR_INVAL;
933d0407baSopenharmony_ci    }
943d0407baSopenharmony_ci    if ((block * c->block_size + off + size) > (c->block_size * c->block_count)) {
953d0407baSopenharmony_ci        PRINT_ERR("read_end(%d) > maxsize(%d)\n", (block * c->block_size + off + size),
963d0407baSopenharmony_ci                (c->block_size * c->block_count));
973d0407baSopenharmony_ci        return LFS_ERR_INVAL;
983d0407baSopenharmony_ci    }
993d0407baSopenharmony_ci    if (dst == NULL) {
1003d0407baSopenharmony_ci        PRINT_ERR("dst is null\n");
1013d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1023d0407baSopenharmony_ci    }
1033d0407baSopenharmony_ci
1043d0407baSopenharmony_ci    ret = fs_get_partition(c->context, &partition_offset);
1053d0407baSopenharmony_ci    if (ret != HDF_SUCCESS) {
1063d0407baSopenharmony_ci        PRINT_ERR("c->context(%s) is not support\n", c->context);
1073d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1083d0407baSopenharmony_ci    }
1093d0407baSopenharmony_ci
1103d0407baSopenharmony_ci    fs = &m_fs_cfg[partition_offset];
1113d0407baSopenharmony_ci    addr = ((fs->block_start + block) * c->block_size) + off;
1123d0407baSopenharmony_ci    str = (unsigned char *)dst;
1133d0407baSopenharmony_ci
1143d0407baSopenharmony_ci    ret = (unsigned int)FlashRead(addr, size, str);
1153d0407baSopenharmony_ci    if (ret != LZ_HARDWARE_SUCCESS) {
1163d0407baSopenharmony_ci        PRINT_ERR("FlashRead failed(%d)\n", ret);
1173d0407baSopenharmony_ci        return LFS_ERR_IO;
1183d0407baSopenharmony_ci    }
1193d0407baSopenharmony_ci
1203d0407baSopenharmony_ci    return LFS_ERR_OK;
1213d0407baSopenharmony_ci}
1223d0407baSopenharmony_ci
1233d0407baSopenharmony_cistatic int32_t fs_write(const struct lfs_config *c,
1243d0407baSopenharmony_ci                        lfs_block_t block,
1253d0407baSopenharmony_ci                        lfs_off_t off,
1263d0407baSopenharmony_ci                        const void *src,
1273d0407baSopenharmony_ci                        lfs_size_t size)
1283d0407baSopenharmony_ci{
1293d0407baSopenharmony_ci    unsigned int res;
1303d0407baSopenharmony_ci    int32_t ret;
1313d0407baSopenharmony_ci    struct fs_cfg *fs;
1323d0407baSopenharmony_ci    uint32_t addr;
1333d0407baSopenharmony_ci    uint32_t partition_offset;
1343d0407baSopenharmony_ci    unsigned char *buffer;
1353d0407baSopenharmony_ci    uint32_t buffer_length;
1363d0407baSopenharmony_ci    uint32_t block_size;
1373d0407baSopenharmony_ci    uint32_t block_start, block_offset, block_end;
1383d0407baSopenharmony_ci    uint32_t flash_block_address;
1393d0407baSopenharmony_ci    unsigned char *str;
1403d0407baSopenharmony_ci    uint32_t str_offset;
1413d0407baSopenharmony_ci    uint32_t write_offset, write_length;
1423d0407baSopenharmony_ci
1433d0407baSopenharmony_ci    if (c == NULL) {
1443d0407baSopenharmony_ci        PRINT_ERR("c is null\n");
1453d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1463d0407baSopenharmony_ci    }
1473d0407baSopenharmony_ci    if ((c->block_size * block + off) >= (c->block_size * c->block_count)) {
1483d0407baSopenharmony_ci        PRINT_ERR("write_start(%d) >= maxsize(%d)\n", (c->block_size * block + off),
1493d0407baSopenharmony_ci                (c->block_size * c->block_count));
1503d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1513d0407baSopenharmony_ci    }
1523d0407baSopenharmony_ci    if ((c->block_size * block + off + size) > (c->block_size * c->block_count)) {
1533d0407baSopenharmony_ci        PRINT_ERR("write_end(%d) > maxsize(%d)\n", (c->block_size * block + off + size),
1543d0407baSopenharmony_ci                (c->block_size * c->block_count));
1553d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1563d0407baSopenharmony_ci    }
1573d0407baSopenharmony_ci    if (src == NULL) {
1583d0407baSopenharmony_ci        PRINT_ERR("src is null\n");
1593d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1603d0407baSopenharmony_ci    }
1613d0407baSopenharmony_ci
1623d0407baSopenharmony_ci    ret = fs_get_partition(c->context, &partition_offset);
1633d0407baSopenharmony_ci    if (ret != HDF_SUCCESS) {
1643d0407baSopenharmony_ci        PRINT_ERR("c->context(%s) is not support\n", c->context);
1653d0407baSopenharmony_ci        return LFS_ERR_INVAL;
1663d0407baSopenharmony_ci    }
1673d0407baSopenharmony_ci
1683d0407baSopenharmony_ci    block_size = c->block_size;
1693d0407baSopenharmony_ci    addr = ((m_fs_cfg[partition_offset].block_start + block) * block_size) + off;
1703d0407baSopenharmony_ci    block_start = addr / block_size;
1713d0407baSopenharmony_ci    block_end = (addr + size) / block_size;
1723d0407baSopenharmony_ci    if (((addr + size) % block_size) != 0) {
1733d0407baSopenharmony_ci        block_end++;
1743d0407baSopenharmony_ci    }
1753d0407baSopenharmony_ci
1763d0407baSopenharmony_ci    buffer = (unsigned char *)malloc(sizeof(unsigned char) * block_size);
1773d0407baSopenharmony_ci    if (buffer == NULL) {
1783d0407baSopenharmony_ci        PRINT_ERR("malloc failed\n");
1793d0407baSopenharmony_ci        return LFS_ERR_NOMEM;
1803d0407baSopenharmony_ci    }
1813d0407baSopenharmony_ci
1823d0407baSopenharmony_ci    str = (unsigned char *)src;
1833d0407baSopenharmony_ci    str_offset = 0;
1843d0407baSopenharmony_ci
1853d0407baSopenharmony_ci    for (block_offset = block_start; block_offset < block_end; block_offset++) {
1863d0407baSopenharmony_ci        if (block_offset == block_start) {
1873d0407baSopenharmony_ci            /* 开头特殊处理 */
1883d0407baSopenharmony_ci            flash_block_address = block_offset * block_size;
1893d0407baSopenharmony_ci            write_offset = (addr - flash_block_address);
1903d0407baSopenharmony_ci            write_length = block_size - write_offset;
1913d0407baSopenharmony_ci            /* 读取整块数据,擦除整块数据,修改部分数据,最后写入Flash */
1923d0407baSopenharmony_ci            res = FlashRead(flash_block_address, block_size, buffer);
1933d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
1943d0407baSopenharmony_ci                PRINT_ERR("FlashRead(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
1953d0407baSopenharmony_ci                return LFS_ERR_IO;
1963d0407baSopenharmony_ci            }
1973d0407baSopenharmony_ci            res = FlashErase(flash_block_address, block_size);
1983d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
1993d0407baSopenharmony_ci                PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
2003d0407baSopenharmony_ci                return LFS_ERR_IO;
2013d0407baSopenharmony_ci            }
2023d0407baSopenharmony_ci            memcpy_s(&buffer[write_offset], block_size - write_offset,  &src[str_offset], write_length);
2033d0407baSopenharmony_ci            res = FlashWrite(flash_block_address, block_size, buffer, 0);
2043d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2053d0407baSopenharmony_ci                PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
2063d0407baSopenharmony_ci                return LFS_ERR_IO;
2073d0407baSopenharmony_ci            }
2083d0407baSopenharmony_ci            str_offset += write_length;
2093d0407baSopenharmony_ci        } else if (block_offset == (block_end - 1)) {
2103d0407baSopenharmony_ci            /* 结尾特殊处理 */
2113d0407baSopenharmony_ci            flash_block_address = block_offset * block_size;
2123d0407baSopenharmony_ci            write_offset = 0;
2133d0407baSopenharmony_ci            write_length = (addr + size) - flash_block_address;
2143d0407baSopenharmony_ci            /* 读取整块数据,擦除整块数据,修改部分数据,最后写入Flash */
2153d0407baSopenharmony_ci            res = FlashRead(flash_block_address, block_size, buffer);
2163d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2173d0407baSopenharmony_ci                PRINT_ERR("FlashRead(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
2183d0407baSopenharmony_ci                return LFS_ERR_IO;
2193d0407baSopenharmony_ci            }
2203d0407baSopenharmony_ci            res = FlashErase(flash_block_address, block_size);
2213d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2223d0407baSopenharmony_ci                PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
2233d0407baSopenharmony_ci                return LFS_ERR_IO;
2243d0407baSopenharmony_ci            }
2253d0407baSopenharmony_ci            memcpy_s(&buffer[write_offset], block_size - write_offset, &src[str_offset], write_length);
2263d0407baSopenharmony_ci            res = FlashWrite(flash_block_address, block_size, buffer, 0);
2273d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2283d0407baSopenharmony_ci                PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
2293d0407baSopenharmony_ci                return LFS_ERR_IO;
2303d0407baSopenharmony_ci            }
2313d0407baSopenharmony_ci            str_offset += write_length;
2323d0407baSopenharmony_ci        } else {
2333d0407baSopenharmony_ci            /* 中间的部分数据,整块处理 */
2343d0407baSopenharmony_ci            flash_block_address = block_offset * block_size;
2353d0407baSopenharmony_ci            write_offset = 0;
2363d0407baSopenharmony_ci            write_length = block_size;
2373d0407baSopenharmony_ci            /* 读取整块数据,擦除整块数据,最后写入Flash */
2383d0407baSopenharmony_ci            res = FlashErase(flash_block_address, block_size);
2393d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2403d0407baSopenharmony_ci                PRINT_ERR("FlashErase(%d, %d) failed(%u)\n", flash_block_address, block_size, res);
2413d0407baSopenharmony_ci                return LFS_ERR_IO;
2423d0407baSopenharmony_ci            }
2433d0407baSopenharmony_ci            res = FlashWrite(flash_block_address, block_size, &src[str_offset], 0);
2443d0407baSopenharmony_ci            if (res != LZ_HARDWARE_SUCCESS) {
2453d0407baSopenharmony_ci                PRINT_ERR("FlashWrite(%d, %d, buffer) failed(%u)\n", flash_block_address, block_size, res);
2463d0407baSopenharmony_ci                return LFS_ERR_IO;
2473d0407baSopenharmony_ci            }
2483d0407baSopenharmony_ci            str_offset += write_length;
2493d0407baSopenharmony_ci        }
2503d0407baSopenharmony_ci    }
2513d0407baSopenharmony_ci
2523d0407baSopenharmony_ci    if (buffer != NULL) {
2533d0407baSopenharmony_ci        free(buffer);
2543d0407baSopenharmony_ci        buffer = NULL;
2553d0407baSopenharmony_ci    }
2563d0407baSopenharmony_ci
2573d0407baSopenharmony_ci    return LFS_ERR_OK;
2583d0407baSopenharmony_ci}
2593d0407baSopenharmony_ci
2603d0407baSopenharmony_cistatic int32_t fs_erase(const struct lfs_config *c, lfs_block_t block)
2613d0407baSopenharmony_ci{
2623d0407baSopenharmony_ci    int32_t ret;
2633d0407baSopenharmony_ci    struct fs_cfg *fs;
2643d0407baSopenharmony_ci    uint32_t addr;
2653d0407baSopenharmony_ci    uint32_t partition_offset;
2663d0407baSopenharmony_ci
2673d0407baSopenharmony_ci    if (c == NULL) {
2683d0407baSopenharmony_ci        PRINT_ERR("c is null\n");
2693d0407baSopenharmony_ci        return LFS_ERR_INVAL;
2703d0407baSopenharmony_ci    }
2713d0407baSopenharmony_ci    if (block >= c->block_count) {
2723d0407baSopenharmony_ci        PRINT_ERR("block(%d) >= block_count(%d)\n", block, c->block_count);
2733d0407baSopenharmony_ci        return LFS_ERR_INVAL;
2743d0407baSopenharmony_ci    }
2753d0407baSopenharmony_ci
2763d0407baSopenharmony_ci    ret = fs_get_partition(c->context, &partition_offset);
2773d0407baSopenharmony_ci    if (ret != HDF_SUCCESS) {
2783d0407baSopenharmony_ci        PRINT_ERR("c->context(%s) is not support\n", c->context);
2793d0407baSopenharmony_ci        return LFS_ERR_INVAL;
2803d0407baSopenharmony_ci    }
2813d0407baSopenharmony_ci
2823d0407baSopenharmony_ci    fs = &m_fs_cfg[partition_offset];
2833d0407baSopenharmony_ci    addr = ((fs->block_start + block) * c->block_size);
2843d0407baSopenharmony_ci    FlashErase(addr, c->block_size);
2853d0407baSopenharmony_ci
2863d0407baSopenharmony_ci    return LFS_ERR_OK;
2873d0407baSopenharmony_ci}
2883d0407baSopenharmony_ci
2893d0407baSopenharmony_cistatic int32_t fs_sync(const struct lfs_config *c)
2903d0407baSopenharmony_ci{
2913d0407baSopenharmony_ci    return LFS_ERR_OK;
2923d0407baSopenharmony_ci}
2933d0407baSopenharmony_ci
2943d0407baSopenharmony_cistatic uint32_t fsdrv_readdrs(const struct DeviceResourceNode *node, struct fs_cfg *fs)
2953d0407baSopenharmony_ci{
2963d0407baSopenharmony_ci    int32_t ret;
2973d0407baSopenharmony_ci    struct DeviceResourceIface *iface = NULL;
2983d0407baSopenharmony_ci    int32_t num = 0;
2993d0407baSopenharmony_ci    uint32_t block_size = FlashGetBlockSize();
3003d0407baSopenharmony_ci    uint32_t address_start, address_end;
3013d0407baSopenharmony_ci
3023d0407baSopenharmony_ci    if (node == NULL) {
3033d0407baSopenharmony_ci        PRINT_ERR("node is null\n");
3043d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3053d0407baSopenharmony_ci    }
3063d0407baSopenharmony_ci    if (fs == NULL) {
3073d0407baSopenharmony_ci        PRINT_ERR("fs  is null\n");
3083d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3093d0407baSopenharmony_ci    }
3103d0407baSopenharmony_ci
3113d0407baSopenharmony_ci    iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
3123d0407baSopenharmony_ci    if (iface == NULL) {
3133d0407baSopenharmony_ci        PRINT_ERR("iface is null\n");
3143d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3153d0407baSopenharmony_ci    }
3163d0407baSopenharmony_ci    if (iface->GetElemNum == NULL) {
3173d0407baSopenharmony_ci        PRINT_ERR("GetElemNum is null\n");
3183d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3193d0407baSopenharmony_ci    }
3203d0407baSopenharmony_ci    if (iface->GetStringArrayElem == NULL) {
3213d0407baSopenharmony_ci        PRINT_ERR("GetStringArrayElem is null\n");
3223d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3233d0407baSopenharmony_ci    }
3243d0407baSopenharmony_ci    if (iface->GetUint32ArrayElem == NULL) {
3253d0407baSopenharmony_ci        PRINT_ERR("GetStringArrayElem is null\n");
3263d0407baSopenharmony_ci        return HDF_ERR_INVALID_PARAM;
3273d0407baSopenharmony_ci    }
3283d0407baSopenharmony_ci
3293d0407baSopenharmony_ci    num = iface->GetElemNum(node, "mount_points");
3303d0407baSopenharmony_ci    if (num < 0 || num > LOSCFG_LFS_MAX_MOUNT_SIZE) {
3313d0407baSopenharmony_ci        PRINT_ERR("invalid mount_points num %d", num);
3323d0407baSopenharmony_ci        return HDF_FAILURE;
3333d0407baSopenharmony_ci    }
3343d0407baSopenharmony_ci
3353d0407baSopenharmony_ci    for (int32_t i = 0; i < num; i++) {
3363d0407baSopenharmony_ci        ret = iface->GetStringArrayElem(node, "mount_points", i, &fs[i].mount_point, NULL);
3373d0407baSopenharmony_ci        if (ret != HDF_SUCCESS) {
3383d0407baSopenharmony_ci            PRINT_ERR("failed to get mount_points");
3393d0407baSopenharmony_ci            return HDF_FAILURE;
3403d0407baSopenharmony_ci        }
3413d0407baSopenharmony_ci
3423d0407baSopenharmony_ci        fs[i].lfs_cfg.context = (void *)fs[i].mount_point;
3433d0407baSopenharmony_ci
3443d0407baSopenharmony_ci        ret = iface->GetUint32ArrayElem(node, "block_size", i, &fs[i].lfs_cfg.block_size, NULL);
3453d0407baSopenharmony_ci        if (ret != HDF_SUCCESS) {
3463d0407baSopenharmony_ci            PRINT_ERR("failed to get block_size");
3473d0407baSopenharmony_ci            return HDF_FAILURE;
3483d0407baSopenharmony_ci        }
3493d0407baSopenharmony_ci
3503d0407baSopenharmony_ci        ret = iface->GetUint32ArrayElem(node, "block_count", i, &fs[i].lfs_cfg.block_count, NULL);
3513d0407baSopenharmony_ci        if (ret != HDF_SUCCESS) {
3523d0407baSopenharmony_ci            PRINT_ERR("failed to get block_count");
3533d0407baSopenharmony_ci            return HDF_FAILURE;
3543d0407baSopenharmony_ci        }
3553d0407baSopenharmony_ci
3563d0407baSopenharmony_ci        ret = iface->GetUint32ArrayElem(node, "block_start", i, &fs[i].block_start, NULL);
3573d0407baSopenharmony_ci        if (ret != HDF_SUCCESS) {
3583d0407baSopenharmony_ci            PRINT_ERR("failed to get block_start");
3593d0407baSopenharmony_ci            return HDF_FAILURE;
3603d0407baSopenharmony_ci        }
3613d0407baSopenharmony_ci    }
3623d0407baSopenharmony_ci
3633d0407baSopenharmony_ci    /* 检查相关参数是否正确 */
3643d0407baSopenharmony_ci    for (int32_t i = 0; i < num; i++) {
3653d0407baSopenharmony_ci        if (fs[i].mount_point == NULL) {
3663d0407baSopenharmony_ci            break;
3673d0407baSopenharmony_ci        }
3683d0407baSopenharmony_ci
3693d0407baSopenharmony_ci        PRINT_LOG("fs[%d]:\n", i);
3703d0407baSopenharmony_ci        PRINT_LOG("     mount_points = %s\n", fs[i].mount_point);
3713d0407baSopenharmony_ci        PRINT_LOG("     context = %s\n", (char *)fs[i].lfs_cfg.context);
3723d0407baSopenharmony_ci        PRINT_LOG("     block_size = %d\n", fs[i].lfs_cfg.block_size);
3733d0407baSopenharmony_ci        PRINT_LOG("     block_count = %d\n", fs[i].lfs_cfg.block_count);
3743d0407baSopenharmony_ci        PRINT_LOG("     block_start = %d\n", fs[i].block_start);
3753d0407baSopenharmony_ci
3763d0407baSopenharmony_ci        /* 检查 */
3773d0407baSopenharmony_ci        if (fs[i].lfs_cfg.block_size != block_size) {
3783d0407baSopenharmony_ci            PRINT_ERR("littefs[%d].lfs_cfg.block_size(%d) != flash_block_size(%d)\n",
3793d0407baSopenharmony_ci                    i, fs[i].lfs_cfg.block_size, block_size);
3803d0407baSopenharmony_ci            return HDF_ERR_INVALID_PARAM;
3813d0407baSopenharmony_ci        }
3823d0407baSopenharmony_ci
3833d0407baSopenharmony_ci        address_start = (uint32_t)(fs[i].block_start * fs[i].lfs_cfg.block_size);
3843d0407baSopenharmony_ci        if (address_start < FLASH_ADDRESS_USER_START) {
3853d0407baSopenharmony_ci            PRINT_ERR("partition[%d].address_start(%d) < FLASH_ADDRESS_USER_START(%d)\n",
3863d0407baSopenharmony_ci                i, address_start, FLASH_ADDRESS_USER_START);
3873d0407baSopenharmony_ci            return HDF_FAILURE;
3883d0407baSopenharmony_ci        }
3893d0407baSopenharmony_ci
3903d0407baSopenharmony_ci        address_end = (uint32_t)((fs[i].block_start + fs[i].lfs_cfg.block_count) * fs[i].lfs_cfg.block_size);
3913d0407baSopenharmony_ci        if (address_end > FLASH_ADDRESS_USER_END) {
3923d0407baSopenharmony_ci            PRINT_ERR("partition[%d].address_end(%d) < FLASH_ADDRESS_USER_END(%d)\n",
3933d0407baSopenharmony_ci                i, address_end, FLASH_ADDRESS_USER_END);
3943d0407baSopenharmony_ci            return HDF_FAILURE;
3953d0407baSopenharmony_ci        }
3963d0407baSopenharmony_ci    }
3973d0407baSopenharmony_ci
3983d0407baSopenharmony_ci    return HDF_SUCCESS;
3993d0407baSopenharmony_ci}
4003d0407baSopenharmony_ci
4013d0407baSopenharmony_cistatic int32_t fsdrv_init(struct HdfDeviceObject *device)
4023d0407baSopenharmony_ci{
4033d0407baSopenharmony_ci    int result;
4043d0407baSopenharmony_ci    int32_t ret;
4053d0407baSopenharmony_ci    struct FileOpInfo *file_op_info = NULL;
4063d0407baSopenharmony_ci
4073d0407baSopenharmony_ci    if (device == NULL) {
4083d0407baSopenharmony_ci        PRINT_ERR("device is null\n");
4093d0407baSopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
4103d0407baSopenharmony_ci    }
4113d0407baSopenharmony_ci    if (device->property == NULL) {
4123d0407baSopenharmony_ci        PRINT_ERR("device is null\n");
4133d0407baSopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
4143d0407baSopenharmony_ci    }
4153d0407baSopenharmony_ci
4163d0407baSopenharmony_ci    /* Flash设备初始化 */
4173d0407baSopenharmony_ci    FlashInit();
4183d0407baSopenharmony_ci
4193d0407baSopenharmony_ci    ret = fsdrv_readdrs(device->property, &m_fs_cfg[0]);
4203d0407baSopenharmony_ci    if (ret != HDF_SUCCESS) {
4213d0407baSopenharmony_ci        PRINT_ERR("%s: fsdrv_readdrs failed(%d)\n", __func__, ret);
4223d0407baSopenharmony_ci        return ret;
4233d0407baSopenharmony_ci    }
4243d0407baSopenharmony_ci
4253d0407baSopenharmony_ci    for (int i = 0; i < sizeof(m_fs_cfg) / sizeof(m_fs_cfg[0]); i++) {
4263d0407baSopenharmony_ci        if (m_fs_cfg[i].mount_point == NULL) {
4273d0407baSopenharmony_ci            PRINT_LOG("m_fs_cfg[%d].mount_point is null\n", i);
4283d0407baSopenharmony_ci            continue;
4293d0407baSopenharmony_ci        }
4303d0407baSopenharmony_ci
4313d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.read = fs_read;
4323d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.prog = fs_write;
4333d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.erase = fs_erase;
4343d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.sync = fs_sync;
4353d0407baSopenharmony_ci
4363d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.read_size = LFSCFG_READSIZE_MAX;
4373d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.prog_size = LFSCFG_PROGSIZE_MAX;
4383d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.cache_size = LFSCFG_CACHESIZE_MAX;
4393d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.lookahead_size = LFSCFG_LOCKAHEADSIZE_MAX;
4403d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.block_cycles = LFSCFG_BLOCKCYCLES_MAX;
4413d0407baSopenharmony_ci
4423d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.file_max = LFS_FILE_MAX;
4433d0407baSopenharmony_ci        m_fs_cfg[i].lfs_cfg.name_max = LFS_NAME_MAX;
4443d0407baSopenharmony_ci
4453d0407baSopenharmony_ci        result = mount(NULL, m_fs_cfg[i].mount_point, "littlefs", 0, &m_fs_cfg[i].lfs_cfg);
4463d0407baSopenharmony_ci        printf("%s: mount fs on '%s' %s\n", __func__, m_fs_cfg[i].mount_point, (result == 0) ? "succeed" : "failed");
4473d0407baSopenharmony_ci        if (ret == 0) {
4483d0407baSopenharmony_ci            ret = mkdir(m_fs_cfg[i].mount_point, S_IRWXU | S_IRWXG | S_IRWXO);
4493d0407baSopenharmony_ci            if (ret == 0) {
4503d0407baSopenharmony_ci                PRINT_LOG("create root dir(%s) success.\n", m_fs_cfg[i].mount_point);
4513d0407baSopenharmony_ci            } else if (errno == EEXIST) {
4523d0407baSopenharmony_ci                PRINT_LOG("root dir(%s) exist.\n", m_fs_cfg[i].mount_point);
4533d0407baSopenharmony_ci            } else {
4543d0407baSopenharmony_ci                PRINT_LOG("create root dir(%s) failed.", m_fs_cfg[i].mount_point);
4553d0407baSopenharmony_ci            }
4563d0407baSopenharmony_ci        }
4573d0407baSopenharmony_ci    }
4583d0407baSopenharmony_ci
4593d0407baSopenharmony_ci    PRINT_LOG("LittleFS service: %s init success!\n", HdfDeviceGetServiceName(device));
4603d0407baSopenharmony_ci    return HDF_SUCCESS;
4613d0407baSopenharmony_ci}
4623d0407baSopenharmony_ci
4633d0407baSopenharmony_cistatic int32_t fsdrv_bind(struct HdfDeviceObject *device)
4643d0407baSopenharmony_ci{
4653d0407baSopenharmony_ci    (void)device;
4663d0407baSopenharmony_ci    return HDF_SUCCESS;
4673d0407baSopenharmony_ci}
4683d0407baSopenharmony_ci
4693d0407baSopenharmony_cistatic void fsdrv_release(struct HdfDeviceObject *device)
4703d0407baSopenharmony_ci{
4713d0407baSopenharmony_ci    (void)device;
4723d0407baSopenharmony_ci    PRINT_LOG("LittleFS service: %s release\n", HdfDeviceGetServiceName(device));
4733d0407baSopenharmony_ci}
4743d0407baSopenharmony_ci
4753d0407baSopenharmony_cistatic struct HdfDriverEntry g_fsDriverEntry = {
4763d0407baSopenharmony_ci    .moduleVersion = 1,
4773d0407baSopenharmony_ci    .moduleName = "HDF_PLATFORM_FS_LITTLEFS",
4783d0407baSopenharmony_ci    .Bind = fsdrv_bind,
4793d0407baSopenharmony_ci    .Init = fsdrv_init,
4803d0407baSopenharmony_ci    .Release = fsdrv_release,
4813d0407baSopenharmony_ci};
4823d0407baSopenharmony_ci
4833d0407baSopenharmony_ciHDF_INIT(g_fsDriverEntry);
484