feat: liteos-m文件系统初始化函数支持littlefs

VFS初始化函数LOS_DiskPartition及LfsFormat支持littlefs,支持对flash设备进行分区和格式化操作
1,VFS层记录Fat/littlefs设备名称、分区等信息,后续在本层做处理
2,flash设备的相关配置及驱动操作接口通过LOS_DiskPartition配置,产品不用直接面向具体文件系统

close: #I5CYKI

Signed-off-by: leonchan5 <chenwei26@huawei.com>
This commit is contained in:
leonchan5 2022-08-10 16:05:36 +08:00
parent 8b19c3cbe4
commit f2c4b59773
5 changed files with 235 additions and 17 deletions

View File

@ -32,6 +32,7 @@
#define _GNU_SOURCE 1
#include "lfs_adapter.h"
#include "los_config.h"
#include "los_fs.h"
#include "vfs_files.h"
#include "vfs_operations.h"
#include "vfs_partition.h"
@ -39,8 +40,76 @@
#include "vfs_mount.h"
#include "securec.h"
struct dirent g_nameValue;
static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_fsLocalMutex = PTHREAD_MUTEX_INITIALIZER;
static struct PartitionCfg g_partitionCfg;
static struct lfs_config g_lfsCfg;
static struct DeviceDesc *g_lfsDevice = NULL;
static uint32_t LfsGetStartAddr(int partition)
{
if (g_lfsDevice == NULL) {
struct DeviceDesc *device = NULL;
for (device = getDeviceList(); device != NULL; device = device->dNext) {
if (strcmp(device->dFsType, "littlefs") == 0) {
g_lfsDevice = device;
break;
}
}
}
if ((g_lfsDevice == NULL) || (partition >= g_lfsDevice->dPartNum)) {
return INVALID_DEVICE_ADDR;
}
return g_lfsDevice->dAddrArray[partition];
}
WEAK int littlefs_block_read(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *dst, lfs_size_t size)
{
UINT32 addr = c->block_size * block + off;
UINT32 startaddr = LfsGetStartAddr((int)c->context);
if (startaddr == INVALID_DEVICE_ADDR) {
return -1;
}
addr += startaddr;
return (g_partitionCfg.readFunc)((int)c->context, &addr, dst, size);
}
WEAK int littlefs_block_write(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *dst, lfs_size_t size)
{
UINT32 addr = c->block_size * block + off;
UINT32 startaddr = LfsGetStartAddr((int)c->context);
if (startaddr == INVALID_DEVICE_ADDR) {
return -1;
}
addr += startaddr;
return (g_partitionCfg.writeFunc)((int)c->context, &addr, dst, size);
}
WEAK int littlefs_block_erase(const struct lfs_config *c, lfs_block_t block)
{
UINT32 addr = c->block_size * block;
UINT32 startaddr = LfsGetStartAddr((int)c->context);
if (startaddr == INVALID_DEVICE_ADDR) {
return -1;
}
addr += startaddr;
return (g_partitionCfg.eraseFunc)((int)c->context, addr, c->block_size);
}
WEAK int littlefs_block_sync(const struct lfs_config *c)
{
(void)c;
return 0;
}
static int ConvertFlagToLfsOpenFlag (int oflags)
{
@ -82,6 +151,28 @@ static int LittlefsErrno(int result)
return (result < 0) ? -result : result;
}
void LfsConfigAdapter(struct PartitionCfg *pCfg, struct lfs_config *lfsCfg)
{
lfsCfg->context = (void *)pCfg->partNo;
lfsCfg->read_size = pCfg->readSize;
lfsCfg->prog_size = pCfg->writeSize;
lfsCfg->cache_size = pCfg->cacheSize;
lfsCfg->block_cycles = pCfg->blockCycles;
lfsCfg->lookahead_size = pCfg->lookaheadSize;
lfsCfg->block_size = pCfg->blockSize;
lfsCfg->block_count = pCfg->blockCount;
lfsCfg->read = littlefs_block_read;
lfsCfg->prog = littlefs_block_write;
lfsCfg->erase = littlefs_block_erase;
lfsCfg->sync = littlefs_block_sync;
g_partitionCfg.readFunc = pCfg->readFunc;
g_partitionCfg.writeFunc = pCfg->writeFunc;
g_partitionCfg.eraseFunc = pCfg->eraseFunc;
}
int LfsMount(struct MountPoint *mp, unsigned long mountflags, const void *data)
{
int ret;
@ -102,14 +193,15 @@ int LfsMount(struct MountPoint *mp, unsigned long mountflags, const void *data)
(void)memset_s(mountHdl, sizeof(lfs_t), 0, sizeof(lfs_t));
mp->mData = (void *)mountHdl;
ret = lfs_mount((lfs_t *)mp->mData, (struct lfs_config *)data);
LfsConfigAdapter((struct PartitionCfg *)data, &g_lfsCfg);
ret = lfs_mount((lfs_t *)mp->mData, &g_lfsCfg);
if (ret != 0) {
ret = lfs_format((lfs_t *)mp->mData, (struct lfs_config*)data);
ret = lfs_format((lfs_t *)mp->mData, &g_lfsCfg);
if (ret == 0) {
ret = lfs_mount((lfs_t *)mp->mData, (struct lfs_config*)data);
ret = lfs_mount((lfs_t *)mp->mData, &g_lfsCfg);
}
}
if (ret != 0) {
free(mountHdl);
errno = LittlefsErrno(ret);
@ -278,7 +370,7 @@ int LfsReaddir(struct Dir *dir, struct dirent *dent)
ret = lfs_dir_read(lfs, dirInfo, &lfsInfo);
if (ret == TRUE) {
pthread_mutex_lock(&g_FslocalMutex);
pthread_mutex_lock(&g_fsLocalMutex);
(void)strncpy_s(dent->d_name, sizeof(dent->d_name), lfsInfo.name, strlen(lfsInfo.name) + 1);
if (lfsInfo.type == LFS_TYPE_DIR) {
dent->d_type = DT_DIR;
@ -287,7 +379,7 @@ int LfsReaddir(struct Dir *dir, struct dirent *dent)
}
dent->d_reclen = lfsInfo.size;
pthread_mutex_unlock(&g_FslocalMutex);
pthread_mutex_unlock(&g_fsLocalMutex);
return LOS_OK;
}
@ -467,9 +559,9 @@ int LfsClose(struct File *file)
return (int)LOS_NOK;
}
pthread_mutex_lock(&g_FslocalMutex);
pthread_mutex_lock(&g_fsLocalMutex);
ret = lfs_file_close((lfs_t *)mp->mData, lfsHandle);
pthread_mutex_unlock(&g_FslocalMutex);
pthread_mutex_unlock(&g_fsLocalMutex);
if (ret != 0) {
errno = LittlefsErrno(ret);
@ -559,6 +651,23 @@ int LfsSync(struct File *file)
return ret;
}
int LfsFormat(const char *partName, void *privData)
{
int ret;
lfs_t lfs = {0};
(void)partName;
LfsConfigAdapter((struct PartitionCfg *)privData, &g_lfsCfg);
ret = lfs_format(&lfs, &g_lfsCfg);
if (ret != 0) {
errno = LittlefsErrno(ret);
ret = LOS_NOK;
}
return ret;
}
static struct MountOps g_lfsMnt = {
.mount = LfsMount,
.umount = LfsUmount,
@ -587,7 +696,7 @@ static struct FileOps g_lfsFops = {
static struct FsManagement g_lfsMgt = {
.fdisk = NULL,
.format = NULL,
.format = LfsFormat,
};
void LfsInit(void)

View File

@ -45,6 +45,6 @@
#include "pthread.h"
#define INVALID_FD (-1)
#define INVALID_DEVICE_ADDR ((uint32_t)-1)
void LfsInit(void);
#endif /* _LFS_ADAPTER_H_ */

View File

@ -82,6 +82,26 @@ int LOS_FsUmount2(const char *target, int flag);
int LOS_FsMount(const char *source, const char *target,
const char *fsType, unsigned long mountflags,
const void *data);
struct PartitionCfg {
/* partition low-level read func */
int (*readFunc)(int partition, UINT32 *offset, void *buf, UINT32 size);
/* partition low-level write func */
int (*writeFunc)(int partition, UINT32 *offset, const void *buf, UINT32 size);
/* partition low-level erase func */
int (*eraseFunc)(int partition, UINT32 offset, UINT32 size);
int readSize; /* size of a block read */
int writeSize; /* size of a block write */
int blockSize; /* size of an erasable block */
int blockCount; /* number of partition blocks */
int cacheSize; /* size of block caches */
int partNo; /* partition number */
int lookaheadSize; /* lookahead size */
int blockCycles; /* block cycles */
};
/*
* @brief Divide the device into partitions.
*
@ -93,6 +113,7 @@ int LOS_FsMount(const char *source, const char *target,
* @param lengthArray List of partition size. For example:
* [0x10000000, 0x2000000], 256M and 512M partitions will be created and
* left all will not allocated.
* @param addrArray List of partition start addr, partition num same as lengthArray
* @param partNum Length of 'lengthArray'.
*
* @return Return LOS_NOK if error. Return LOS_OK if success.
@ -103,8 +124,8 @@ int LOS_FsMount(const char *source, const char *target,
* The name is a combination of: 'deviceName'+'p'+'partitionId',
* such as "emmc0p0", "emmc0p1", "emmc0p2"...
*/
int LOS_DiskPartition(const char *dev, const char *fsType, int *lengthArray,
int partnum);
int LOS_DiskPartition(const char *dev, const char *fsType, int *lengthArray, int *addrArray,
int partNum);
/*
* @brief Format a partition.

View File

@ -37,6 +37,8 @@
#include "stdlib.h"
#include "string.h"
static struct DeviceDesc *g_deviceList = NULL;
int GetPartIdByPartName(const char *partName)
{
if (partName == NULL) {
@ -67,16 +69,86 @@ int GetDevIdByDevName(const char *dev)
return (int)LOS_NOK;
}
int LOS_DiskPartition(const char *dev, const char *fsType, int *lengthArray,
int partnum)
struct DeviceDesc *getDeviceList(VOID)
{
return g_deviceList;
}
static int AddDevice(const char *dev, const char *fsType, int *lengthArray, int *addrArray,
int partNum)
{
struct DeviceDesc *prev = NULL;
for (prev = g_deviceList; prev != NULL; prev = prev->dNext) {
if (strcmp(prev->dDev, dev) == 0) {
errno = -EEXIST;
return LOS_NOK;
}
}
if (addrArray == NULL) {
errno = -EFAULT;
return LOS_NOK;
}
prev = (struct DeviceDesc *)malloc(sizeof(struct DeviceDesc));
if (prev == NULL) {
errno = -ENOMEM;
return LOS_NOK;
}
prev->dDev = strdup(dev);
prev->dFsType = strdup(fsType);
prev->dAddrArray = (int *)malloc(partNum * sizeof(int));
if (prev->dDev == NULL || prev->dFsType == NULL || prev->dAddrArray == NULL) {
goto errout;
}
(void)memcpy_s(prev->dAddrArray, partNum * sizeof(int), addrArray, partNum * sizeof(int));
if (lengthArray != NULL) {
prev->dLengthArray = (int *)malloc(partNum * sizeof(int));
if (prev->dLengthArray == NULL) {
goto errout;
}
(void)memcpy_s(prev->dLengthArray, partNum * sizeof(int), lengthArray, partNum * sizeof(int));
}
prev->dNext = g_deviceList;
prev->dPartNum = partNum;
g_deviceList = prev;
return LOS_OK;
errout:
if (prev->dDev != NULL) {
free((void *)prev->dDev);
}
if (prev->dFsType != NULL) {
free((void *)prev->dFsType);
}
if (prev->dAddrArray != NULL) {
free((void *)prev->dAddrArray);
}
if (prev->dLengthArray != NULL) {
free((void *)prev->dLengthArray);
}
free(prev);
errno = -ENOMEM;
return LOS_NOK;
}
int LOS_DiskPartition(const char *dev, const char *fsType, int *lengthArray, int *addrArray,
int partNum)
{
int ret = (int)LOS_NOK;
struct FsMap *fMap = VfsFsMapGet(fsType);
if ((fMap != NULL) && (fMap->fsMgt != NULL) &&
(fMap->fsMgt->fdisk != NULL)) {
ret = fMap->fsMgt->fdisk(dev, lengthArray, partnum);
ret = fMap->fsMgt->fdisk(dev, lengthArray, partNum);
if (ret == LOS_NOK) {
return ret;
}
}
ret = AddDevice(dev, fsType, lengthArray, addrArray, partNum);
return ret;
}
@ -100,5 +172,6 @@ int LOS_PartitionFormat(const char *partName, char *fsType, void *data)
(fMap->fsMgt->format != NULL)) {
ret = fMap->fsMgt->format(partName, data);
}
return ret;
}

View File

@ -31,6 +31,8 @@
#ifndef _VFS_PARTITION_H_
#define _VFS_PARTITION_H_
#include "los_compiler.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@ -41,6 +43,19 @@ extern "C" {
int GetPartIdByPartName(const char *partName);
int GetDevIdByDevName(const char *dev);
struct DeviceDesc *getDeviceList(void);
struct DeviceDesc {
struct FsMap *dFs; /* file system info */
struct DeviceDesc *dNext; /* point to next mount point */
const char *dPath; /* target path, /system, /usr, etc. */
const char *dDev; /* device, "emmc0p0", "emmc0p1", etc. */
void *dData; /* specific file system handle */
const char *dFsType; /* file system type */
int *dLengthArray; /* point to device partitions length array */
int *dAddrArray; /* point to device partitions address array */
int dPartNum; /* number of device partitions */
};
#ifdef __cplusplus
#if __cplusplus