鸿蒙轻内核M核源码分析系列二一 02 文件系统LittleFS

1、LFS文件系统结构体介绍

会分2部分来介绍结构体部分,先介绍LittleFS文件系统的结构体,然后介绍LiteOS-M内核中提供的和LittleFS相关的一些结构体。

1.1 LittleFS的枚举结构体

在openharmony/third_party/littlefs/lfs.h头文件中定义LittleFS的枚举、结构体,我们先简单了解下,后文会使用到的。

枚举lfs_type定义文件类型,了解下普通文件LFS_TYPE_REG和目录LFS_TYPE_DIR即可。枚举lfs_open_flags定义文件系统的打开标签属性信息,需要熟悉常用的只读LFS_O_RDONLY、只写LFS_O_WRONLY、读写LFS_O_RDWR等等。

// File types
enum lfs_type {// file typesLFS_TYPE_REG            = 0x001,LFS_TYPE_DIR            = 0x002,// internally used typesLFS_TYPE_SPLICE         = 0x400,LFS_TYPE_NAME           = 0x000,LFS_TYPE_STRUCT         = 0x200,LFS_TYPE_USERATTR       = 0x300,LFS_TYPE_FROM           = 0x100,LFS_TYPE_TAIL           = 0x600,LFS_TYPE_GLOBALS        = 0x700,LFS_TYPE_CRC            = 0x500,// internally used type specializationsLFS_TYPE_CREATE         = 0x401,LFS_TYPE_DELETE         = 0x4ff,LFS_TYPE_SUPERBLOCK     = 0x0ff,LFS_TYPE_DIRSTRUCT      = 0x200,LFS_TYPE_CTZSTRUCT      = 0x202,LFS_TYPE_INLINESTRUCT   = 0x201,LFS_TYPE_SOFTTAIL       = 0x600,LFS_TYPE_HARDTAIL       = 0x601,LFS_TYPE_MOVESTATE      = 0x7ff,// internal chip sourcesLFS_FROM_NOOP           = 0x000,LFS_FROM_MOVE           = 0x101,LFS_FROM_USERATTRS      = 0x102,
};// File open flags
enum lfs_open_flags {// open flagsLFS_O_RDONLY = 1,         // Open a file as read only
#ifndef LFS_READONLYLFS_O_WRONLY = 2,         // Open a file as write onlyLFS_O_RDWR   = 3,         // Open a file as read and writeLFS_O_CREAT  = 0x0100,    // Create a file if it does not existLFS_O_EXCL   = 0x0200,    // Fail if a file already existsLFS_O_TRUNC  = 0x0400,    // Truncate the existing file to zero sizeLFS_O_APPEND = 0x0800,    // Move to end of file on every write
#endif// internally used flags
#ifndef LFS_READONLYLFS_F_DIRTY   = 0x010000, // File does not match storageLFS_F_WRITING = 0x020000, // File has been written since last flush
#endifLFS_F_READING = 0x040000, // File has been read since last flush
#ifndef LFS_READONLYLFS_F_ERRED   = 0x080000, // An error occurred during write
#endifLFS_F_INLINE  = 0x100000, // Currently inlined in directory entry
};

结构体lfs_t是littlefs文件系统类型结构体,lfs文件系统操作接口的第一个参数一般为这个结构体。成员变量struct lfs_config *cfg下文会涉及,其他成员变量可以暂不了解。

// The littlefs filesystem type
typedef struct lfs {lfs_cache_t rcache;lfs_cache_t pcache;lfs_block_t root[2];struct lfs_mlist {struct lfs_mlist *next;uint16_t id;uint8_t type;lfs_mdir_t m;} *mlist;uint32_t seed;lfs_gstate_t gstate;lfs_gstate_t gdisk;lfs_gstate_t gdelta;struct lfs_free {lfs_block_t off;lfs_block_t size;lfs_block_t i;lfs_block_t ack;uint32_t *buffer;} free;const struct lfs_config *cfg;lfs_size_t name_max;lfs_size_t file_max;lfs_size_t attr_max;#ifdef LFS_MIGRATEstruct lfs1 *lfs1;
#endif
} lfs_t;

结构体lfs_file_t、lfs_dir_t分别是littlefs的文件和目录类型结构体,暂不需要关心成员变量细节,知道结构体的用途即可。

// littlefs directory type
typedef struct lfs_dir {struct lfs_dir *next;uint16_t id;uint8_t type;lfs_mdir_t m;lfs_off_t pos;lfs_block_t head[2];
} lfs_dir_t;// littlefs file type
typedef struct lfs_file {struct lfs_file *next;uint16_t id;uint8_t type;lfs_mdir_t m;struct lfs_ctz {lfs_block_t head;lfs_size_t size;} ctz;uint32_t flags;lfs_off_t pos;lfs_block_t block;lfs_off_t off;lfs_cache_t cache;const struct lfs_file_config *cfg;
} lfs_file_t;

结构体lfs_config用于提供初始化littlefs文件系统的一些配置。其中.read,.prog,.erase,.sync分别对应该硬件平台上的底层的读写\擦除\同步等接口。

  • read_size 每次读取的字节数,可以比物理读单元大以改善性能,这个数值决定了读缓存的大小,但值太大会带来更多的内存消耗。

  • prog_size 每次写入的字节数,可以比物理写单元大以改善性能,这个数值决定了写缓存的大小,必须是read_size的整数倍,但值太大会带来更多的内存消耗。

  • block_size 每个擦除块的字节数,可以比物理擦除单元大,但此数值应尽可能小因为每个文件至少会占用一个块。必须是prog_size的整数倍。

  • block_count 可以被擦除的块数量,这取决于块设备的容量及擦除块的大小。

// Configuration provided during initialization of the littlefs
struct lfs_config {// Opaque user provided context that can be used to pass// information to the block device operationsvoid *context;int (*read)(const struct lfs_config *c, lfs_block_t block,lfs_off_t off, void *buffer, lfs_size_t size);int (*prog)(const struct lfs_config *c, lfs_block_t block,lfs_off_t off, const void *buffer, lfs_size_t size);int (*erase)(const struct lfs_config *c, lfs_block_t block);int (*sync)(const struct lfs_config *c);#ifdef LFS_THREADSAFEint (*lock)(const struct lfs_config *c);int (*unlock)(const struct lfs_config *c);
#endiflfs_size_t read_size;lfs_size_t prog_size;lfs_size_t block_size;lfs_size_t block_count;int32_t block_cycles;lfs_size_t cache_size;lfs_size_t lookahead_size;void *read_buffer;void *prog_buffer;void *lookahead_buffer;lfs_size_t name_max;lfs_size_t file_max;lfs_size_t attr_max;lfs_size_t metadata_max;
};

结构体lfs_info用于维护文件信息,包含文件类型,大小和文件名信息。

// File info structure
struct lfs_info {// Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIRuint8_t type;// Size of the file, only valid for REG files. Limited to 32-bits.lfs_size_t size;// Name of the file stored as a null-terminated string. Limited to// LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to// reduce RAM. LFS_NAME_MAX is stored in superblock and must be// respected by other littlefs drivers.char name[LFS_NAME_MAX+1];
};

1.2 LiteOS-M LittleFS的结构体

我们来看下在文件components\fs\littlefs\lfs_api.h里定义的几个结构体。结构体LittleFsHandleStruct维护文件相关的信息,该结构体的成员包含是否使用,文件路径和lfs文件系统类型结构体lfs_t *lfsHandle和文件类型结构体lfs_file_t file。类似的,结构体FileDirInfo维护目录相关的信息,该结构体成员包含包含是否使用,目录名称和lfs文件系统类型结构体lfs_t *lfsHandle和目录类型结构体lfs_dir_t dir。另外一个结构体FileOpInfo维护文件操作信息。

typedef struct {uint8_t useFlag;const char *pathName;lfs_t *lfsHandle;lfs_file_t file;
} LittleFsHandleStruct;struct FileOpInfo {uint8_t useFlag;const struct FileOps *fsVops;char *dirName;lfs_t lfsInfo;
};typedef struct {uint8_t useFlag;char *dirName;lfs_t *lfsHandle;lfs_dir_t dir;
} FileDirInfo;

2、LiteOS-M LittleFS的重要全局变量及操作

了解下文件components\fs\littlefs\lfs_api.c定义的常用全局变量。⑴处的g_lfsDir数组维护目录信息,默认支持的目录数目为LFS_MAX_OPEN_DIRS,等于10。⑵处的g_fsOp数组维护针对每个挂载点的文件操作信息,默认挂载点数目LOSCFG_LFS_MAX_MOUNT_SIZE为3个。⑶处的g_handle数组维护文件信息,默认支持文件的数量LITTLE_FS_MAX_OPEN_FILES为100个。⑷处开始的struct dirent g_nameValue是目录项结构体变量,用于函数LfsReaddir();pthread_mutex_t g_FslocalMutex是互斥锁变量;g_littlefsMntName是挂载点名称数组。⑸处开始的挂载操作变量g_lfsMnt、文件操作操作全局变量g_lfsFops在虚拟文件系统中被使用。

⑴  FileDirInfo g_lfsDir[LFS_MAX_OPEN_DIRS] = {0};⑵  struct FileOpInfo g_fsOp[LOSCFG_LFS_MAX_MOUNT_SIZE] = {0};
⑶  static LittleFsHandleStruct g_handle[LITTLE_FS_MAX_OPEN_FILES] = {0};
⑷  struct dirent g_nameValue;static pthread_mutex_t g_FslocalMutex = PTHREAD_MUTEX_INITIALIZER;static const char *g_littlefsMntName[LOSCFG_LFS_MAX_MOUNT_SIZE] = {"/a", "/b", "/c"};......
⑸  const struct MountOps g_lfsMnt = {.Mount = LfsMount,.Umount = LfsUmount,};const struct FileOps g_lfsFops = {.Mkdir = LfsMkdir,.Unlink = LfsUnlink,.Rmdir = LfsRmdir,.Opendir = LfsOpendir,.Readdir = LfsReaddir,.Closedir = LfsClosedir,.Open = LfsOpen,.Close = LfsClose,.Write = LfsWrite,.Read = LfsRead,.Seek = LfsSeek,.Rename = LfsRename,.Getattr = LfsStat,.Fsync = LfsFsync,.Fstat = LfsFstat,};

下文继续介绍下和这些变量相关的内部操作接口。

2.1 目录信息数组操作

GetFreeDir()设置目录信息数组元素信息。参数dirName为目录名称。遍历目录信息数组,遍历到第一个未使用的元素标记其为已使用状态,设置目录名称,返回目录信息元素指针地址。如果遍历失败,返回NULL。函数FreeDirInfo()为函数GetFreeDir()的反向操作,根据目录名称设置对应的数组元素为未使用状态,并把GetFreeDir设置为NULL。

函数CheckDirIsOpen()用于检测目录是否已经打开。如果目录信息数组中记录着对应的目录信息,则标志着该目录已经打开。

FileDirInfo *GetFreeDir(const char *dirName)
{pthread_mutex_lock(&g_FslocalMutex);for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {if (g_lfsDir[i].useFlag == 0) {g_lfsDir[i].useFlag = 1;g_lfsDir[i].dirName = strdup(dirName);pthread_mutex_unlock(&g_FslocalMutex);return &(g_lfsDir[i]);}}pthread_mutex_unlock(&g_FslocalMutex);return NULL;
}void FreeDirInfo(const char *dirName)
{pthread_mutex_lock(&g_FslocalMutex);for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {if (g_lfsDir[i].useFlag == 1 && strcmp(g_lfsDir[i].dirName, dirName) == 0) {g_lfsDir[i].useFlag = 0;if (g_lfsDir[i].dirName) {free(g_lfsDir[i].dirName);g_lfsDir[i].dirName = NULL;}pthread_mutex_unlock(&g_FslocalMutex);}}pthread_mutex_unlock(&g_FslocalMutex);
}BOOL CheckDirIsOpen(const char *dirName)
{pthread_mutex_lock(&g_FslocalMutex);for (int i = 0; i < LFS_MAX_OPEN_DIRS; i++) {if (g_lfsDir[i].useFlag == 1) {if (strcmp(g_lfsDir[i].dirName, dirName) == 0) {pthread_mutex_unlock(&g_FslocalMutex);return TRUE;}}}pthread_mutex_unlock(&g_FslocalMutex);return FALSE;
}

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:https://qr21.cn/FV7h05

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/27858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线时钟python案例

试了一下用通义来编写一些代码&#xff0c;以下是一个在线时钟的样例&#xff0c;只要能运行python就可以使用。 以下是运行后的结果。 代码&#xff08;复制可用&#xff09; import tkinter as tk from time import strftimedef update_time():current_time strftime(&quo…

Postman使用教程(Postman详细图文教程)

本文讲解的是postman工具安装、postman安装教程、postman工具下载、postman使用教程。Postman使得得开发人员和测试人员能够更高效地与Web服务进行交互和调试。 Postman不仅支持常见的HTTP方法&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;还提供了丰富的请求编辑功能&…

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告

20240615给飞凌的OK3588-C开发板刷Rockchip原厂的Buildroot后的测试报告&#xff1a; 【切记&#xff0c;由于没有替换DTS的&#xff0c;开发板发热量巨大&#xff01;因此配备鼓风机进行加强散热了】 0、adb 默认没有 1、HDMI IN 4K 2024/6/15 20:32 4K全屏 2、HDMI OUT …

Redis原理篇——分布式锁

Redis原理篇——分布式锁 分布式锁是什么&#xff1f;分布式锁有哪些特性&#xff1f;分布式锁常用实现方式Redis 实现分布式锁一、简单的 Redis 锁二、带过期时间的 Redis 锁三、加上 Owner 的 Redis 锁四、Lua 脚本确保原子性 分布式锁是什么&#xff1f; 分布式锁是在分布式…

软件体系结构笔记(自用)

来自《软件体系结构原理、方法与实践&#xff08;第三版&#xff09;》清华大学出版社 张友生编著 1-8章12章 复习笔记 如有错误&#xff0c;欢迎指正&#xff01;&#xff01;&#xff01;

HCIP认证笔记(填空)

1、为防止攻击者伪造BGP报文对设备进行攻击,可以通过配置GTSM功能检测IP报文中的TTL值的范围来对设备进行保护。如果某台设备配置了“peer x.x.x.x valid-ttl-hops 100",则被检测的报文的TTL值的有效范围为【(156),255】; 解析: peer {group-name | ipv4-address…

学习cel-go了解一下通用表达语言评估是什么

文章目录 1. 前言2. cel-go2.1 cel-go关键概念Applications(应用)Compilation(编译)Expressions(表达式)Environment环境解析表达式的三个阶段 3. cel-go的使用4. cel-go使用5. 说明6. 小结7. 参考 1. 前言 最近因为在项目里面实现的一个使用和||来组合获取字段值的功能有点儿…

MySQL员工练习

MySQL员工练习 1.数据显示 员工信息表emp&#xff1a; 字段&#xff1a;员工id,员工名字,工作岗位,部门经理,受雇日期,薪水,奖金,部门编号 英文名&#xff1a;EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,BONUS,DEPTNO 部门信息表dept&#xff1a; 字段&#xff1a;部门编号,部门名称,部…

自然抽样和平顶抽样

自然抽样和平顶抽样是两种信号处理和采样技术&#xff0c;它们在音频信号处理、信号重建以及数字信号处理中有着不同的应用。 1. 自然抽样&#xff08;也称为理想抽样或无失真抽样&#xff09;&#xff1a;样值脉冲的幅度随原始信号m(t)的幅度而变&#xff1b; 自然抽样过程的…

Java算法常用技巧

一、排序 资料&#xff1a;https://blog.csdn.net/weixin_72499901/article/details/136592073 正排序 import java.util.Arrays;public class SortArray {public static void main(String[] args) {int[] citations {5, 3, 8, 2, 1, 4};// 打印原数组System.out.println(&…

windows10或者windows11怎么查看自己电脑显卡型号

win10系统&#xff1a; 右键单击任务栏后弹出菜单选择任务管理器 打开任务管理器后&#xff0c;点击性能查看左侧GPU0或者GPU1 如果有nvidia字样表示自己电脑有nvidia显卡&#xff0c;如果是AMD或者intel字样表示没有nvidia显卡。注意如果你有GPU0或者GPU1说明你电脑是双显卡&…

后端中缓存的作用以及基于Spring框架演示实现缓存

缓存的作用及演示 现在我们使用的程序都是通过去数据库里拿数据然后展示的 长期对数据库进行数据访问 这样数据库的压力会越来越大 数据库扛不住了 创建了一个新的区域 程序访问去缓存 缓存区数据库 缓存里放数据 有效降低数据访问的压力 我们首先进行一个演示 为了演示…

spring boot配置ssl证书,支持https访问

1. 阿里云官网下载证书,云控制台搜索ssl&#xff0c;点击进入。 2.点击免费证书&#xff0c;立即购买。 3. 点击创建证书&#xff0c;填写完证书申请后&#xff0c;等待证书签发。 4. 证书签发以后&#xff0c;点击下载证书&#xff0c;spring boot选tomcat服务器类型的。 5. …

Android开发更改JDK版本

今天在跑GitHub上面一个Android项目时&#xff0c;在Android编译时出现如下错误&#xff1a; Unsupported Java. Your build is currently configured to use Java 17.0.2 and Gradle 7.0.2.错误原因&#xff1a; JDK和Gradle版本对应出错。 本地的JDK为1.8正好可以更改为本…

跨境电商测评、采购大额下单自养号需要解决哪些技术原理?

市场上有许多伪装工具&#xff0c;但大多数只是为了方便开发人员测试系统程序&#xff0c;它们并不能针对特定的电商平台进行伪装。每个电商平台都有其独特的风控机制&#xff0c;因此&#xff0c;我们需要从硬件环境的底层配合软件控制&#xff0c;以满足各平台的检测规则。 …

永磁同步直线电机(PMLSM)控制与仿真4-永磁同步直线电机数学三环闭环控制仿真

文章目录 1、参数设置及脚本2、相电流波形3、位置波形4、速度波形5、控制电流波形6、永磁同步直线电机在实际控制中如何控制参考 写在前面&#xff1a;原本为一篇文章写完了永磁同步直线电机数学模型介绍&#xff0c;永磁同步直线电机数学模型搭建&#xff0c;以及永磁同步直线…

Jacob环境探索(兼容性、管理员、DLL位置、VS环境,COM权限)

概述&#xff1a; 最近在生产开发实践出现了很多问题&#xff0c;经过了一系列排查&#xff0c;特做如下总结 探索成果&#xff1a; 1. jacob.dll的建议位置 首先jacob的官网&#xff0c;以及官方GitHub&#xff0c;你可以从这里找到DLL文件&#xff0c;以及相关资料然后DLL文…

【APP移动端自动化测试】第一节.环境配置和adb调试工具

文章目录 前言一、Java环境搭建二、AndroidSDK环境搭建三、Android模拟器安装四、adb调试工具基本介绍 4.1 adb构成和基本原理 4.2 adb获取包名&#xff0c;界面名 4.3 adb文件传输 4.4 adb获取app启动时间 4.5 adb获取手机日志 4.6 adb其他有关…

Windows 11 中安装 Docker Desktop 并安装镜像

本该主要介绍在 Windows 11 中安装 Docker Desktop 时的一些准备工作&#xff0c;以及该如何下载和安装&#xff0c;然后分别使用管理界面和 Docker 命令安装两个镜像。 一、准备工作 在 Windows 11 中安装 Docker Desktop 前&#xff0c;需要做一些准备。打开 【Windows 功能…

MongoDB~事务了解;可调一致性模型功能与因果一致性模型功能分析

背景 MongoDB 从 3.0版本引入 WiredTiger 存储引擎之后开始支持事务&#xff0c;MongoDB 3.6之前的版本只能支持单文档的事务&#xff0c;从 MongoDB 4.0版本开始支持复制集部署模式下的事务&#xff0c;从 MongoDB 4.2版本开始支持分片集群中的事务。 根据官方文档介绍&…