使用littlefs-fuse在PC端调试littlefs文件系统

2024-04-12 02:08

本文主要是介绍使用littlefs-fuse在PC端调试littlefs文件系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

littlefs是arm面向嵌入式设备推出的一款掉电安全的小型文件系统,具有抗掉电,动态磨损均衡,RAM/ROM需求少等特点,具体介绍可见 https://github.com/ARMmbed/littlefs

作为一款在嵌入式设备上使用的文件系统,出问题时,一般是需要将数据dump出来进行分析的。此时就需要PC端的调试工具了。

littlefs-fuse简介

这个项目提供了一个littlefs的FUSE封装,也就是你可以借助此项目,在PC上直接将littlefs镜像挂载起来,并正常进行一些文件系统的操作。

源码位于:https://github.com/ARMmbed/littlefs-fuse

结构

我们直接下载下来

 $ git clone https://github.com/ARMmbed/littlefs-fuse.git$ cd littlefs-fuse

先看下结构

$ tree -L 2.
├── lfs_fuse_bd.c
├── lfs_fuse_bd.h
├── lfs_fuse.c
├── LICENSE.md
├── littlefs
│   ├── DESIGN.md
│   ├── emubd
│   ├── lfs.c
│   ├── lfs.h
│   ├── lfs_util.c
│   ├── lfs_util.h
│   ├── LICENSE.md
│   ├── Makefile
│   ├── README.md
│   ├── scripts
│   ├── SPEC.md
│   └── tests
├── Makefile
└── README.md

外层是封装,里面则直接包含了littlefs文件夹。当我们需要特定版本的littlefs,例如使用跟设备上同一版本的littlefs时,只需要替换掉里层的这个littlefs即可,非常方便。

编译

根据README,项目依赖 FUSE version 2.6及以上的版本,可以使用如下命令查看版本

fusermount -V

另外还需要安装下 libfuse-dev:

sudo apt-get install libfuse-dev

依赖项满足之后,直接make即可生成lfs应用程序

make

生成设备并挂载使用

首先需要造一个块设备出来

sudo chmod a+rw /dev/loop0                  # make loop device user accessible
dd if=/dev/zero of=image bs=512 count=2048  # create a 1MB image
losetup /dev/loop0 image                    # attach the loop device

我们上一步是dd生成了一个空的image,所以需要先格式化,

./lfs --format /dev/loop0

再挂载

mkdir -p mount
./lfs /dev/loop0 mount

挂载成功后,执行mount可以看到挂载情况

$ mount | grep lfs
/home/zhuangqiubin/debug_littlefs/littlefs-fuse/lfs on /home/zhuangqiubin/debug_littlefs/littlefs-fuse/mount type fuse.lfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

现在就可以在mount目录下,随意进行操作了,创建删除读出写入,都会被转换成littlefs的操作,最终作用到image上

过程中,可以随时dump出数据,就可以看到你的操作,最终存储到littlefs上时什么样的数据格式了,例如

$ echo "www.cnblogs.com/zqb-all/" >> mount/test_littlefs.txt$ hexdump -C image
00000000  03 00 00 00 f0 0f ff f7  6c 69 74 74 6c 65 66 73  |........littlefs|
00000010  2f e0 00 10 00 00 02 00  00 02 00 00 00 08 00 00  |/...............|
00000020  ff 00 00 00 ff ff ff 7f  fe 03 00 00 20 00 04 09  |............ ...|
00000030  74 65 73 74 5f 6c 69 74  74 6c 65 66 73 2e 74 78  |test_littlefs.tx|
00000040  74 20 00 00 11 70 0f f9  b7 ee c0 48 bb ff ff ff  |t ...p.....H....|
00000050  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000200  04 00 00 00 f0 0f ff f7  6c 69 74 74 6c 65 66 73  |........littlefs|
00000210  2f e0 00 10 00 00 02 00  00 02 00 00 00 08 00 00  |/...............|
00000220  ff 00 00 00 ff ff ff 7f  fe 03 00 00 20 00 04 09  |............ ...|
00000230  74 65 73 74 5f 6c 69 74  74 6c 65 66 73 2e 74 78  |test_littlefs.tx|
00000240  74 20 00 00 08 77 77 77  2e 63 6e 62 6c 6f 67 73  |t ...www.cnblogs|
00000250  2e 63 6f 6d 2f 7a 71 62  2d 61 6c 6c 2f 0a 70 0f  |.com/zqb-all/.p.|
00000260  f9 87 46 fe c1 ad ff ff  ff ff ff ff ff ff ff ff  |..F.............|
00000270  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000400  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

使用完毕之后,用以下命令卸载

umount mount
sudo losetup -d /dev/loop0

挂载一个指定镜像

以上是生成了空的镜像,格式化再挂载。如果要挂载一个现成的镜像,步骤也是差不多的,只是镜像换一下。假设现成的镜像叫littlefs.img,则

sudo chmod a+rw /dev/loop0                  # make loop device user accessible
losetup /dev/loop0 littlefs.img                    # attach the loop device
mkdir -p mount
./lfs /dev/loop0 mount

卸载命令没有差别

umount mount
sudo losetup -d /dev/loop0

但从设备上dump出的littlefs镜像,其配置不一定会跟littlefs-fuse的默认配置匹配。

此时为了能正确挂载,以及准确地模拟littlefs在设备上运行的情况,我们需要将配置改成一样的。

解决方式一,直接修改源码,例如

diff --git a/lfs_fuse.c b/lfs_fuse.c
index 3c87dad..d1a99a2 100644
--- a/lfs_fuse.c
+++ b/lfs_fuse.c
@@ -26,7 +26,16 @@// config and other state
-static struct lfs_config config = {0};
+/* static struct lfs_config config = {0}; */
+static struct lfs_config config = {
+    .read_size = 256,
+    .prog_size = 256,
+    .block_size = 4096,
+    .block_count = 1224,
+    .block_cycles = 512,
+    .cache_size = 256,
+    .lookahead_size = 32
+};

修改后重新make生成即可

解决方式二,在调用的时候,通过命令行参数指定,例如

./lfs --block_size=512 --format /dev/loop0
./lfs --block_size=512 /dev/loop0 mount

支持的选项,可以在help中找到

$lfs -h
usage: ./lfs [options] device mountpointgeneral options:-o opt,[opt...]        FUSE options-h   --help            print help-V   --version         print versionlittlefs options:--format               format instead of mounting--migrate              migrate previous version  instead of mounting-b   --block_size      logical block size, overrides the block device--block_count          block count, overrides the block device--block_cycles         number of erase cycles before eviction (512)--read_size            readable unit (block_size)--prog_size            programmable unit (block_size)--cache_size           size of caches (block_size)--lookahead_size       size of lookahead buffer (8192)--name_max             max size of file names (255)--file_max             max size of file contents (2147483647)--attr_max             max size of custom attributes (1022)FUSE options:-d   -o debug          enable debug output (implies -f)-f                     foreground operation-s                     disable multi-threaded operation-o allow_other         allow access to other users-o allow_root          allow access to root-o auto_unmount        auto unmount on process termination-o nonempty            allow mounts over non-empty file/dir-o default_permissions enable permission checking by kernel-o fsname=NAME         set filesystem name-o subtype=NAME        set filesystem type-o large_read          issue large read requests (2.4 only)-o max_read=N          set maximum size of read requests-o hard_remove         immediate removal (don't hide files)-o use_ino             let filesystem set inode numbers-o readdir_ino         try to fill in d_ino in readdir-o direct_io           use direct I/O-o kernel_cache        cache files in kernel-o [no]auto_cache      enable caching based on modification times (off)-o umask=M             set file permissions (octal)-o uid=N               set file owner-o gid=N               set file group-o entry_timeout=T     cache timeout for names (1.0s)-o negative_timeout=T  cache timeout for deleted names (0.0s)-o attr_timeout=T      cache timeout for attributes (1.0s)-o ac_attr_timeout=T   auto cache timeout for attributes (attr_timeout)-o noforget            never forget cached inodes-o remember=T          remember cached inodes for T seconds (0s)-o nopath              don't supply path if not necessary-o intr                allow requests to be interrupted-o intr_signal=NUM     signal to send on interrupt (10)-o modules=M1[:M2...]  names of modules to push onto filesystem stack-o max_write=N         set maximum size of write requests-o max_readahead=N     set maximum readahead-o max_background=N    set number of maximum background requests-o congestion_threshold=N  set kernel's congestion threshold-o async_read          perform reads asynchronously (default)-o sync_read           perform reads synchronously-o atomic_o_trunc      enable atomic open+truncate support-o big_writes          enable larger than 4kB writes-o no_remote_lock      disable remote file locking-o no_remote_flock     disable remote file locking (BSD)-o no_remote_posix_lock disable remove file locking (POSIX)-o [no_]splice_write   use splice to write to the fuse device-o [no_]splice_move    move data while splicing to the fuse device-o [no_]splice_read    use splice to read from the fuse deviceModule options:[iconv]-o from_code=CHARSET   original encoding of file names (default: UTF-8)-o to_code=CHARSET	    new encoding of the file names (default: UTF-8)[subdir]-o subdir=DIR	    prepend this directory to all paths (mandatory)-o [no]rellinks	    transform absolute symlinks to relative

调试

既然可以在PC上模拟挂载和读写,那首先最直观的,就是可以在littlefs的源码中按需添加调试代码,再重新挂载dump出来的镜像,通过打印来分析问题。

其次,必要的时候,我们还可以上gdb

make DEBUG=1 clean all                # build with debug info
gdb --args ./lfs -d /dev/loop0 mount  # run with gdb

本文地址:https://www.cnblogs.com/zqb-all/p/12078659.html

这篇关于使用littlefs-fuse在PC端调试littlefs文件系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895814

相关文章

Python数据验证神器Pydantic库的使用和实践中的避坑指南

《Python数据验证神器Pydantic库的使用和实践中的避坑指南》Pydantic是一个用于数据验证和设置的库,可以显著简化API接口开发,文章通过一个实际案例,展示了Pydantic如何在生产环... 目录1️⃣ 崩溃时刻:当你的API接口又双叒崩了!2️⃣ 神兵天降:3行代码解决验证难题3️⃣ 深度

Linux内核定时器使用及说明

《Linux内核定时器使用及说明》文章详细介绍了Linux内核定时器的特性、核心数据结构、时间相关转换函数以及操作API,通过示例展示了如何编写和使用定时器,包括按键消抖的应用... 目录1.linux内核定时器特征2.Linux内核定时器核心数据结构3.Linux内核时间相关转换函数4.Linux内核定时

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

Springboot3 ResponseEntity 完全使用案例

《Springboot3ResponseEntity完全使用案例》ResponseEntity是SpringBoot中控制HTTP响应的核心工具——它能让你精准定义响应状态码、响应头、响应体,相比... 目录Spring Boot 3 ResponseEntity 完全使用教程前置准备1. 项目基础依赖(M

Java使用Spire.Barcode for Java实现条形码生成与识别

《Java使用Spire.BarcodeforJava实现条形码生成与识别》在现代商业和技术领域,条形码无处不在,本教程将引导您深入了解如何在您的Java项目中利用Spire.Barcodefor... 目录1. Spire.Barcode for Java 简介与环境配置2. 使用 Spire.Barco

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

C# 预处理指令(# 指令)的具体使用

《C#预处理指令(#指令)的具体使用》本文主要介绍了C#预处理指令(#指令)的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录1、预处理指令的本质2、条件编译指令2.1 #define 和 #undef2.2 #if, #el

C#中Trace.Assert的使用小结

《C#中Trace.Assert的使用小结》Trace.Assert是.NET中的运行时断言检查工具,用于验证代码中的关键条件,下面就来详细的介绍一下Trace.Assert的使用,具有一定的参考价值... 目录1、 什么是 Trace.Assert?1.1 最简单的比喻1.2 基本语法2、⚡ 工作原理3