使用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

相关文章

vue使用docxtemplater导出word

《vue使用docxtemplater导出word》docxtemplater是一种邮件合并工具,以编程方式使用并处理条件、循环,并且可以扩展以插入任何内容,下面我们来看看如何使用docxtempl... 目录docxtemplatervue使用docxtemplater导出word安装常用语法 封装导出方

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意