mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
feat(fs): file writes update the file cache (#6186)
Co-authored-by: kevinkang-Globe <139213362+kevinkang-Globe@users.noreply.github.com>
This commit is contained in:
parent
e3f70a2987
commit
4e85b0faa5
@ -42,7 +42,8 @@ extensions = [
|
||||
'sphinx_sitemap',
|
||||
'lv_example',
|
||||
'sphinx_rtd_dark_mode',
|
||||
'link_roles'
|
||||
'link_roles',
|
||||
'sphinxcontrib.mermaid'
|
||||
]
|
||||
|
||||
default_dark_mode = False
|
||||
|
@ -34,7 +34,7 @@ The work directory can be set with ``LV_FS_..._PATH``. E.g.
|
||||
``"/home/joe/projects/"`` The actual file/directory paths will be
|
||||
appended to it.
|
||||
|
||||
Cached reading is also supported if ``LV_FS_..._CACHE_SIZE`` is set to
|
||||
:ref:`Cached reading <overview_file_system_cache>` is also supported if ``LV_FS_..._CACHE_SIZE`` is set to
|
||||
not ``0`` value. :cpp:func:`lv_fs_read` caches this size of data to lower the
|
||||
number of actual reads from the storage.
|
||||
|
||||
|
@ -155,6 +155,95 @@ To use files in image widgets the following callbacks are required:
|
||||
- seek
|
||||
- tell
|
||||
|
||||
.. _overview_file_system_cache:
|
||||
|
||||
Optional file buffering/caching
|
||||
*******************************
|
||||
|
||||
Files will buffer their reads if the corresponding ``LV_FS_*_CACHE_SIZE``
|
||||
config option is set to a value greater than zero. Each open file will
|
||||
buffer up to that many bytes to reduce the number of FS driver calls.
|
||||
|
||||
Generally speaking, file buffering can be optimized for different kinds
|
||||
of access patterns. The one implemented here is optimal for reading large
|
||||
files in chunks, which is what the image decoder does.
|
||||
It has the potential to call the driver's ``read`` fewer
|
||||
times than ``lv_fs_read`` is called. In the best case where the cache size is
|
||||
\>= the size of the file, ``read`` will only be called once. This strategy is good
|
||||
for linear reading of large files but less helpful for short random reads across a file bigger than the buffer
|
||||
since data will be buffered that will be discarded after the next seek and read.
|
||||
The cache should be sufficiently large or disabled in that case. Another case where the cache should be disabled
|
||||
is if the file contents are expected to change by an external factor like with special OS files.
|
||||
|
||||
The implementation is documented below. Note that the FS functions make calls
|
||||
to other driver FS functions when the cache is enabled. i.e., ``lv_fs_read`` may call the driver's ``seek``
|
||||
so the driver needs to implement more callbacks when the cache is enabled.
|
||||
|
||||
``lv_fs_read`` :sub:`(behavior when the cache is enabled)`
|
||||
-------------------------------------------------
|
||||
|
||||
.. mermaid::
|
||||
:zoom:
|
||||
|
||||
%%{init: {'theme':'neutral'}}%%
|
||||
flowchart LR
|
||||
A["call lv_fs_read and
|
||||
the cache is enabled"] --> B{{"is there cached data
|
||||
at the file position?"}}
|
||||
B -->|yes| C{{"does the cache have
|
||||
all required bytes available?"}}
|
||||
C -->|yes| D["copy all required bytes from
|
||||
the cache to the destination
|
||||
buffer"]
|
||||
C -->|no| F["copy the available
|
||||
required bytes
|
||||
until the end of the cache
|
||||
into the destination buffer"]
|
||||
--> G["seek the real file to the end
|
||||
of what the cache had available"]
|
||||
--> H{{"is the number of remaining bytes
|
||||
larger than the size of the whole cache?"}}
|
||||
H -->|yes| I["read the remaining bytes
|
||||
from the real file to the
|
||||
destination buffer"]
|
||||
H -->|no| J["eagerly read the real file
|
||||
to fill the whole cache
|
||||
or as many bytes as the
|
||||
read call can"]
|
||||
--> O["copy the required bytes
|
||||
to the destination buffer"]
|
||||
B -->|no| K["seek the real file to
|
||||
the file position"]
|
||||
--> L{{"is the number of required
|
||||
bytes greater than the
|
||||
size of the entire cache?"}}
|
||||
L -->|yes| M["read the real file to
|
||||
the destination buffer"]
|
||||
L -->|no| N["eagerly read the real file
|
||||
to fill the whole cache
|
||||
or as many bytes as the
|
||||
read call can"]
|
||||
--> P["copy the required bytes
|
||||
to the destination buffer"]
|
||||
|
||||
``lv_fs_write`` :sub:`(behavior when the cache is enabled)`
|
||||
--------------------------------------------------
|
||||
|
||||
The part of the cache that coincides with the written content
|
||||
will be updated to reflect the written content.
|
||||
|
||||
``lv_fs_seek`` :sub:`(behavior when the cache is enabled)`
|
||||
-------------------------------------------------
|
||||
|
||||
The driver's ``seek`` will not actually be called unless the ``whence``
|
||||
is ``LV_FS_SEEK_END``, in which case ``seek`` and ``tell`` will be called
|
||||
to determine where the end of the file is.
|
||||
|
||||
``lv_fs_tell`` :sub:`(behavior when the cache is enabled)`
|
||||
-------------------------------------------------
|
||||
|
||||
The driver's ``tell`` will not actually be called.
|
||||
|
||||
.. _overview_file_system_api:
|
||||
|
||||
API
|
||||
|
@ -10,5 +10,6 @@ sphinxcontrib-htmlhelp
|
||||
sphinxcontrib-jsmath
|
||||
sphinxcontrib-qthelp
|
||||
sphinxcontrib-serializinghtml
|
||||
sphinxcontrib-mermaid
|
||||
sphinx-rtd-dark-mode
|
||||
typing-extensions
|
||||
|
337
src/misc/lv_fs.c
337
src/misc/lv_fs.c
@ -27,6 +27,9 @@
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static const char * lv_fs_get_real_path(const char * path);
|
||||
static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
|
||||
static lv_fs_res_t lv_fs_write_cached(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
|
||||
static lv_fs_res_t lv_fs_seek_cached(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -171,100 +174,17 @@ lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p)
|
||||
return res;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, char * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
uint32_t file_position = file_p->cache->file_position;
|
||||
uint32_t start = file_p->cache->start;
|
||||
uint32_t end = file_p->cache->end;
|
||||
char * buffer = file_p->cache->buffer;
|
||||
uint32_t buffer_size = file_p->drv->cache_size;
|
||||
|
||||
if(start <= file_position && file_position <= end) {
|
||||
/* Data can be read from cache buffer */
|
||||
uint32_t buffer_remaining_length = (uint32_t)end - file_position + 1;
|
||||
uint32_t buffer_offset = (end - start) - buffer_remaining_length + 1;
|
||||
|
||||
/* Do not allow reading beyond the actual memory block for memory-mapped files */
|
||||
if(file_p->drv->cache_size == LV_FS_CACHE_FROM_BUFFER) {
|
||||
if(btr > buffer_remaining_length)
|
||||
btr = buffer_remaining_length - 1;
|
||||
}
|
||||
|
||||
if(btr <= buffer_remaining_length) {
|
||||
/*Data is in cache buffer, and buffer end not reached, no need to read from FS*/
|
||||
lv_memcpy(buf, buffer + buffer_offset, btr);
|
||||
*br = btr;
|
||||
}
|
||||
else {
|
||||
/*First part of data is in cache buffer, but we need to read rest of data from FS*/
|
||||
lv_memcpy(buf, buffer + buffer_offset, buffer_remaining_length);
|
||||
|
||||
file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->end + 1,
|
||||
LV_FS_SEEK_SET);
|
||||
|
||||
uint32_t bytes_read_to_buffer = 0;
|
||||
if(btr - buffer_remaining_length > buffer_size) {
|
||||
/*If remaining data chuck is bigger than buffer size, then do not use cache, instead read it directly from FS*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)(buf + buffer_remaining_length),
|
||||
btr - buffer_remaining_length, &bytes_read_to_buffer);
|
||||
}
|
||||
else {
|
||||
/*If remaining data chunk is smaller than buffer size, then read into cache buffer*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer);
|
||||
file_p->cache->start = file_p->cache->end + 1;
|
||||
file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1;
|
||||
|
||||
uint16_t data_chunk_remaining = LV_MIN(btr - buffer_remaining_length, bytes_read_to_buffer);
|
||||
lv_memcpy(buf + buffer_remaining_length, buffer, data_chunk_remaining);
|
||||
}
|
||||
*br = LV_MIN(buffer_remaining_length + bytes_read_to_buffer, btr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position,
|
||||
LV_FS_SEEK_SET);
|
||||
|
||||
/*Data is not in cache buffer*/
|
||||
if(btr > buffer_size) {
|
||||
/*If bigger data is requested, then do not use cache, instead read it directly*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buf, btr, br);
|
||||
}
|
||||
else {
|
||||
/*If small data is requested, then read from FS into cache buffer*/
|
||||
if(buffer == NULL) {
|
||||
file_p->cache->buffer = lv_malloc(buffer_size);
|
||||
LV_ASSERT_MALLOC(file_p->cache->buffer);
|
||||
buffer = file_p->cache->buffer;
|
||||
}
|
||||
|
||||
uint32_t bytes_read_to_buffer = 0;
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer);
|
||||
file_p->cache->start = file_position;
|
||||
file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1;
|
||||
|
||||
*br = LV_MIN(btr, bytes_read_to_buffer);
|
||||
lv_memcpy(buf, buffer, *br);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(res == LV_FS_RES_OK) {
|
||||
file_p->cache->file_position += *br;
|
||||
}
|
||||
|
||||
LV_PROFILER_END;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
if(br != NULL) *br = 0;
|
||||
if(file_p->drv == NULL) return LV_FS_RES_INV_PARAM;
|
||||
if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
|
||||
if(file_p->drv->cache_size) {
|
||||
if(file_p->drv->read_cb == NULL || file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
else {
|
||||
if(file_p->drv->read_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
@ -272,7 +192,7 @@ lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t
|
||||
lv_fs_res_t res;
|
||||
|
||||
if(file_p->drv->cache_size) {
|
||||
res = lv_fs_read_cached(file_p, (char *)buf, btr, &br_tmp);
|
||||
res = lv_fs_read_cached(file_p, buf, btr, &br_tmp);
|
||||
}
|
||||
else {
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, buf, btr, &br_tmp);
|
||||
@ -293,30 +213,25 @@ lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, u
|
||||
return LV_FS_RES_INV_PARAM;
|
||||
}
|
||||
|
||||
if(file_p->drv->write_cb == NULL) {
|
||||
return LV_FS_RES_NOT_IMP;
|
||||
if(file_p->drv->cache_size) {
|
||||
if(file_p->drv->write_cb == NULL || file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
else {
|
||||
if(file_p->drv->write_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
|
||||
/*Need to do FS seek before writing data to FS*/
|
||||
if(file_p->drv->cache_size) {
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET);
|
||||
if(res != LV_FS_RES_OK) {
|
||||
LV_PROFILER_END;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
lv_fs_res_t res;
|
||||
uint32_t bw_tmp = 0;
|
||||
res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, &bw_tmp);
|
||||
if(file_p->drv->cache_size) {
|
||||
res = lv_fs_write_cached(file_p, buf, btw, &bw_tmp);
|
||||
}
|
||||
else {
|
||||
res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, &bw_tmp);
|
||||
}
|
||||
if(bw != NULL) *bw = bw_tmp;
|
||||
|
||||
if(file_p->drv->cache_size && res == LV_FS_RES_OK)
|
||||
file_p->cache->file_position += bw_tmp;
|
||||
|
||||
LV_PROFILER_END;
|
||||
|
||||
return res;
|
||||
@ -328,49 +243,18 @@ lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whenc
|
||||
return LV_FS_RES_INV_PARAM;
|
||||
}
|
||||
|
||||
if(file_p->drv->seek_cb == NULL) {
|
||||
return LV_FS_RES_NOT_IMP;
|
||||
if(file_p->drv->cache_size) {
|
||||
if(file_p->drv->seek_cb == NULL || file_p->drv->tell_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
else {
|
||||
if(file_p->drv->seek_cb == NULL) return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
|
||||
LV_PROFILER_BEGIN;
|
||||
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
lv_fs_res_t res;
|
||||
if(file_p->drv->cache_size) {
|
||||
switch(whence) {
|
||||
case LV_FS_SEEK_SET: {
|
||||
file_p->cache->file_position = pos;
|
||||
|
||||
/*FS seek if new position is outside cache buffer*/
|
||||
if(file_p->cache->file_position < file_p->cache->start || file_p->cache->file_position > file_p->cache->end) {
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_CUR: {
|
||||
file_p->cache->file_position += pos;
|
||||
|
||||
/*FS seek if new position is outside cache buffer*/
|
||||
if(file_p->cache->file_position < file_p->cache->start || file_p->cache->file_position > file_p->cache->end) {
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_END: {
|
||||
/*Because we don't know the file size, we do a little trick: do a FS seek, then get the new file position from FS*/
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
uint32_t tmp_position;
|
||||
res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, &tmp_position);
|
||||
|
||||
if(res == LV_FS_RES_OK) {
|
||||
file_p->cache->file_position = tmp_position;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
res = lv_fs_seek_cached(file_p, pos, whence);
|
||||
}
|
||||
else {
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence);
|
||||
@ -388,7 +272,7 @@ lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos)
|
||||
return LV_FS_RES_INV_PARAM;
|
||||
}
|
||||
|
||||
if(file_p->drv->tell_cb == NULL) {
|
||||
if(file_p->drv->cache_size == 0 && file_p->drv->tell_cb == NULL) {
|
||||
*pos = 0;
|
||||
return LV_FS_RES_NOT_IMP;
|
||||
}
|
||||
@ -621,3 +505,162 @@ static const char * lv_fs_get_real_path(const char * path)
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lv_fs_read_cached(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
uint32_t file_position = file_p->cache->file_position;
|
||||
uint32_t start = file_p->cache->start;
|
||||
uint32_t end = file_p->cache->end;
|
||||
char * buffer = file_p->cache->buffer;
|
||||
uint32_t buffer_size = file_p->drv->cache_size;
|
||||
|
||||
if(start <= file_position && file_position <= end) {
|
||||
/* Data can be read from cache buffer */
|
||||
uint32_t buffer_remaining_length = (uint32_t)end - file_position + 1;
|
||||
uint32_t buffer_offset = (end - start) - buffer_remaining_length + 1;
|
||||
|
||||
/* Do not allow reading beyond the actual memory block for memory-mapped files */
|
||||
if(file_p->drv->cache_size == LV_FS_CACHE_FROM_BUFFER) {
|
||||
if(btr > buffer_remaining_length)
|
||||
btr = buffer_remaining_length - 1;
|
||||
}
|
||||
|
||||
if(btr <= buffer_remaining_length) {
|
||||
/*Data is in cache buffer, and buffer end not reached, no need to read from FS*/
|
||||
lv_memcpy(buf, buffer + buffer_offset, btr);
|
||||
*br = btr;
|
||||
}
|
||||
else {
|
||||
/*First part of data is in cache buffer, but we need to read rest of data from FS*/
|
||||
lv_memcpy(buf, buffer + buffer_offset, buffer_remaining_length);
|
||||
|
||||
file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->end + 1,
|
||||
LV_FS_SEEK_SET);
|
||||
|
||||
uint32_t bytes_read_to_buffer = 0;
|
||||
if(btr - buffer_remaining_length > buffer_size) {
|
||||
/*If remaining data chuck is bigger than buffer size, then do not use cache, instead read it directly from FS*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (char *)buf + buffer_remaining_length,
|
||||
btr - buffer_remaining_length, &bytes_read_to_buffer);
|
||||
}
|
||||
else {
|
||||
/*If remaining data chunk is smaller than buffer size, then read into cache buffer*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, buffer, buffer_size, &bytes_read_to_buffer);
|
||||
file_p->cache->start = file_p->cache->end + 1;
|
||||
file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1;
|
||||
|
||||
uint16_t data_chunk_remaining = LV_MIN(btr - buffer_remaining_length, bytes_read_to_buffer);
|
||||
lv_memcpy((char *)buf + buffer_remaining_length, buffer, data_chunk_remaining);
|
||||
}
|
||||
*br = LV_MIN(buffer_remaining_length + bytes_read_to_buffer, btr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position,
|
||||
LV_FS_SEEK_SET);
|
||||
|
||||
/*Data is not in cache buffer*/
|
||||
if(btr > buffer_size) {
|
||||
/*If bigger data is requested, then do not use cache, instead read it directly*/
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buf, btr, br);
|
||||
}
|
||||
else {
|
||||
/*If small data is requested, then read from FS into cache buffer*/
|
||||
if(buffer == NULL) {
|
||||
file_p->cache->buffer = lv_malloc(buffer_size);
|
||||
LV_ASSERT_MALLOC(file_p->cache->buffer);
|
||||
buffer = file_p->cache->buffer;
|
||||
}
|
||||
|
||||
uint32_t bytes_read_to_buffer = 0;
|
||||
res = file_p->drv->read_cb(file_p->drv, file_p->file_d, (void *)buffer, buffer_size, &bytes_read_to_buffer);
|
||||
file_p->cache->start = file_position;
|
||||
file_p->cache->end = file_p->cache->start + bytes_read_to_buffer - 1;
|
||||
|
||||
*br = LV_MIN(btr, bytes_read_to_buffer);
|
||||
lv_memcpy(buf, buffer, *br);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(res == LV_FS_RES_OK) {
|
||||
file_p->cache->file_position += *br;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lv_fs_write_cached(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
|
||||
/*Need to do FS seek before writing data to FS*/
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, file_p->cache->file_position, LV_FS_SEEK_SET);
|
||||
if(res != LV_FS_RES_OK) return res;
|
||||
|
||||
res = file_p->drv->write_cb(file_p->drv, file_p->file_d, buf, btw, bw);
|
||||
if(res != LV_FS_RES_OK) return res;
|
||||
|
||||
if(file_p->cache->end >= file_p->cache->start) {
|
||||
uint32_t start_position = file_p->cache->file_position;
|
||||
uint32_t end_position = file_p->cache->file_position + *bw - 1;
|
||||
char * cache_buffer = file_p->cache->buffer;
|
||||
const char * write_buffer = buf;
|
||||
|
||||
if(start_position <= file_p->cache->start && end_position >= file_p->cache->end) {
|
||||
lv_memcpy(cache_buffer,
|
||||
write_buffer + (file_p->cache->start - start_position),
|
||||
file_p->cache->end + 1 - file_p->cache->start);
|
||||
}
|
||||
else if(start_position >= file_p->cache->start && end_position <= file_p->cache->end) {
|
||||
lv_memcpy(cache_buffer + (start_position - file_p->cache->start),
|
||||
write_buffer,
|
||||
end_position + 1 - start_position);
|
||||
}
|
||||
else if(end_position >= file_p->cache->start && end_position <= file_p->cache->end) {
|
||||
lv_memcpy(cache_buffer,
|
||||
write_buffer + (file_p->cache->start - start_position),
|
||||
end_position + 1 - file_p->cache->start);
|
||||
}
|
||||
else if(start_position >= file_p->cache->start && start_position <= file_p->cache->end) {
|
||||
lv_memcpy(cache_buffer + (start_position - file_p->cache->start),
|
||||
write_buffer,
|
||||
file_p->cache->end + 1 - start_position);
|
||||
}
|
||||
}
|
||||
|
||||
file_p->cache->file_position += *bw;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static lv_fs_res_t lv_fs_seek_cached(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence)
|
||||
{
|
||||
lv_fs_res_t res = LV_FS_RES_OK;
|
||||
switch(whence) {
|
||||
case LV_FS_SEEK_SET: {
|
||||
file_p->cache->file_position = pos;
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_CUR: {
|
||||
file_p->cache->file_position += pos;
|
||||
break;
|
||||
}
|
||||
case LV_FS_SEEK_END: {
|
||||
/*Because we don't know the file size, we do a little trick: do a FS seek, then get the new file position from FS*/
|
||||
res = file_p->drv->seek_cb(file_p->drv, file_p->file_d, pos, whence);
|
||||
if(res == LV_FS_RES_OK) {
|
||||
uint32_t tmp_position;
|
||||
res = file_p->drv->tell_cb(file_p->drv, file_p->file_d, &tmp_position);
|
||||
|
||||
if(res == LV_FS_RES_OK) {
|
||||
file_p->cache->file_position = tmp_position;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -178,4 +178,99 @@ static void read_random_drv(char drv_letter, uint32_t cache_size)
|
||||
drv->cache_size = original_cache_size;
|
||||
}
|
||||
|
||||
void test_write_read_random(void)
|
||||
{
|
||||
lv_fs_drv_t * drv = lv_fs_get_drv('A');
|
||||
uint32_t original_cache_size = drv->cache_size;
|
||||
drv->cache_size = 7;
|
||||
|
||||
/* create the file and reopen for read+write. stdio "rb+" mode requires the file to exist */
|
||||
lv_fs_res_t res;
|
||||
lv_fs_file_t f;
|
||||
res = lv_fs_open(&f, "A:fs_write_read_random.bin", LV_FS_MODE_WR);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
res = lv_fs_close(&f);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
res = lv_fs_open(&f, "A:fs_write_read_random.bin", LV_FS_MODE_WR | LV_FS_MODE_RD);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
|
||||
uint8_t buf1000[1000];
|
||||
for(uint32_t i = 0; i < 1000; i++) buf1000[i] = i;
|
||||
res = lv_fs_write(&f, buf1000, 1000, NULL);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
|
||||
/**
|
||||
* {{{action, amount}, ... x20 actions per combo}, ... x100 combos}
|
||||
* actions are read (0), write (1), seek (2)
|
||||
* read and write amount ranges from 1 to 20. seek amount ranges from -20 to 20.
|
||||
* seeks occur as frequently as reads+writes combined.
|
||||
*/
|
||||
// *INDENT-OFF*
|
||||
static const int8_t actions[100][20][2] = {
|
||||
{{2, -20}, {2, 17}, {0, 20}, {2, 19}, {1, 18}, {1, 4}, {1, 13}, {2, -7}, {1, 6}, {1, 19}, {2, 3}, {1, 12}, {2, 12}, {2, -2}, {2, -20}, {2, -17}, {1, 15}, {2, -17}, {0, 18}, {2, 14}}, {{2, 19}, {2, 17}, {2, -12}, {2, -5}, {2, -1}, {2, -17}, {1, 4}, {2, 19}, {2, 3}, {2, 1}, {2, 10}, {2, 18}, {0, 10}, {2, 8}, {2, 17}, {2, 20}, {0, 5}, {0, 14}, {0, 6}, {1, 8}}, {{0, 1}, {2, -20}, {2, -12}, {1, 9}, {0, 9}, {2, 19}, {1, 8}, {0, 13}, {0, 5}, {2, -7}, {2, -14}, {0, 8}, {2, 13}, {1, 5}, {0, 3}, {0, 16}, {2, 19}, {0, 4}, {1, 6}, {2, -4}}, {{0, 1}, {2, 12}, {1, 7}, {1, 17}, {1, 19}, {0, 8}, {1, 1}, {2, 9}, {2, -14}, {2, 14}, {2, -17}, {2, 11}, {1, 4}, {2, 19}, {2, -18}, {1, 12}, {2, -14}, {0, 9}, {1, 7}, {2, 17}}, {{2, -6}, {0, 13}, {1, 15}, {1, 8}, {2, -1}, {2, 15}, {2, 3}, {2, -16}, {2, -11}, {2, 14}, {2, -19}, {2, 6}, {1, 10}, {1, 6}, {1, 12}, {2, 12}, {0, 10}, {2, 10}, {2, -4}, {2, 5}}, {{2, -6}, {1, 2}, {1, 11}, {1, 19}, {2, 2}, {2, 20}, {2, -19}, {2, -7}, {0, 13}, {2, 4}, {1, 6}, {0, 9}, {0, 6}, {2, -1}, {2, -5}, {2, 14}, {2, 15}, {0, 4}, {0, 6}, {0, 10}}, {{1, 17}, {1, 17}, {0, 15}, {0, 3}, {1, 8}, {2, -9}, {1, 13}, {0, 20}, {0, 3}, {1, 17}, {2, -8}, {2, -1}, {1, 13}, {0, 13}, {0, 8}, {1, 1}, {2, -4}, {2, 13}, {2, 17}, {2, -14}}, {{1, 17}, {1, 13}, {1, 17}, {1, 5}, {1, 3}, {0, 20}, {2, 12}, {0, 13}, {2, 5}, {2, -10}, {2, 10}, {0, 6}, {2, 18}, {0, 17}, {2, 2}, {1, 5}, {2, 16}, {2, -10}, {0, 2}, {2, -9}}, {{2, 7}, {2, -2}, {1, 14}, {0, 15}, {1, 2}, {2, 6}, {2, 11}, {1, 2}, {0, 12}, {2, 9}, {0, 17}, {0, 15}, {2, -19}, {0, 11}, {2, 3}, {2, 15}, {2, 19}, {2, -16}, {1, 6}, {1, 15}}, {{2, 12}, {1, 2}, {2, -4}, {2, -20}, {0, 18}, {2, -16}, {1, 15}, {2, -9}, {2, -7}, {1, 1}, {0, 7}, {0, 18}, {1, 18}, {0, 2}, {2, 17}, {1, 2}, {1, 8}, {1, 18}, {2, -7}, {0, 2}},
|
||||
{{2, 19}, {2, 17}, {2, -7}, {0, 17}, {0, 18}, {1, 4}, {1, 1}, {0, 3}, {2, 4}, {2, -4}, {1, 20}, {0, 1}, {2, 20}, {0, 6}, {2, 10}, {0, 19}, {2, -1}, {0, 7}, {0, 16}, {1, 13}}, {{2, 10}, {2, 13}, {2, 15}, {2, 3}, {2, 12}, {0, 14}, {2, 6}, {2, 14}, {2, -13}, {2, 18}, {0, 19}, {2, -8}, {2, -9}, {0, 12}, {2, -20}, {2, -6}, {2, 15}, {2, 18}, {1, 18}, {1, 10}}, {{0, 15}, {2, -6}, {2, 17}, {1, 7}, {0, 9}, {0, 11}, {0, 12}, {0, 20}, {2, -1}, {2, -8}, {0, 13}, {2, 19}, {1, 3}, {0, 18}, {1, 13}, {2, 12}, {2, 13}, {1, 5}, {2, -14}, {2, 18}}, {{0, 6}, {1, 4}, {1, 6}, {0, 2}, {2, 8}, {1, 9}, {2, 20}, {0, 9}, {2, -1}, {2, 5}, {0, 18}, {2, 8}, {2, 12}, {2, -14}, {0, 18}, {1, 1}, {2, -15}, {2, 14}, {2, -11}, {2, -2}}, {{1, 4}, {2, 6}, {2, 18}, {1, 19}, {0, 18}, {0, 19}, {0, 14}, {0, 12}, {2, 3}, {0, 19}, {2, -20}, {0, 8}, {2, -15}, {2, -15}, {0, 8}, {1, 17}, {2, 2}, {1, 14}, {0, 11}, {0, 13}}, {{2, -10}, {2, -8}, {1, 18}, {1, 11}, {1, 5}, {0, 2}, {2, -19}, {2, -9}, {1, 5}, {2, -1}, {2, 2}, {1, 5}, {0, 9}, {0, 17}, {2, 2}, {0, 10}, {1, 12}, {1, 10}, {0, 8}, {2, -13}}, {{0, 13}, {1, 5}, {2, -1}, {2, -16}, {2, 2}, {0, 6}, {2, -11}, {0, 5}, {2, 5}, {2, -6}, {2, -6}, {1, 19}, {0, 8}, {2, -16}, {2, 14}, {0, 11}, {0, 14}, {0, 18}, {0, 14}, {2, 1}}, {{2, 3}, {2, -2}, {0, 10}, {1, 1}, {0, 10}, {2, -15}, {2, 19}, {2, 2}, {1, 15}, {1, 10}, {2, -18}, {0, 20}, {0, 10}, {2, 3}, {1, 13}, {0, 8}, {0, 16}, {0, 14}, {2, 13}, {2, -7}}, {{0, 4}, {1, 7}, {0, 2}, {0, 15}, {0, 20}, {1, 9}, {0, 14}, {2, 18}, {0, 1}, {0, 4}, {2, -17}, {1, 10}, {1, 15}, {0, 2}, {2, -6}, {2, 4}, {2, 4}, {2, 17}, {2, -13}, {1, 20}}, {{1, 8}, {0, 20}, {2, 4}, {1, 6}, {2, -19}, {1, 4}, {0, 5}, {1, 8}, {1, 17}, {2, -4}, {2, 14}, {1, 10}, {2, 7}, {1, 18}, {2, 17}, {1, 6}, {0, 20}, {2, 1}, {2, -12}, {2, 18}},
|
||||
{{2, -7}, {1, 12}, {2, 4}, {2, 14}, {0, 13}, {1, 17}, {2, -2}, {2, -9}, {2, -13}, {1, 4}, {2, 4}, {1, 5}, {0, 15}, {2, -11}, {2, 3}, {2, 1}, {2, -11}, {2, 11}, {2, -11}, {0, 4}}, {{1, 7}, {2, 20}, {0, 6}, {0, 9}, {1, 2}, {0, 11}, {2, 4}, {2, -19}, {0, 17}, {2, -7}, {0, 20}, {0, 10}, {1, 11}, {1, 20}, {1, 6}, {2, 14}, {0, 11}, {0, 19}, {2, 4}, {1, 8}}, {{0, 9}, {2, -3}, {1, 17}, {2, 14}, {2, 3}, {1, 19}, {2, 17}, {0, 18}, {2, 16}, {0, 9}, {2, -15}, {1, 14}, {2, 11}, {2, -7}, {0, 17}, {2, 12}, {2, 6}, {2, 9}, {0, 7}, {1, 3}}, {{0, 1}, {2, 13}, {1, 19}, {0, 19}, {2, 6}, {2, -14}, {2, 8}, {2, -18}, {2, 4}, {2, -7}, {0, 12}, {2, 15}, {1, 3}, {2, -19}, {2, 15}, {2, -2}, {1, 19}, {1, 18}, {1, 19}, {0, 16}}, {{2, 7}, {2, 14}, {2, 14}, {2, -19}, {0, 1}, {2, -5}, {0, 17}, {2, 2}, {2, 15}, {1, 13}, {0, 20}, {0, 12}, {2, 20}, {0, 9}, {2, -8}, {0, 14}, {1, 19}, {2, -15}, {2, 17}, {2, -12}}, {{0, 16}, {2, -7}, {2, -4}, {1, 11}, {1, 17}, {2, -14}, {0, 16}, {2, 6}, {1, 19}, {2, 17}, {2, 10}, {2, -12}, {2, -17}, {1, 4}, {2, -14}, {2, -7}, {2, -17}, {2, -1}, {2, -16}, {1, 8}}, {{0, 5}, {0, 15}, {2, 4}, {2, 20}, {2, 7}, {2, 3}, {2, 17}, {0, 8}, {0, 18}, {2, -18}, {1, 1}, {0, 15}, {2, -4}, {0, 13}, {1, 11}, {0, 4}, {2, 11}, {1, 11}, {1, 10}, {2, -9}}, {{2, -5}, {2, -16}, {1, 2}, {1, 17}, {2, 9}, {2, -2}, {0, 7}, {0, 14}, {2, -10}, {0, 6}, {1, 14}, {1, 15}, {2, 12}, {2, 11}, {2, -9}, {2, -10}, {2, -14}, {2, 9}, {0, 13}, {2, 5}}, {{2, 8}, {2, -16}, {2, 20}, {1, 8}, {1, 2}, {2, -5}, {2, -20}, {1, 2}, {1, 4}, {1, 9}, {0, 19}, {2, -18}, {0, 6}, {0, 13}, {1, 5}, {2, 2}, {0, 4}, {1, 19}, {2, 15}, {1, 12}}, {{2, -8}, {0, 16}, {1, 10}, {2, 5}, {2, -16}, {0, 3}, {2, 5}, {0, 6}, {1, 17}, {2, 1}, {2, 13}, {0, 3}, {0, 6}, {0, 6}, {0, 19}, {1, 13}, {2, 19}, {2, 5}, {1, 16}, {2, 5}},
|
||||
{{2, -19}, {2, -1}, {0, 19}, {2, -3}, {2, 13}, {2, -12}, {0, 2}, {2, -20}, {2, 15}, {2, -9}, {2, -2}, {2, 13}, {2, -6}, {0, 2}, {1, 6}, {2, -1}, {0, 12}, {0, 20}, {2, -14}, {1, 2}}, {{1, 9}, {2, -14}, {2, -2}, {2, -13}, {0, 3}, {1, 6}, {2, 20}, {2, 11}, {2, 17}, {2, 5}, {0, 5}, {1, 1}, {2, -9}, {1, 8}, {2, -2}, {0, 18}, {2, -8}, {1, 11}, {2, 6}, {1, 7}}, {{2, 17}, {2, 14}, {2, 16}, {1, 20}, {2, -1}, {2, -7}, {1, 3}, {1, 14}, {0, 1}, {0, 18}, {2, -14}, {0, 10}, {0, 18}, {2, 19}, {1, 13}, {2, -16}, {1, 17}, {1, 1}, {2, -13}, {0, 13}}, {{2, -2}, {0, 14}, {0, 12}, {2, -8}, {1, 16}, {0, 18}, {2, 5}, {2, 13}, {1, 14}, {2, -4}, {2, 16}, {2, -16}, {2, 16}, {1, 18}, {2, 15}, {2, 4}, {2, -5}, {1, 7}, {2, -20}, {2, -9}}, {{2, 18}, {2, 2}, {2, 5}, {0, 4}, {2, 17}, {2, -15}, {2, 8}, {2, -11}, {1, 8}, {2, -6}, {2, -13}, {0, 5}, {0, 18}, {0, 15}, {2, -8}, {2, -15}, {1, 1}, {2, 4}, {2, -9}, {2, 14}}, {{2, -1}, {2, 1}, {1, 12}, {0, 9}, {2, -11}, {1, 4}, {1, 11}, {1, 5}, {0, 12}, {2, -7}, {1, 1}, {0, 6}, {0, 15}, {2, -10}, {2, -18}, {2, -12}, {0, 3}, {2, 2}, {2, -17}, {2, 1}}, {{2, -5}, {2, 18}, {1, 2}, {2, 14}, {2, 20}, {0, 13}, {0, 11}, {0, 6}, {2, -7}, {2, 13}, {1, 13}, {2, -1}, {1, 12}, {2, -9}, {2, 3}, {1, 6}, {2, -16}, {0, 6}, {0, 9}, {2, -14}}, {{1, 6}, {2, 7}, {2, -13}, {0, 5}, {1, 4}, {0, 15}, {2, 18}, {2, -4}, {2, 16}, {1, 1}, {2, 17}, {0, 2}, {1, 12}, {0, 17}, {1, 18}, {1, 5}, {1, 8}, {1, 4}, {2, -9}, {1, 9}}, {{0, 20}, {1, 10}, {2, 20}, {2, 13}, {0, 18}, {0, 10}, {1, 3}, {0, 8}, {2, -16}, {2, -16}, {2, -2}, {0, 20}, {2, -19}, {2, -11}, {1, 17}, {1, 18}, {1, 5}, {0, 6}, {2, -9}, {1, 8}}, {{0, 18}, {0, 19}, {2, 16}, {2, -14}, {1, 7}, {1, 9}, {0, 16}, {0, 16}, {1, 17}, {0, 14}, {2, -16}, {1, 6}, {1, 11}, {2, 7}, {1, 19}, {1, 11}, {2, -14}, {0, 7}, {1, 12}, {0, 2}},
|
||||
{{2, 3}, {2, -15}, {0, 13}, {2, -3}, {0, 16}, {1, 18}, {0, 11}, {0, 16}, {1, 13}, {2, -18}, {1, 14}, {2, 11}, {0, 11}, {2, -14}, {2, -19}, {0, 2}, {2, -7}, {0, 5}, {0, 20}, {2, -7}}, {{2, 9}, {2, 5}, {2, 7}, {0, 15}, {2, 4}, {0, 5}, {2, -17}, {2, 16}, {2, 8}, {0, 11}, {0, 1}, {1, 8}, {2, -5}, {1, 1}, {2, 4}, {2, -4}, {2, -17}, {0, 5}, {1, 10}, {0, 5}}, {{0, 11}, {1, 16}, {1, 18}, {0, 5}, {2, -13}, {0, 5}, {1, 13}, {1, 10}, {1, 11}, {0, 5}, {1, 9}, {1, 4}, {1, 19}, {2, 1}, {1, 19}, {1, 18}, {1, 8}, {2, 2}, {2, -5}, {1, 4}}, {{0, 12}, {1, 16}, {2, -1}, {1, 10}, {1, 10}, {2, -19}, {2, -20}, {1, 17}, {1, 19}, {1, 4}, {2, 12}, {0, 1}, {2, -15}, {2, -1}, {2, -10}, {2, -19}, {0, 18}, {0, 6}, {2, 18}, {0, 18}}, {{1, 10}, {0, 13}, {2, 3}, {0, 20}, {0, 19}, {0, 5}, {0, 9}, {0, 5}, {0, 20}, {0, 9}, {2, 16}, {1, 11}, {0, 12}, {2, -17}, {0, 20}, {0, 14}, {1, 17}, {2, 15}, {1, 7}, {2, -1}}, {{2, -10}, {2, 1}, {0, 2}, {2, -11}, {2, -17}, {2, -10}, {1, 9}, {2, -6}, {2, -19}, {1, 14}, {0, 4}, {1, 6}, {2, -9}, {2, 3}, {1, 2}, {2, 19}, {1, 15}, {0, 7}, {0, 4}, {2, 2}}, {{1, 12}, {2, -8}, {2, 13}, {2, -19}, {0, 17}, {0, 20}, {1, 3}, {1, 15}, {1, 20}, {2, 17}, {0, 12}, {2, -2}, {1, 8}, {2, -12}, {0, 11}, {2, 17}, {1, 14}, {1, 13}, {2, 2}, {2, 3}}, {{0, 13}, {1, 13}, {2, -4}, {1, 17}, {1, 1}, {1, 5}, {0, 10}, {1, 12}, {0, 9}, {2, -16}, {0, 13}, {2, 19}, {2, 9}, {1, 18}, {2, -1}, {2, -14}, {0, 5}, {1, 2}, {0, 20}, {2, -19}}, {{1, 7}, {2, 19}, {2, 11}, {2, -16}, {1, 19}, {2, -14}, {0, 7}, {1, 10}, {2, 8}, {0, 12}, {1, 12}, {2, -11}, {2, 6}, {2, -16}, {2, 15}, {1, 20}, {2, -12}, {1, 7}, {2, -16}, {2, 7}}, {{0, 8}, {2, 19}, {1, 12}, {2, -12}, {2, 4}, {1, 10}, {1, 13}, {2, 2}, {2, -14}, {2, -10}, {2, 18}, {1, 16}, {0, 10}, {2, 19}, {2, -1}, {1, 17}, {2, -1}, {0, 14}, {1, 11}, {0, 18}},
|
||||
{{2, 2}, {2, -2}, {2, 12}, {0, 7}, {0, 14}, {2, -15}, {2, 13}, {2, -3}, {0, 1}, {2, -2}, {1, 2}, {2, 4}, {2, 4}, {2, 16}, {1, 4}, {2, 1}, {1, 9}, {1, 6}, {1, 12}, {1, 11}}, {{2, -10}, {1, 16}, {1, 12}, {0, 18}, {2, -13}, {0, 19}, {2, 15}, {0, 11}, {0, 2}, {0, 4}, {0, 7}, {0, 10}, {2, -10}, {2, 11}, {0, 13}, {0, 10}, {2, -14}, {2, -18}, {0, 7}, {2, 16}}, {{2, -19}, {2, -5}, {1, 9}, {0, 15}, {2, 4}, {2, -14}, {1, 13}, {2, 10}, {2, -7}, {2, 14}, {2, 8}, {2, 9}, {0, 14}, {2, -4}, {1, 2}, {1, 19}, {0, 18}, {2, 18}, {1, 6}, {2, -6}}, {{2, -15}, {2, 1}, {0, 8}, {1, 5}, {2, -11}, {2, -3}, {0, 19}, {0, 4}, {1, 19}, {1, 2}, {1, 2}, {0, 3}, {0, 16}, {2, -3}, {2, 18}, {1, 20}, {2, -16}, {2, -2}, {2, -17}, {1, 15}}, {{1, 19}, {2, -11}, {1, 13}, {0, 14}, {1, 18}, {2, 11}, {2, 13}, {2, -14}, {1, 5}, {2, -6}, {0, 4}, {2, 19}, {0, 12}, {1, 4}, {2, -6}, {2, 8}, {2, 9}, {2, -10}, {2, -3}, {2, -19}}, {{2, 7}, {2, -9}, {2, 5}, {2, 12}, {2, -20}, {2, -3}, {2, -12}, {2, 5}, {0, 6}, {2, 15}, {1, 8}, {1, 9}, {2, 18}, {2, -14}, {2, 10}, {1, 5}, {1, 2}, {0, 14}, {2, 14}, {0, 19}}, {{2, 12}, {0, 9}, {0, 14}, {1, 4}, {2, 4}, {2, -8}, {2, 4}, {0, 13}, {1, 10}, {2, 18}, {2, 13}, {2, 15}, {1, 18}, {2, 7}, {2, -18}, {2, 18}, {1, 9}, {2, -9}, {0, 16}, {2, -14}}, {{0, 16}, {2, 9}, {2, 7}, {1, 6}, {0, 14}, {2, -18}, {1, 14}, {1, 2}, {0, 10}, {1, 6}, {0, 10}, {2, 2}, {1, 1}, {0, 19}, {1, 6}, {2, -3}, {2, 3}, {2, 12}, {2, 5}, {1, 18}}, {{2, -17}, {0, 17}, {0, 5}, {2, 18}, {2, 8}, {0, 14}, {0, 10}, {1, 20}, {2, 7}, {1, 10}, {1, 14}, {1, 10}, {0, 11}, {1, 15}, {0, 16}, {1, 14}, {0, 3}, {2, 16}, {2, -5}, {2, -4}}, {{1, 15}, {2, -9}, {0, 11}, {0, 16}, {2, 1}, {0, 12}, {0, 7}, {0, 16}, {2, 14}, {0, 3}, {1, 11}, {2, 4}, {1, 6}, {2, -1}, {1, 20}, {1, 13}, {0, 2}, {2, -12}, {0, 9}, {2, 8}},
|
||||
{{0, 1}, {2, -4}, {0, 19}, {2, -15}, {2, -16}, {2, -10}, {2, 7}, {0, 10}, {2, -6}, {2, -8}, {2, -3}, {2, 18}, {1, 20}, {2, 10}, {1, 18}, {2, -3}, {0, 7}, {2, 3}, {2, 14}, {2, 15}}, {{1, 17}, {0, 7}, {1, 17}, {2, -8}, {2, -12}, {2, -9}, {2, 15}, {0, 10}, {1, 10}, {2, -6}, {2, -20}, {1, 17}, {2, -9}, {1, 15}, {1, 3}, {1, 8}, {0, 1}, {1, 13}, {2, -5}, {0, 14}}, {{2, 8}, {0, 11}, {0, 12}, {2, 5}, {2, -4}, {2, -5}, {2, -2}, {0, 20}, {2, -4}, {1, 1}, {1, 2}, {0, 4}, {2, 14}, {1, 17}, {2, -13}, {1, 13}, {2, 12}, {2, 20}, {2, 14}, {2, -9}}, {{2, -20}, {2, 13}, {1, 20}, {2, 20}, {2, 9}, {0, 16}, {2, 1}, {0, 13}, {2, 17}, {2, 8}, {2, 13}, {2, -3}, {2, -1}, {2, -19}, {2, 1}, {1, 16}, {2, -16}, {0, 6}, {2, 2}, {1, 8}}, {{1, 4}, {1, 9}, {1, 8}, {2, -12}, {0, 4}, {1, 8}, {0, 9}, {2, -2}, {2, -19}, {2, 2}, {2, -1}, {0, 14}, {2, 4}, {2, -17}, {0, 1}, {2, 4}, {2, -20}, {2, 3}, {0, 7}, {1, 4}}, {{0, 6}, {2, -5}, {1, 13}, {2, 15}, {2, 11}, {0, 7}, {1, 17}, {2, 9}, {1, 14}, {2, -7}, {2, 12}, {2, -18}, {0, 19}, {2, -1}, {2, 14}, {2, 5}, {2, -16}, {1, 2}, {2, -2}, {0, 17}}, {{1, 11}, {2, 4}, {2, 7}, {1, 16}, {2, 14}, {0, 14}, {2, 16}, {1, 11}, {1, 10}, {2, -3}, {2, -10}, {1, 7}, {2, 9}, {0, 19}, {2, 1}, {0, 7}, {1, 11}, {0, 9}, {2, -16}, {1, 8}}, {{0, 10}, {0, 4}, {2, -8}, {2, 20}, {2, 16}, {2, 5}, {0, 16}, {1, 6}, {2, 2}, {2, 14}, {2, 11}, {1, 15}, {2, -10}, {2, -5}, {0, 4}, {0, 4}, {2, -13}, {2, 11}, {0, 13}, {0, 11}}, {{0, 6}, {1, 4}, {2, 15}, {2, 17}, {1, 1}, {2, -20}, {1, 18}, {0, 19}, {2, -12}, {2, 1}, {2, -15}, {2, -11}, {1, 19}, {0, 13}, {1, 2}, {0, 17}, {2, 14}, {0, 14}, {2, 12}, {0, 19}}, {{2, -16}, {1, 20}, {2, -14}, {1, 7}, {2, -13}, {2, 19}, {2, 20}, {2, -14}, {1, 17}, {2, 20}, {1, 2}, {2, -19}, {2, -17}, {2, 18}, {2, 6}, {1, 17}, {2, 7}, {0, 8}, {1, 20}, {2, 9}},
|
||||
{{2, 20}, {2, 17}, {2, 15}, {1, 13}, {0, 7}, {2, -6}, {0, 8}, {2, -17}, {1, 15}, {2, -20}, {0, 17}, {2, -17}, {0, 12}, {1, 14}, {2, -8}, {2, -17}, {0, 12}, {2, -3}, {2, -13}, {0, 7}}, {{0, 3}, {2, 12}, {2, 4}, {0, 13}, {0, 15}, {1, 4}, {2, 7}, {2, -20}, {0, 4}, {0, 6}, {0, 12}, {2, 10}, {2, -13}, {0, 20}, {2, -11}, {0, 16}, {2, -13}, {2, -5}, {1, 14}, {0, 7}}, {{2, 16}, {1, 11}, {2, -1}, {0, 9}, {0, 19}, {2, 9}, {2, 6}, {1, 15}, {2, 2}, {2, 8}, {1, 3}, {2, 20}, {2, -18}, {2, -15}, {2, -20}, {0, 10}, {1, 9}, {2, 5}, {2, -17}, {2, 14}}, {{2, -15}, {2, -10}, {2, -18}, {1, 20}, {1, 4}, {0, 18}, {1, 10}, {2, 19}, {2, -9}, {2, 20}, {0, 1}, {0, 11}, {2, -18}, {2, 5}, {1, 15}, {0, 10}, {2, -14}, {2, 6}, {0, 17}, {0, 3}}, {{1, 18}, {1, 5}, {0, 11}, {2, 11}, {0, 13}, {1, 5}, {0, 19}, {2, 20}, {1, 10}, {2, 19}, {0, 13}, {0, 7}, {2, 1}, {2, 14}, {1, 19}, {0, 9}, {1, 17}, {2, 18}, {0, 11}, {1, 9}}, {{2, -17}, {2, 10}, {2, -19}, {2, -18}, {2, 6}, {0, 9}, {0, 20}, {1, 7}, {2, -14}, {2, -11}, {0, 14}, {1, 1}, {0, 13}, {0, 2}, {2, 3}, {0, 2}, {2, 11}, {2, 10}, {2, 12}, {2, -4}}, {{2, 13}, {1, 14}, {2, 7}, {1, 12}, {2, -9}, {2, -4}, {2, -8}, {2, 13}, {0, 3}, {1, 20}, {2, 2}, {2, 5}, {0, 19}, {0, 10}, {2, 14}, {2, -15}, {1, 5}, {2, 18}, {2, -8}, {2, 6}}, {{1, 5}, {1, 9}, {1, 19}, {2, 19}, {0, 13}, {2, 2}, {2, 12}, {2, 17}, {2, -16}, {0, 12}, {0, 9}, {1, 17}, {0, 13}, {2, 7}, {1, 7}, {2, 14}, {0, 12}, {0, 7}, {2, -16}, {1, 7}}, {{2, 15}, {0, 9}, {1, 3}, {0, 4}, {2, -3}, {0, 12}, {2, 9}, {0, 6}, {1, 16}, {0, 10}, {2, -6}, {1, 20}, {2, 11}, {2, -3}, {2, -6}, {0, 15}, {0, 14}, {0, 11}, {2, -19}, {2, -14}}, {{0, 12}, {2, 8}, {1, 20}, {2, 18}, {2, 3}, {2, 2}, {2, 4}, {2, 7}, {2, -19}, {2, -9}, {2, 2}, {0, 19}, {0, 11}, {2, -9}, {0, 9}, {2, -14}, {1, 13}, {0, 2}, {0, 1}, {2, -19}},
|
||||
{{2, -4}, {1, 6}, {0, 18}, {2, 4}, {1, 12}, {0, 17}, {2, 10}, {2, 13}, {2, 10}, {1, 10}, {2, -1}, {2, -11}, {2, -15}, {2, -5}, {2, -16}, {2, -12}, {0, 2}, {2, -10}, {2, 15}, {1, 2}}, {{2, -9}, {2, -14}, {1, 4}, {0, 5}, {2, -9}, {0, 7}, {0, 9}, {1, 16}, {1, 10}, {2, -14}, {0, 7}, {2, -18}, {0, 19}, {1, 3}, {1, 7}, {2, -19}, {2, 14}, {0, 9}, {1, 7}, {2, -5}}, {{2, 16}, {0, 13}, {2, 20}, {2, -9}, {0, 20}, {2, 20}, {0, 5}, {0, 6}, {1, 4}, {2, -11}, {0, 14}, {0, 9}, {2, 18}, {0, 14}, {0, 12}, {2, 16}, {2, 8}, {2, -13}, {1, 9}, {1, 3}}, {{2, 1}, {2, 13}, {2, -8}, {0, 9}, {2, -16}, {0, 12}, {0, 12}, {2, 19}, {2, -10}, {2, 1}, {2, -20}, {1, 10}, {0, 18}, {2, -15}, {2, -15}, {1, 15}, {0, 15}, {0, 1}, {2, -5}, {0, 19}}, {{2, 6}, {2, 15}, {2, -20}, {1, 20}, {2, 3}, {2, 7}, {1, 1}, {0, 5}, {0, 4}, {2, 8}, {1, 19}, {2, -3}, {2, 18}, {1, 10}, {0, 11}, {2, -19}, {0, 3}, {2, 5}, {1, 4}, {0, 6}}, {{0, 5}, {2, -17}, {1, 1}, {0, 1}, {2, -9}, {0, 8}, {2, -10}, {2, -4}, {0, 13}, {2, 19}, {0, 6}, {2, 9}, {2, 14}, {2, 11}, {0, 16}, {2, 13}, {1, 1}, {2, 9}, {2, 14}, {0, 18}}, {{0, 10}, {1, 12}, {1, 4}, {2, -12}, {2, 7}, {0, 5}, {1, 15}, {2, 7}, {2, 17}, {1, 18}, {2, 3}, {0, 12}, {1, 8}, {1, 13}, {2, -17}, {1, 20}, {0, 18}, {1, 12}, {1, 16}, {0, 16}}, {{2, -10}, {2, -1}, {2, 10}, {1, 4}, {2, -12}, {1, 19}, {2, 18}, {2, -15}, {2, -5}, {1, 11}, {2, -7}, {0, 20}, {2, -12}, {2, -12}, {1, 11}, {2, 8}, {2, 2}, {2, -2}, {2, -4}, {2, 19}}, {{2, 5}, {1, 15}, {1, 18}, {2, 20}, {1, 4}, {0, 7}, {2, -8}, {2, 1}, {2, -6}, {2, 8}, {1, 1}, {2, 12}, {1, 15}, {0, 16}, {1, 13}, {0, 1}, {0, 19}, {0, 20}, {2, -3}, {0, 12}}, {{1, 18}, {2, -4}, {1, 8}, {2, 19}, {1, 11}, {0, 12}, {0, 20}, {2, 4}, {1, 12}, {0, 17}, {2, 8}, {1, 5}, {2, -13}, {1, 3}, {1, 14}, {1, 4}, {0, 20}, {1, 18}, {0, 7}, {0, 17}},
|
||||
{{2, 14}, {2, 10}, {2, -12}, {2, -15}, {1, 3}, {2, -17}, {1, 12}, {2, 9}, {2, -9}, {0, 11}, {2, 12}, {0, 16}, {0, 13}, {2, -17}, {2, 13}, {2, 11}, {1, 13}, {2, 16}, {0, 14}, {2, -8}}, {{0, 16}, {2, -10}, {1, 12}, {1, 12}, {2, 19}, {1, 5}, {2, 1}, {2, 19}, {0, 17}, {2, -19}, {2, 20}, {0, 7}, {1, 11}, {2, -3}, {2, -19}, {2, -20}, {2, 15}, {2, -18}, {2, 11}, {2, -19}}, {{2, -11}, {2, 10}, {0, 10}, {1, 15}, {1, 1}, {2, 7}, {2, -9}, {2, -3}, {0, 2}, {0, 20}, {0, 1}, {2, 14}, {2, -16}, {1, 14}, {0, 19}, {0, 11}, {2, 4}, {2, -9}, {2, -4}, {2, -10}}, {{2, 2}, {2, 17}, {1, 7}, {0, 18}, {0, 12}, {2, -15}, {2, 18}, {1, 7}, {1, 3}, {2, 14}, {1, 19}, {1, 6}, {2, -19}, {2, 9}, {0, 11}, {1, 13}, {2, -13}, {0, 19}, {1, 15}, {0, 14}}, {{2, 14}, {1, 3}, {2, 4}, {0, 14}, {1, 8}, {2, 7}, {0, 16}, {1, 11}, {2, 11}, {1, 13}, {1, 6}, {2, -10}, {0, 17}, {1, 18}, {1, 1}, {2, -11}, {1, 9}, {0, 16}, {2, 5}, {2, -6}}, {{0, 11}, {2, -2}, {1, 7}, {2, 8}, {2, 20}, {0, 7}, {0, 14}, {2, -17}, {2, 14}, {2, -14}, {2, -16}, {2, -12}, {2, -19}, {2, 10}, {2, -8}, {1, 1}, {1, 14}, {0, 5}, {0, 14}, {2, 14}}, {{2, 10}, {2, 18}, {1, 15}, {1, 15}, {2, 10}, {2, 14}, {1, 15}, {2, -16}, {2, -4}, {2, -1}, {2, -20}, {2, 2}, {1, 6}, {0, 2}, {2, -17}, {0, 13}, {2, -8}, {2, 18}, {2, 9}, {2, -12}}, {{2, -7}, {1, 16}, {2, 15}, {1, 14}, {1, 15}, {0, 8}, {1, 19}, {2, -13}, {2, 17}, {2, 4}, {2, -17}, {2, -2}, {0, 8}, {1, 11}, {2, 14}, {0, 13}, {2, -12}, {2, -1}, {2, -5}, {0, 6}}, {{0, 2}, {2, -1}, {2, -15}, {1, 9}, {0, 17}, {0, 8}, {2, 19}, {0, 5}, {1, 16}, {2, 3}, {1, 17}, {2, -8}, {2, -1}, {2, -4}, {2, -16}, {0, 4}, {2, -8}, {2, 14}, {2, -20}, {2, -15}}, {{0, 5}, {0, 20}, {1, 13}, {0, 13}, {2, 18}, {1, 19}, {0, 7}, {0, 13}, {2, -7}, {2, 11}, {0, 16}, {1, 6}, {2, -19}, {2, 6}, {1, 18}, {2, 4}, {2, -7}, {2, -8}, {2, 20}, {0, 19}}
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
uint8_t buf[20];
|
||||
uint8_t n = 0;
|
||||
uint32_t bres = 0;
|
||||
for(uint32_t i = 0; i < 100; i++) {
|
||||
/* bring the pos back to the middle of the file */
|
||||
int32_t pos = 500;
|
||||
res = lv_fs_seek(&f, pos, LV_FS_SEEK_SET);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
for(uint32_t j = 0; j < 20; j++) {
|
||||
int8_t action = actions[i][j][0];
|
||||
int8_t amount = actions[i][j][1];
|
||||
switch(action) {
|
||||
case 0: /* read */
|
||||
res = lv_fs_read(&f, buf, amount, &bres);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
TEST_ASSERT_EQUAL(amount, bres);
|
||||
TEST_ASSERT(0 == memcmp(buf, buf1000 + pos, amount));
|
||||
pos += amount;
|
||||
break;
|
||||
case 1: /* write */
|
||||
for(int32_t k = 0; k < amount; k++) {
|
||||
buf[k] = n;
|
||||
buf1000[pos + k] = n;
|
||||
n++;
|
||||
}
|
||||
res = lv_fs_write(&f, buf, amount, &bres);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
TEST_ASSERT_EQUAL(amount, bres);
|
||||
pos += amount;
|
||||
break;
|
||||
case 2: /* seek */
|
||||
pos += amount; /* amount may be negative */
|
||||
res = lv_fs_seek(&f, pos, LV_FS_SEEK_SET);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* test SEEK_END */
|
||||
uint32_t tell_pos;
|
||||
res = lv_fs_seek(&f, 0, LV_FS_SEEK_END);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
res = lv_fs_tell(&f, &tell_pos);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
TEST_ASSERT_EQUAL(tell_pos, 1000);
|
||||
|
||||
res = lv_fs_close(&f);
|
||||
TEST_ASSERT_EQUAL(LV_FS_RES_OK, res);
|
||||
|
||||
drv->cache_size = original_cache_size;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user