LittleFileSystem
LittleFileSystem 类层次结构
小文件系统(LittleFS)是专为嵌入式系统设计的故障安全文件系统,专门用于使用外部闪存存储的微控制器。
| | | .---._____
.-----. | |
--|o |---| LittleFS |
--| |---| |
'-----' '----------'
| | |
微控制器和闪存存储对嵌入式存储提出了三个挑战:功耗,磨损以及有限的 RAM 和 ROM。该文件系统为所有这三个问题提供了解决方案。
-
有限的 RAM/ROM - 此文件系统使用有限的内存。它避免了递归并将动态内存限制为可以静态提供的可配置缓冲区。
-
功率损耗弹性 - 我们为可能存在随机电源故障的操作系统设计了此功能。它具有强大的写时复制保证,并使磁盘上的存储保持有效状态。
-
磨损均衡 - 由于最常见的嵌入式存储形式是易受攻击的闪存,因此文件系统为无法容纳完整闪存转换层的系统提供了一种动态耗损均衡。
有关其他信息,请参阅存储概述页面。
用例
我们为具有外部闪存存储的微控制器构建了这个产品。在这种情况下,它在 RAM,ROM,磨损和运行时方面优于其他 Mbed OS 文件系统。
要存储在可从 PC 访问的 SD 卡上,请使用 FATFileSystem,因为它具有可移植性。
用法
使用块设备和文件路径实例化 LittleFileSystem 类。
它提供的 API 是标准的 Mbed OS 文件系统 API。声明后,Mbed OS 为标准 C 库提供重定向层。
LittleFileSystem 类参考
公共成员函数 | |
LittleFileSystem (const char *name=NULL, BlockDevice *bd=NULL, lfs_size_t read_size=MBED_LFS_READ_SIZE, lfs_size_t prog_size=MBED_LFS_PROG_SIZE, lfs_size_t block_size=MBED_LFS_BLOCK_SIZE, lfs_size_t lookahead=MBED_LFS_LOOKAHEAD) | |
virtual int | mount (BlockDevice *bd) |
virtual int | unmount () |
virtual int | reformat (BlockDevice *bd) |
virtual int | remove (const char *path) |
virtual int | rename (const char *path, const char *newpath) |
virtual int | stat (const char *path, struct stat *st) |
virtual int | mkdir (const char *path, mode_t mode) |
virtual int | statvfs (const char *path, struct statvfs *buf) |
公共成员函数继承自 mbed::FileSystem | |
FileSystem (const char *name=NULL) | |
公共成员函数继承自 mbed::FileSystemLike | |
FileSystemLike (const char *name=NULL) | |
FileHandle * | open (const char *path, int flags) |
DirHandle * | opendir (const char *path) |
公共成员函数继承自 mbed::FileSystemHandle | |
virtual | ~FileSystemHandle () |
公共成员函数继承自 mbed::FileBase | |
FileBase (const char *name, PathType t) | |
const char * | getName (void) |
PathType | getPathType (void) |
静态公共成员函数 | |
static int | format (BlockDevice *bd, lfs_size_t read_size=MBED_LFS_READ_SIZE, lfs_size_t prog_size=MBED_LFS_PROG_SIZE, lfs_size_t block_size=MBED_LFS_BLOCK_SIZE, lfs_size_t lookahead=MBED_LFS_LOOKAHEAD) |
静态公共成员函数继承自 mbed::FileBase | |
static FileBase * | lookup (const char *name, unsigned int len) |
static FileBase * | get (int n) |
受保护的成员函数 | |
virtual int | file_open (mbed::fs_file_t *file, const char *path, int flags) |
virtual int | file_close (mbed::fs_file_t file) |
virtual ssize_t | file_read (mbed::fs_file_t file, void *buffer, size_t size) |
virtual ssize_t | file_write (mbed::fs_file_t file, const void *buffer, size_t size) |
virtual int | file_sync (mbed::fs_file_t file) |
virtual off_t | file_seek (mbed::fs_file_t file, off_t offset, int whence) |
virtual off_t | file_tell (mbed::fs_file_t file) |
virtual off_t | file_size (mbed::fs_file_t file) |
virtual int | dir_open (mbed::fs_dir_t *dir, const char *path) |
virtual int | dir_close (mbed::fs_dir_t dir) |
virtual ssize_t | dir_read (mbed::fs_dir_t dir, struct dirent *ent) |
virtual void | dir_seek (mbed::fs_dir_t dir, off_t offset) |
virtual off_t | dir_tell (mbed::fs_dir_t dir) |
virtual void | dir_rewind (mbed::fs_dir_t dir) |
受保护的成员函数继承自 mbed::FileSystem | |
virtual int | file_isatty (fs_file_t file) |
virtual void | file_rewind (fs_file_t file) |
virtual size_t | dir_size (fs_dir_t dir) |
virtual int | open (FileHandle **file, const char *path, int flags) |
virtual int | open (DirHandle **dir, const char *path) |
LittleFileSystem 示例
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include <stdio.h>
#include <errno.h>
// Block devices
#include "SPIFBlockDevice.h"
#include "SDBlockDevice.h"
#include "HeapBlockDevice.h"
// File systems
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
// Physical block device, can be any device that supports the BlockDevice API
SPIFBlockDevice bd(
MBED_CONF_SPIF_DRIVER_SPI_MOSI,
MBED_CONF_SPIF_DRIVER_SPI_MISO,
MBED_CONF_SPIF_DRIVER_SPI_CLK,
MBED_CONF_SPIF_DRIVER_SPI_CS);
// File system declaration
LittleFileSystem fs("fs");
// Set up the button to trigger an erase
InterruptIn irq(BUTTON1);
void erase() {
printf("Initializing the block device... ");
fflush(stdout);
int err = bd.init();
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Erasing the block device... ");
fflush(stdout);
err = bd.erase(0, bd.size());
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Deinitializing the block device... ");
fflush(stdout);
err = bd.deinit();
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
}
// Entry point for the example
int main() {
printf("--- Mbed OS filesystem example ---\n");
// Setup the irq in case we want to use it
irq.fall(erase);
// Try to mount the filesystem
printf("Mounting the filesystem... ");
fflush(stdout);
int err = fs.mount(&bd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
// Reformat if we can't mount the filesystem
// this should only happen on the first boot
printf("No filesystem found, formatting... ");
fflush(stdout);
err = fs.reformat(&bd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
}
// Open the numbers file
printf("Opening \"/fs/numbers.txt\"... ");
fflush(stdout);
FILE *f = fopen("/fs/numbers.txt", "r+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
// Create the numbers file if it doesn't exist
printf("No file found, creating a new file... ");
fflush(stdout);
f = fopen("/fs/numbers.txt", "w+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
for (int i = 0; i < 10; i++) {
printf("\rWriting numbers (%d/%d)... ", i, 10);
fflush(stdout);
err = fprintf(f, " %d\n", i);
if (err < 0) {
printf("Fail :(\n");
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
printf("Seeking file... ");
fflush(stdout);
err = fseek(f, 0, SEEK_SET);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
// Go through and increment the numbers
for (int i = 0; i < 10; i++) {
printf("\rIncrementing numbers (%d/%d)... ", i, 10);
fflush(stdout);
// Get current stream position
long pos = ftell(f);
// Parse out the number and increment
int32_t number;
fscanf(f, "%d", &number);
number += 1;
// Seek to beginning of number
fseek(f, pos, SEEK_SET);
// Store number
fprintf(f, " %d\n", number);
}
printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
// Close the file which also flushes any cached writes
printf("Closing \"/fs/numbers.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Display the root directory
printf("Opening the root directory... ");
fflush(stdout);
DIR *d = opendir("/fs/");
printf("%s\n", (!d ? "Fail :(" : "OK"));
if (!d) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
printf("root directory:\n");
while (true) {
struct dirent *e = readdir(d);
if (!e) {
break;
}
printf(" %s\n", e->d_name);
}
printf("Closing the root directory... ");
fflush(stdout);
err = closedir(d);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Display the numbers file
printf("Opening \"/fs/numbers.txt\"... ");
fflush(stdout);
f = fopen("/fs/numbers.txt", "r");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
printf("numbers:\n");
while (!feof(f)) {
int c = fgetc(f);
printf("%c", c);
}
printf("\rClosing \"/fs/numbers.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Tidy up
printf("Unmounting... ");
fflush(stdout);
err = fs.unmount();
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Mbed OS filesystem example done!\n");
}