#embassy #filesystem #no-std #fatfs

sys no-std fatfs-embedded

Rust 对流行的嵌入式 FatFs 库的绑定

1 个不稳定版本

0.1.0 2024年1月27日

#859 in 嵌入式开发

MIT 许可证

2.5MB
23K SLoC

C 22K SLoC // 0.0% comments Rust 710 SLoC

fatfs-embedded

Rust 对来自 elm-chan.org 的流行嵌入式 FatFs 库的绑定。完整文档可在 docs.rs 上找到。


lib.rs:

FatFs 是一个通用的 FAT/exFAT 文件系统模块,专为小型嵌入式系统设计。 fatfs-embeddedelm-chan.org 上的流行 FatFs 库的 Rust 封装。它基于 R0.15 版本。

目标

  • 嵌入式使用 - 默认情况下,此库是 no_std,但针对操作系统时,为了测试目的,是 std 兼容的。
  • 线程安全 - 选择依赖于 Embassy 框架以支持并发,该框架适合嵌入式系统。为了替代 FF_FS_REENTRANT 选项,实现了全局文件系统互斥锁,这对于 Rust 实现来说更合适。
  • 可移植 - 通过实现 FatFsDriver 特性来添加对任何块设备的支持。由于 FatFs 的结构,不幸地需要 alloc 支持。包括一个模拟的块存储驱动程序实现,供测试使用,可能用作参考。

Drop

决定不实现文件或目录的 Drop 特性。这是因为这样做将需要获取文件系统对象的锁,这很容易引起锁定条件。文件和目录必须手动关闭。(文件系统对象本身被实现为一个静态单例,因此永远不会丢弃。)

FatFs 配置

大多数 FatFs 功能都启用了,但有少数例外

  • FF_USE_FORWARD 被禁用,以避免使用额外的 unsafe 代码。
  • FF_CODE_PAGE 被设置为 0,因此必须通过调用 setcp() 来设置。
  • FF_VOLUMES 目前设置为 1,限制了支持的卷数只能为 1。
  • FF_MULTI_PARTITION 目前不支持。
  • FF_FS_LOCK 配置为支持 10 个同时打开的文件。
  • 没有提供 f_printf() 函数的实现。

功能

  • chrono(默认)- 启用库中的时间支持。可以通过FatFsDriver特质的实现提供对RTC的访问。

示例

一个简短的示例,格式化和挂载一个模拟驱动器,将字符串写入文件,然后读取数据

#[path = "../tests/simulated_driver.rs"]
mod simulated_driver;

use fatfs_embedded::fatfs::{self, File, FileOptions, FormatOptions};
use embassy_futures::block_on;

const TEST_STRING: &[u8] = b"Hello world!";

//Install a block device driver that implements `FatFsDriver`
let driver = simulated_driver::RamBlockStorage::new();
block_on(fatfs::diskio::install(driver));

//Acquire a lock on the file system.
let mut locked_fs = block_on(fatfs::FS.lock());

//Format the drive.
locked_fs.mkfs("", FormatOptions::FAT32, 0, 0, 0, 0);

//Mount the drive.
locked_fs.mount();

//Create a new file.
let mut test_file: File = locked_fs.open("test.txt", 
    FileOptions::CreateAlways | 
    FileOptions::Read | 
    FileOptions::Write).unwrap();

//Write a string to the file.
locked_fs.write(&mut test_file, TEST_STRING);

//Seek back to the beginning of the file.
locked_fs.seek(&mut test_file, 0);

//Read the string back from the file.
let mut read_back: [u8; TEST_STRING.len()] = [0; TEST_STRING.len()];
locked_fs.read(&mut test_file, &mut read_back);
assert_eq!(TEST_STRING, read_back);

//Close the file when done.
locked_fs.close(&mut test_file);

依赖项

~2.3–5MB
~89K SLoC