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