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:
parent
8b19c3cbe4
commit
f2c4b59773
|
@ -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)
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue