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