背景

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 mountpoint general options:
-o opt,[opt...] FUSE options
-h --help print help
-V --version print version littlefs 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 device Module 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文件系统的更多相关文章

  1. CoCos2dx开发:PC端调试运行正常但打包apk文件后在手机上点击闪退

    记:今天调试时出现的一个PC端调试运行正常,但打包apk文件后在手机上点击闪退的问题. 可能在不同的情况条件下,会有不同的原因导致apk安装后闪退问题.拿android studio等软件来说,开发安 ...

  2. 【工具】PC端调试手机端 Html 页面的工具

    一.概述 有一个项目需要在手机端显示一个 web 页面,而每次把应用 launch 后,从手机端看比较麻烦,因此搜罗了几种在 PC 端调试手机端页面的工具. 二.工具 http://fonkie.it ...

  3. 小程序开发时PC端调试返回结果和手机端IOS不一致问题

    IOS11登录时遇到一个请求与PC返回不一致情况, 在小程序调试时IOS上始终没有wx.request() 不能发送请求 尝试解决方法 打开微信小程序调试的设置, 将TLS设为可信任的域名 设置 -- ...

  4. 安装weinre在PC端调试移动端

    1.使用node安装weinre. 2.启动weinre, weinre --httpPort 8081  --boundHost -all- 3.在浏览器打开 http://localhost:80 ...

  5. Fiddler4工具配置及调试手机和PC端浏览器

    Fiddler最大的用处: 模拟请求.修改请求.手机应用调试 Fiddler最新版本 下载地址: http://www.telerik.com/download/fiddler Fiddler 想要监 ...

  6. PC端写的API接口和手机端APP联合调试

    一.遇到问题的情况:项目框架:asp.net MVC5 ,写的给手机端调用的API接口. 二.自己在本地 IIS上部署项目,在手机端的请求服务器上把地址和端口换上本地部署的,如图所示 三.用管理员的身 ...

  7. 让你在PC上调试Web App,UC浏览器发布开发者版

    目前,在手机上使用浏览器访问网页,无法便捷地进行网页语言调试.手机屏幕相对较小且操作不便,直接在手机上进行网页数据调试不太现实. 因此,UC使用技术将手机网页调试信息分离,实现一种能在大屏幕.高配置P ...

  8. PC远程调试移动设备

    我们在移动端进行前端开发时,会遇到一个让人头痛但不得不面对的问题——调试. 在 PC 机器上,我们有功能强大的 Chrome DevTools.Firebug,即便是老版本的 IE ,我们也可以安装微 ...

  9. 移动端调试利器 JSConsole 介绍

    先看这篇文章 Web应用调试:现在是Weinre和JSConsole,最终会是WebKit的远程调试协议. 我们先不看未来,从此文可见,当下的移动端调试还是 Weinre 和 JSConsole 的天 ...

随机推荐

  1. 【Luogu P2024&P1892】食物链&团伙(并查集拓展域)

    Luogu P1892 Luogu P2024 这两道一眼看过去很容易发现可以用并查集来做--但是当我们仔细阅读题面后,会发现其实并没有那么简单. 我们知道并查集可以很轻松地维护具有传递性的信息,也就 ...

  2. 【Luogu P2002&P2341】消息扩散/受欢迎的奶牛

    Luogu P2002 Luogu P2341 使用强连通分量算法缩点 第一题统计入度为0的个数强连通分量数. 第二题的答案为当且仅当仅有一个强连通分量的出度为0时该强连通分量的节点数,原因如下:若一 ...

  3. GitHub的高级搜索方式

    平时在学完一个知识后,需要写些 demo来进行练手,这个时候 GitHub就是最好不过的资源库了,以下整理了一些关于在 github 上面找项目的一些小技巧. 一.单条件使用 项目名称 仓库名称包含 ...

  4. css优先级之important

    css优先级之important

  5. 从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  6. CTF中遇到的php

    1.if(eregi("hackerDJ",$_GET[id])) {   //eregi字符串对比 echo("<p>not allowed!</p& ...

  7. Lua和C交互的简易教程

    转载请标明出处:http://blog.csdn.net/shensky711/article/details/52458051 本文出自: [HansChen的博客] Lua栈 要理解Lua和C++ ...

  8. 【Android - 自定义View】之自定义九宫格手势解锁控件

    首先来介绍一下这个自定义View: (1)这个自定义View的名称叫做 LockView ,继承自View类: (2)这个自定义View实现了应用中常见的九宫格手势解锁功能,可以用于保证应用安全: ( ...

  9. 英语口语考试资料Food

    新东方推荐文章:Food and Health The food we eat seems to have profound effects on our health. Although scien ...

  10. c 程序之 最大公约数 和 最小公倍数

    1.最大公约数     30  10  -> 10 #include<stdio.h> /* 求最大公约数 辗转相减法 36 --16 4 */ int main(){ int a, ...