1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
/**
* @file lv_fs_memfs.c
*
* File System Interface driver for memory-mapped files
*
* This driver allows using a memory area as a file that can be read by normal file operations. It can
* be used, e.g., to store font files in slow flash memory, and load them into RAM on demand.
*
* You can enable it in lv_conf.h:
*
* #define LV_USE_FS_MEMFS 1
*
* The actual implementation uses the built-in cache mechanism of the file system interface.
*
* Since this is not an actual file system, file write and directories are not supported.
*
* The default drive letter is 'M', but this can be changed in lv_conf.h:
*
* #define LV_FS_MEMFS_LETTER 'M'
*
* To use it seamlessly with the file system interface a new extended path object has been introduced:
*
* lv_fs_path_ex_t mempath;
*
* This structure can be initialized with the helper function:
*
* lv_fs_make_path_ex(&mempath, (const uint8_t *) & my_mem_buffer, sizeof(my_mem_buffer));
*
* Then the "file" can be opened with:
*
* lv_fs_file_t file;
* lv_fs_res_t res = lv_fs_open(&file, (const char *) & mempath, LV_FS_MODE_RD);
*
* The path object can be used at any place where a file path is required, e.g.:
*
* lv_font_t* my_font = lv_binfont_create((const char *) & mempath);
*
*/
/*********************
* INCLUDES
*********************/
#include "../../../lvgl.h"
#if LV_USE_FS_MEMFS
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
/**********************
* STATIC VARIABLES
**********************/
static lv_fs_drv_t fs_drv; /*A driver descriptor*/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Register a driver for the File system interface
*/
void lv_fs_memfs_init(void)
{
/*---------------------------------------------------
* Register the file system interface in LVGL
*--------------------------------------------------*/
lv_fs_drv_init(&fs_drv);
/*Set up fields...*/
fs_drv.letter = LV_FS_MEMFS_LETTER;
fs_drv.cache_size = LV_FS_CACHE_FROM_BUFFER;
fs_drv.open_cb = fs_open;
fs_drv.close_cb = fs_close;
fs_drv.read_cb = fs_read;
fs_drv.write_cb = NULL;
fs_drv.seek_cb = fs_seek;
fs_drv.tell_cb = fs_tell;
fs_drv.dir_close_cb = NULL;
fs_drv.dir_open_cb = NULL;
fs_drv.dir_read_cb = NULL;
lv_fs_drv_register(&fs_drv);
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Open a file
* @param drv pointer to a driver where this function belongs
* @param path pointer to an extended path object containing the memory buffer address and size
* @param mode read: FS_MODE_RD (currently only reading from the buffer is supported)
* @return pointer to FIL struct or NULL in case of fail
*/
static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
{
LV_UNUSED(drv);
LV_UNUSED(mode);
return (void *)path;
}
/**
* Close an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a FILE variable. (opened with fs_open)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
{
LV_UNUSED(drv);
LV_UNUSED(file_p);
return LV_FS_RES_OK;
}
/**
* Read data from an opened file
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a FILE variable.
* @param buf pointer to a memory block where to store the read data
* @param btr number of Bytes To Read
* @param br the real number of read bytes (Byte Read)
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
{
LV_UNUSED(drv);
LV_UNUSED(file_p);
LV_UNUSED(buf);
LV_UNUSED(btr);
*br = 0;
return LV_FS_RES_OK;
}
/**
* Set the read pointer.
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a FILE variable. (opened with fs_open )
* @param pos the new position of read pointer
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
{
/* NOTE: this function is only called to determine the end of the buffer when LV_FS_SEEK_END was given to lv_fs_seek() */
LV_UNUSED(drv);
lv_fs_file_t * fp = (lv_fs_file_t *)file_p;
switch(whence) {
case LV_FS_SEEK_SET: {
fp->cache->file_position = pos;
break;
}
case LV_FS_SEEK_CUR: {
fp->cache->file_position += pos;
break;
}
case LV_FS_SEEK_END: {
fp->cache->file_position = fp->cache->end - pos;
break;
}
}
if(fp->cache->file_position < fp->cache->start)
fp->cache->file_position = fp->cache->start;
else if(fp->cache->file_position > fp->cache->end)
fp->cache->file_position = fp->cache->end;
return LV_FS_RES_OK;
}
/**
* Give the position of the read write pointer
* @param drv pointer to a driver where this function belongs
* @param file_p pointer to a FILE variable
* @param pos_p pointer to store the result
* @return LV_FS_RES_OK: no error, the file is read
* any error from lv_fs_res_t enum
*/
static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
{
LV_UNUSED(drv);
*pos_p = ((lv_fs_file_t *)file_p)->cache->file_position;
return LV_FS_RES_OK;
}
#else /*LV_USE_FS_MEMFS == 0*/
#if defined(LV_FS_MEMFS_LETTER) && LV_FS_MEMFS_LETTER != '\0'
#warning "LV_USE_FS_MEMFS is not enabled but LV_FS_MEMFS_LETTER is set"
#endif
#endif /*LV_USE_FS_MEMFS*/
|