acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

file-system.md (4763B)

      1 ```eval_rst
      2 .. include:: /header.rst
      3 :github_url: |github_link_base|/overview/file-system.md
      4 ```
      5 # File system
      6 
      7 LVGL has a 'File system' abstraction module that enables you to attach any type of file system.
      8 A file system is identified by an assigned drive letter.
      9 For example, if an SD card is associated with the letter `'S'`, a file can be reached using `"S:path/to/file.txt"`.
     10 
     11 ## Ready to use drivers
     12 The [lv_fs_if](https://github.com/lvgl/lv_fs_if) repository contains prepared drivers using POSIX, standard C and the [FATFS](http://elm-chan.org/fsw/ff/00index_e.html) API.
     13 See its [README](https://github.com/lvgl/lv_fs_if#readme) for the details.
     14 
     15 ## Adding a driver
     16 
     17 ### Registering a driver
     18 To add a driver, a `lv_fs_drv_t` needs to be initialized like below. The `lv_fs_drv_t` needs to be static, global or dynamically allocated and not a local variable.
     19 ```c
     20 static lv_fs_drv_t drv;                   /*Needs to be static or global*/
     21 lv_fs_drv_init(&drv);                     /*Basic initialization*/
     22 
     23 drv.letter = 'S';                         /*An uppercase letter to identify the drive */
     24 drv.cache_size = my_cache_size;           /*Cache size for reading in bytes. 0 to not cache.*/
     25 
     26 drv.ready_cb = my_ready_cb;               /*Callback to tell if the drive is ready to use */
     27 drv.open_cb = my_open_cb;                 /*Callback to open a file */
     28 drv.close_cb = my_close_cb;               /*Callback to close a file */
     29 drv.read_cb = my_read_cb;                 /*Callback to read a file */
     30 drv.write_cb = my_write_cb;               /*Callback to write a file */
     31 drv.seek_cb = my_seek_cb;                 /*Callback to seek in a file (Move cursor) */
     32 drv.tell_cb = my_tell_cb;                 /*Callback to tell the cursor position  */
     33 
     34 drv.dir_open_cb = my_dir_open_cb;         /*Callback to open directory to read its content */
     35 drv.dir_read_cb = my_dir_read_cb;         /*Callback to read a directory's content */
     36 drv.dir_close_cb = my_dir_close_cb;       /*Callback to close a directory */
     37 
     38 drv.user_data = my_user_data;             /*Any custom data if required*/
     39 
     40 lv_fs_drv_register(&drv);                 /*Finally register the drive*/
     41 
     42 ```
     43 
     44 Any of the callbacks can be `NULL` to indicate that operation is not supported.
     45 
     46 
     47 ### Implementing the callbacks
     48 
     49 #### Open callback
     50 The prototype of `open_cb` looks like this:
     51 ```c
     52 void * (*open_cb)(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
     53 ```
     54 
     55 `path` is the path after the drive letter (e.g. "S:path/to/file.txt" -> "path/to/file.txt"). `mode` can be `LV_FS_MODE_WR` or `LV_FS_MODE_RD` to open for writes or reads.
     56 
     57 The return value is a pointer to a *file object* that describes the opened file or `NULL` if there were any issues (e.g. the file wasn't found).
     58 The returned file object will be passed to other file system related callbacks. (see below)
     59 
     60 ### Other callbacks
     61 The other callbacks are quite similar. For example `write_cb` looks like this:
     62 ```c
     63 lv_fs_res_t (*write_cb)(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
     64 ```
     65 
     66 For `file_p`, LVGL passes the return value of `open_cb`, `buf` is the data to write, `btw` is the Bytes To Write, `bw` is the actually written bytes.
     67 
     68 For a template of these callbacks see [lv_fs_template.c](https://github.com/lvgl/lvgl/blob/master/examples/porting/lv_port_fs_template.c).
     69 
     70 
     71 ## Usage example
     72 
     73 The example below shows how to read from a file:
     74 ```c
     75 lv_fs_file_t f;
     76 lv_fs_res_t res;
     77 res = lv_fs_open(&f, "S:folder/file.txt", LV_FS_MODE_RD);
     78 if(res != LV_FS_RES_OK) my_error_handling();
     79 
     80 uint32_t read_num;
     81 uint8_t buf[8];
     82 res = lv_fs_read(&f, buf, 8, &read_num);
     83 if(res != LV_FS_RES_OK || read_num != 8) my_error_handling();
     84 
     85 lv_fs_close(&f);
     86 ```
     87 *The mode in `lv_fs_open` can be `LV_FS_MODE_WR` to open for writes only or `LV_FS_MODE_RD | LV_FS_MODE_WR` for both*
     88 
     89 This example shows how to read a directory's content. It's up to the driver how to mark directories in the result but it can be a good practice to insert a `'/'` in front of each directory name.
     90 ```c
     91 lv_fs_dir_t dir;
     92 lv_fs_res_t res;
     93 res = lv_fs_dir_open(&dir, "S:/folder");
     94 if(res != LV_FS_RES_OK) my_error_handling();
     95 
     96 char fn[256];
     97 while(1) {
     98     res = lv_fs_dir_read(&dir, fn);
     99     if(res != LV_FS_RES_OK) {
    100         my_error_handling();
    101         break;
    102     }
    103 
    104     /*fn is empty, if not more files to read*/
    105     if(strlen(fn) == 0) {
    106         break;
    107     }
    108 
    109     printf("%s\n", fn);
    110 }
    111 
    112 lv_fs_dir_close(&dir);
    113 ```
    114 
    115 ## Use drives for images
    116 
    117 [Image](/widgets/core/img) objects can be opened from files too (besides variables stored in the compiled program).
    118 
    119 To use files in image widgets the following callbacks are required:
    120 - open
    121 - close
    122 - read
    123 - seek
    124 - tell
    125 
    126 
    127 
    128 ## API
    129 
    130 ```eval_rst
    131 
    132 .. doxygenfile:: lv_fs.h
    133   :project: lvgl
    134 
    135 ```