Merge branch 'main' into TFTP

This commit is contained in:
2023-11-13 12:27:58 +01:00
5 changed files with 1198 additions and 532 deletions

View File

@@ -1,17 +1,52 @@
# LLFS (Linked List File System)
## Introduction
The llfs filesystem can be generated using the mkllfss utility.
It is a simple filesystem that uses a linked list to store files.
The filesystem is stored in a single c file (`llfs_data.c`), which can be compiled and read by the llfs library.
The llfs filesystem is a flat filesystem, meaning that it does not support directories.
The llfs filesystem can be generated using the [mkllfs](mkllfs.md) utility.
The resulting C file encapsulates the filesystem data within a linked list which can be used by the llfs library.
As a flat filesystem, llfs lacks support for directories.
Using the llfs API, information about the files in the filesystem can be retrieved,
and the files can be read using direct memory access.
Alternatively, the POSIX file functions can be used.
But this is more resource intensive, as data must be copied before using it.
It's essential to note that the llfs filesystem operates in a read-only mode,
restricting operations solely to read functions.
## Table of contents
- [Introduction](#introduction)
- [Table of contents](#table-of-contents)
- [Initialization](#initialization)
- [Usage of the llfs API](#usage-of-the-llfs-api)
- [The `llfs_file_t` struct](#the-llfs_file_t-struct)
- [Getting a list of files](#getting-a-list-of-files)
- [Iterator function (not recommended)](#iterator-function-not-recommended)
- [Reading a file](#reading-a-file)
- [Getting the number of files](#getting-the-number-of-files)
- [Using the POSIX file functions](#using-the-posix-file-functions)
## Initialization
Before using the llfs API, or the file related POSIX (fopen, fgetc, ...) functions, the filesystem must be initialized by calling `llfs_init()`.
## Usage of the llfs API
### The `llfs_file_t` struct
The `llfs_file_t` struct contains information about a file in the filesystem.
```c
typedef struct {
const uint8_t* data; // Pointer to the file data (len bytes)
const char* name; // Null-terminated string with the filename
size_t len; // Length of the file data
} llfs_file_t;
```
The data pointer points to the data of the file in the filesystem, and can be used to read the file.
### Getting a list of files
```c
#include "llfs.h"
void main(void) {
llfs_init();
// Allocate space for 10 files
llfs_file_t file_list[10];
@@ -33,13 +68,50 @@ Result:
[Info] (2031) [main]: File: file1.txt, size: 77
```
It is also possible to use a file extension filter (e.g. `*.bmp`, `*.txt`, `*.py`).
```c
// ...
size_t file_count = llfs_file_list(file_list, 10, "*.bmp");
// ...
```
This will only return files with the `.bmp` extension.
````
[Info] (2009) [main]: File: image.bmp, size: 9270
[Info] (2019) [main]: File: image2.bmp, size: 7738
````
#### Iterator function (not recommended)
It is also possible to iterate through the files without allocating an array.
When the memory pointer is `NULL`, the iterator will start at the beginning of the file list.
Each call to `llfs_next_file()` will return the next file in the list,
if a filter is specified files that don't match the filter will be skipped.
```c
#include "llfs.h"
void main(void) {
llfs_init();
// Get the file list
void* mem = NULL; // Pointer for internal use by the llfs library
llfs_file_t* file;
while ((file = llfs_next_file(&mem, ".bmp")) != NULL) {
LOG_INFO(TAG, "File: %s", file->name);
}
}
```
While this method doesn't require allocating memory for the file list,
it is slower than the previous method due to the overhead calling the function for each file.
Additionally, the required memory for the filelist is very small, so it's recommended to use the first method.
### Reading a file
```c
#include "llfs.h"
void main(void) {
llfs_init();
// Get a file by name
llfs_file_t *file = llfs_file_open("filename with a space.txt");
llfs_file_t* file = llfs_file_open("filename with a space.txt");
if (file != NULL) {
// Print the file name, size and data
@@ -55,3 +127,37 @@ Result:
[Info] (2040) [main]: File found: filename with a space.txt, size: 61
[Info] (2047) [main]: File data: This is a file with a space in it's filename.
```
### Getting the number of files
```c
#include "llfs.h"
void main(void) {
llfs_init();
// Get the number of files
size_t file_count = llfs_file_count();
// Print the number of files
LOG_INFO(TAG, "File count: %d", file_count);
}
```
## Using the POSIX file functions
The llfs library also supports the POSIX file functions.
As the file system is read-only, write functions are not implemented.
There is also a limit on the number of files that can be open concurrently,
this is set by the `POSIX_MAX_FILES` macro in `llfs.c`.
The default value is 10, but there are already 3 files in use (stdin, stdout, stderr),
so the maximum number of files that can be open is 7.
The following functions are tested and working, but other functions might also work:
- `fopen`
- `fclose`
- `fgetc`
- `fread`
- `fseek`
- `ftell`
- `rewind`
- `fstat`
- `fileno`