1 /**
2  * @file lv_fs.h
3  *
4  */
5 
6 #ifndef LV_FS_H
7 #define LV_FS_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 
18 #if LV_USE_FILESYSTEM
19 
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include "lv_mem.h"
23 
24 /*********************
25  *      DEFINES
26  *********************/
27 #define LV_FS_MAX_FN_LENGTH 64
28 #define LV_FS_MAX_PATH_LENGTH 256
29 
30 /**********************
31  *      TYPEDEFS
32  **********************/
33 
34 /**
35  * Errors in the file system module.
36  */
37 enum {
38     LV_FS_RES_OK = 0,
39     LV_FS_RES_HW_ERR,     /*Low level hardware error*/
40     LV_FS_RES_FS_ERR,     /*Error in the file system structure */
41     LV_FS_RES_NOT_EX,     /*Driver, file or directory is not exists*/
42     LV_FS_RES_FULL,       /*Disk full*/
43     LV_FS_RES_LOCKED,     /*The file is already opened*/
44     LV_FS_RES_DENIED,     /*Access denied. Check 'fs_open' modes and write protect*/
45     LV_FS_RES_BUSY,       /*The file system now can't handle it, try later*/
46     LV_FS_RES_TOUT,       /*Process time outed*/
47     LV_FS_RES_NOT_IMP,    /*Requested function is not implemented*/
48     LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
49     LV_FS_RES_INV_PARAM,  /*Invalid parameter among arguments*/
50     LV_FS_RES_UNKNOWN,    /*Other unknown error*/
51 };
52 typedef uint8_t lv_fs_res_t;
53 
54 /**
55  * Filesystem mode.
56  */
57 enum {
58     LV_FS_MODE_WR = 0x01,
59     LV_FS_MODE_RD = 0x02,
60 };
61 typedef uint8_t lv_fs_mode_t;
62 
63 typedef struct _lv_fs_drv_t {
64     char letter;
65     uint16_t file_size;
66     uint16_t rddir_size;
67     bool (*ready_cb)(struct _lv_fs_drv_t * drv);
68 
69     lv_fs_res_t (*open_cb)(struct _lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
70     lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t * drv, void * file_p);
71     lv_fs_res_t (*remove_cb)(struct _lv_fs_drv_t * drv, const char * fn);
72     lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
73     lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
74     lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos);
75     lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
76     lv_fs_res_t (*trunc_cb)(struct _lv_fs_drv_t * drv, void * file_p);
77     lv_fs_res_t (*size_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * size_p);
78     lv_fs_res_t (*rename_cb)(struct _lv_fs_drv_t * drv, const char * oldname, const char * newname);
79     lv_fs_res_t (*free_space_cb)(struct _lv_fs_drv_t * drv, uint32_t * total_p, uint32_t * free_p);
80 
81     lv_fs_res_t (*dir_open_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, const char * path);
82     lv_fs_res_t (*dir_read_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, char * fn);
83     lv_fs_res_t (*dir_close_cb)(struct _lv_fs_drv_t * drv, void * rddir_p);
84 
85 #if LV_USE_USER_DATA
86     lv_fs_drv_user_data_t user_data; /**< Custom file user data */
87 #endif
88 } lv_fs_drv_t;
89 
90 typedef struct {
91     void * file_d;
92     lv_fs_drv_t * drv;
93 } lv_fs_file_t;
94 
95 typedef struct {
96     void * dir_d;
97     lv_fs_drv_t * drv;
98 } lv_fs_dir_t;
99 
100 /**********************
101  * GLOBAL PROTOTYPES
102  **********************/
103 
104 /**
105  * Initialize the File system interface
106  */
107 void _lv_fs_init(void);
108 
109 /**
110  * Initialize a file system driver with default values.
111  * It is used to surly have known values in the fields ant not memory junk.
112  * After it you can set the fields.
113  * @param drv pointer to driver variable to initialize
114  */
115 void lv_fs_drv_init(lv_fs_drv_t * drv);
116 
117 /**
118  * Add a new drive
119  * @param drv_p pointer to an lv_fs_drv_t structure which is inited with the
120  * corresponding function pointers. The data will be copied so the variable can be local.
121  */
122 void lv_fs_drv_register(lv_fs_drv_t * drv_p);
123 
124 /**
125  * Give a pointer to a driver from its letter
126  * @param letter the driver letter
127  * @return pointer to a driver or NULL if not found
128  */
129 lv_fs_drv_t * lv_fs_get_drv(char letter);
130 
131 /**
132  * Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
133  * returned.
134  * @param letter letter of the drive
135  * @return true: drive is ready; false: drive is not ready
136  */
137 bool lv_fs_is_ready(char letter);
138 
139 /**
140  * Open a file
141  * @param file_p pointer to a lv_fs_file_t variable
142  * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
143  * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
144  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
145  */
146 lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
147 
148 /**
149  * Close an already opened file
150  * @param file_p pointer to a lv_fs_file_t variable
151  * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum
152  */
153 lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);
154 
155 /**
156  * Delete a file
157  * @param path path of the file to delete
158  * @return  LV_FS_RES_OK or any error from lv_fs_res_t enum
159  */
160 lv_fs_res_t lv_fs_remove(const char * path);
161 
162 /**
163  * Read from a file
164  * @param file_p pointer to a lv_fs_file_t variable
165  * @param buf pointer to a buffer where the read bytes are stored
166  * @param btr Bytes To Read
167  * @param br the number of real read bytes (Bytes Read). NULL if unused.
168  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
169  */
170 lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
171 
172 /**
173  * Write into a file
174  * @param file_p pointer to a lv_fs_file_t variable
175  * @param buf pointer to a buffer with the bytes to write
176  * @param btr Bytes To Write
177  * @param br the number of real written bytes (Bytes Written). NULL if unused.
178  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
179  */
180 lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
181 
182 /**
183  * Set the position of the 'cursor' (read write pointer) in a file
184  * @param file_p pointer to a lv_fs_file_t variable
185  * @param pos the new position expressed in bytes index (0: start of file)
186  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
187  */
188 lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos);
189 
190 /**
191  * Give the position of the read write pointer
192  * @param file_p pointer to a lv_fs_file_t variable
193  * @param pos_p pointer to store the position of the read write pointer
194  * @return LV_FS_RES_OK or any error from 'fs_res_t'
195  */
196 lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);
197 
198 /**
199  * Truncate the file size to the current position of the read write pointer
200  * @param file_p pointer to an 'ufs_file_t' variable. (opened with lv_fs_open )
201  * @return LV_FS_RES_OK: no error, the file is read
202  *         any error from lv_fs_res_t enum
203  */
204 lv_fs_res_t lv_fs_trunc(lv_fs_file_t * file_p);
205 
206 /**
207  * Give the size of a file bytes
208  * @param file_p pointer to a lv_fs_file_t variable
209  * @param size pointer to a variable to store the size
210  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
211  */
212 lv_fs_res_t lv_fs_size(lv_fs_file_t * file_p, uint32_t * size);
213 
214 /**
215  * Rename a file
216  * @param oldname path to the file
217  * @param newname path with the new name
218  * @return LV_FS_RES_OK or any error from 'fs_res_t'
219  */
220 lv_fs_res_t lv_fs_rename(const char * oldname, const char * newname);
221 
222 /**
223  * Initialize a 'fs_dir_t' variable for directory reading
224  * @param rddir_p pointer to a 'fs_read_dir_t' variable
225  * @param path path to a directory
226  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
227  */
228 lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);
229 
230 /**
231  * Read the next filename form a directory.
232  * The name of the directories will begin with '/'
233  * @param rddir_p pointer to an initialized 'fs_rdir_t' variable
234  * @param fn pointer to a buffer to store the filename
235  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
236  */
237 lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn);
238 
239 /**
240  * Close the directory reading
241  * @param rddir_p pointer to an initialized 'fs_dir_t' variable
242  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
243  */
244 lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);
245 
246 /**
247  * Get the free and total size of a driver in kB
248  * @param letter the driver letter
249  * @param total_p pointer to store the total size [kB]
250  * @param free_p pointer to store the free size [kB]
251  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
252  */
253 lv_fs_res_t lv_fs_free_space(char letter, uint32_t * total_p, uint32_t * free_p);
254 
255 /**
256  * Fill a buffer with the letters of existing drivers
257  * @param buf buffer to store the letters ('\0' added after the last letter)
258  * @return the buffer
259  */
260 char * lv_fs_get_letters(char * buf);
261 
262 /**
263  * Return with the extension of the filename
264  * @param fn string with a filename
265  * @return pointer to the beginning extension or empty string if no extension
266  */
267 const char * lv_fs_get_ext(const char * fn);
268 
269 /**
270  * Step up one level
271  * @param path pointer to a file name
272  * @return the truncated file name
273  */
274 char * lv_fs_up(char * path);
275 
276 /**
277  * Get the last element of a path (e.g. U:/folder/file -> file)
278  * @param buf buffer to store the letters ('\0' added after the last letter)
279  * @return pointer to the beginning of the last element in the path
280  */
281 const char * lv_fs_get_last(const char * path);
282 
283 /**********************
284  *      MACROS
285  **********************/
286 
287 #endif /*LV_USE_FILESYSTEM*/
288 
289 #ifdef __cplusplus
290 } /* extern "C" */
291 #endif
292 
293 #endif /*LV_FS_H*/
294