diff --git a/.gitignore b/.gitignore index e818d98..1d3d17a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,18 @@ *.out *.app +# Log files +*.log + +# Metadata directories +.metadata/ +project/.metadata + +# Test files +project/Core/Inc/stlogo.h +project/Core/Inc/test_img.h +project/Core/Inc/test_data.h + project/Debug/ project/.idea/ @@ -43,4 +55,5 @@ project/.mxproject project/project.launch -project/.cproject \ No newline at end of file +project/Scripts +Scripts/ \ No newline at end of file diff --git a/docs/lcd_api.md b/docs/lcd_api.md new file mode 100644 index 0000000..32c46ae --- /dev/null +++ b/docs/lcd_api.md @@ -0,0 +1,92 @@ +# LCD API + +## Introduction + +The LCD API can be used to display BMP images or text onto the LCD screen. +At the moment of writing, only BMP's in C array's are supported. +Supported color schemes for BMP's are ARGB8888, RGB565, RGB888. +Displayed text that is exceeds the LCD width size, will be wrapped onto the next line and a '-' character will be injected if the wrap occurs within a word. + +## Usage of LCD API +### Generating BMP C header files +#### Resizing images +To resize an image to the desired size (width and height), one can use an image editor such as Photoshop, GIMP, ImageMagick, ... . + +For example, using ImageMagick: +```bash +convert in.png -resize 10% BMP3:out.bmp +#OR (depending on the version of ImageMagick) +magick in.png -resize 50x50 out.png +``` + +The resize option can both be used to resize in percentages or in pixels. + +The BMP3 option is used to convert the PNG to Bitmap version 3.0 (note that the BMP header will still be present in the output image). + +#### Generating the C array +To easily generate a BMP C array (in the desired color scheme) from an image, [lv_img_conv](https://github.com/lvgl/lv_img_conv) can be used. + +See the installation instructions on Github or use the [online version](https://lvgl.io/tools/imageconverter). + +Example: +```bash +./lv_img_conv.js test.png -f -c CF_TRUE_COLOR +``` + +The command above will generate a .c file in which arrays can be found for RGB332, RGB565, ARGB8888. It is also possible to generate a binary BMP image file in ARGB8332, ARGB8565, ARGB8565_RBSWAP, ARGB8888. +```bash +./lv_img_conv.js logo_lvgl.png -f -c CF_TRUE_COLOR -t bin --binary-format ARGB8888 +``` + +### Using the LCD API +#### Initialization of LCD API +The `lcd_init(bool bl_on)` function initialises the LCD screen. The `bl_on` variable allows to enable or disable the LCD backlight. +```c +#include "lcd_api.h" + +... + +void main(void) { + ... + lcd_init(true); + ... +} +``` + +#### Drawing text on the screen + +```c +void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font); +``` + +```c +#include "lcd_api.h" + +... + +void main(void) { + ... + lcd_init(true); + ... + lcd_display_text("This is a text string.", 10, 10, LCD_GREEN, LCD_BLACK, LCD_FONT16); +} +``` +Display text on the LCD screen in a certain color. When text width exceeds BSP_LCD_GetXSize(), a text wrap will be performed. If the text wrap is between two will be injected. + +#### Drawing a BMP (C-array) onto the screen +```c +void lcd_draw_bmp(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_t x_size, uint32_t y_size, uint32_t color_mode); +``` + +```c +#include "lcd_api.h" +#include "test_image.h" + +void main(void) { + ... + lcd_init(true); + ... + lcd_draw_bmp(bmp_array, 0, 0, 50, 50, LCD_ARGB8888); +} +``` +Draw BMP image from C array to the LCD screen at position X, Y. In color mode ARGB8888, RGB888, RGB565 or ARGB1555 Supports ARGB8888, RGB565, RGB888 (see LCD_* defines in header file). diff --git a/docs/llfs.md b/docs/llfs.md index eac7c21..2fa6986 100644 --- a/docs/llfs.md +++ b/docs/llfs.md @@ -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` diff --git a/docs/mkllfs.md b/docs/mkllfs.md index 971ae5f..1e6ed8c 100644 --- a/docs/mkllfs.md +++ b/docs/mkllfs.md @@ -7,6 +7,8 @@ The llfs filesystem is a flat filesystem, meaning that it does not support direc The mkllfs utilit can be used to generate the `llfs_data.c` file. The `llfs_data.c` file from a directory with files. +A pre-compiled version can be download: [mkllfs.exe](https://github.com/Sani7/2023-Webservices_And_Applications/releases/tag/v0.2.0) + ## Usage The mkllfs utility can be used as follows: ```bash @@ -22,6 +24,10 @@ Available options: -v, --version print the version of mkllfs and the llfs library that it generates for ``` +### Using the batch file +The `mkllfs.bat` file can be used to generate the `llfs_data.c` file from the data in the `llfs-data` directory. +Before using this script, place mkllfs.exe in the same directory as the batch file. + ## Building The mkllfs utility can be built using the following command: ```bash @@ -30,4 +36,4 @@ gcc -o mkllfs mkllfs.c For windows, you can use the following command: ```bash gcc -o mkllfs.exe mkllfs.c -``` \ No newline at end of file +``` diff --git a/llfs-data/color_bar.bmp b/llfs-data/color_bar.bmp new file mode 100644 index 0000000..7617e44 Binary files /dev/null and b/llfs-data/color_bar.bmp differ diff --git a/llfs-data/st.bmp b/llfs-data/st.bmp new file mode 100644 index 0000000..7f04d96 Binary files /dev/null and b/llfs-data/st.bmp differ diff --git a/llfs-data/test.txt b/llfs-data/test.txt new file mode 100644 index 0000000..f0655f1 --- /dev/null +++ b/llfs-data/test.txt @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer penatibus lorem nunc semper venenatis vestibulum urna. Hac elit inceptos mattis integer sollicitudin pellentesque parturient. Est fermentum laoreet class egestas odio tellus condimentum. \ No newline at end of file diff --git a/llfs-data/test2.txt b/llfs-data/test2.txt new file mode 100644 index 0000000..ee5aba4 --- /dev/null +++ b/llfs-data/test2.txt @@ -0,0 +1 @@ +Aliquet pellentesque morbi fermentum dolor fermentum auctor lacinia. Montes euismod habitasse fringilla praesent sodales metus interdum. Lacinia vel duis cum auctor class commodo adipiscing. Elementum condimentum taciti iaculis metus ornare duis curae. Risus consectetur urna convallis metus fusce arcu class. Nisl himenaeos vel praesent laoreet taciti himenaeos lacus. Duis pharetra aptent phasellus sodales imperdiet aptent elit. \ No newline at end of file diff --git a/mkllfs.cmd b/mkllfs.cmd new file mode 100644 index 0000000..e20ce47 --- /dev/null +++ b/mkllfs.cmd @@ -0,0 +1,2 @@ +mkllfs.exe llfs-data project/Core/Src/llfs_data.c +pause \ No newline at end of file diff --git a/mkllfs/main.c b/mkllfs/main.c index b188d52..6c21641 100644 --- a/mkllfs/main.c +++ b/mkllfs/main.c @@ -1,7 +1,7 @@ /** * @file main.c * @brief Converts files to a C file that can be used by llfs (linked list file system). - * @version 0.1.0 + * @version 0.2.0 * @author Lorenz C. */ @@ -10,8 +10,8 @@ #include #include "tinydir.h" -#define VERSION "0.1.0" -#define LLFS_VERSION "0.1.0" +#define VERSION "0.2.0" +#define LLFS_VERSION "0.1.1" #define MAX_PATH_LEN 256 static void file_name_to_llfs_name(char* llfs_name, const char* file_name); @@ -99,6 +99,7 @@ int main(int argc, char** argv) { // Write the file data to the output file fprintf(out_file, "// File: %s\n", file.name); + fprintf(out_file, "__attribute__((section(\".ext_qspi_flash\")))\n"); fprintf(out_file, "const uint8_t %s_data[] = {\n", llfs_name); for (int i = 0, c; (c = fgetc(src_file)) != EOF; i++) { file_size++; diff --git a/project/.cproject b/project/.cproject index b36ef16..a5b2457 100644 --- a/project/.cproject +++ b/project/.cproject @@ -24,7 +24,7 @@