1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-27 18:02:17 +03:00

Add time to filesystem API (#6544)

* Add time to filesystem API

Support the ESP32 File::getLastWrite() call and setting the time on
all filesystems automatically (assuming the system clock has
been set properly and time(NULL) returns the proper time!).

Adds Dir::fileTime() to get the time of a file being listed, similar to
Dir::fileName() and Dir::fileSize().

Adds ::setTimeCallback(time_t (*cb)()) to File, Dir, and FS, allowing
users to override the default timestamp on a per-file, directory, or
filesystem basis. By default, a simple callback returning time(nullptr)
is implemented.

LittleFS uses the 't' attribute and should be backwards compatible.

SD/SDFS work and include wrappers for obsolete SdFat timestamp callbacks
using the MSDOS time.

This PR does not update SPIFFS, due to compatability concerns and a
possible massive rewrite which would make it possible to determine if an
old-style ot metadata enabled FS is present at mount time.

Includes an updated SD/listfiles and LittleFS_time example.

Replaces #6315

* Add links to new mklittlefs w/timestamp support

Include the update mklittlefs which generated 't' metadata on imported
files.
	../tools/sdk/lwip2/include/netif/lowpan6_opts.h

* Add explicit note about timestamp being local time

* Address review concerns

Clean up some awkward object instantiations.

Remove the _enableTime flag/setter from SPIFFS.

Clean up the FSConfig constructors using C++ style init lists.
This commit is contained in:
Earle F. Philhower, III
2019-10-31 06:09:52 -07:00
committed by david gauchard
parent b4c28e74d6
commit 72dd589599
12 changed files with 576 additions and 114 deletions

View File

@ -92,6 +92,27 @@ and ``SPIFFS.open()`` to ``LittleFS.open()`` with the rest of the
code remaining untouched.
SDFS and SD
-----------
FAT filesystems are supported on the ESP8266 using the old Arduino wrapper
"SD.h" which wraps the "SDFS.h" filesystem transparently.
Any commands discussed below pertaining to SPIFFS or LittleFS are
applicable to SD/SDFS.
For legacy applications, the classic SD filesystem may continue to be used,
but for new applications, directly accessing the SDFS filesystem is
recommended as it may expose additional functionality that the old Arduino
SD filesystem didn't have.
Note that in earlier releases of the core, using SD and SPIFFS in the same
sketch was complicated and required the use of ``NO_FS_GLOBALS``. The
current design makes SD, SDFS, SPIFFS, and LittleFS fully source compatible
and so please remove any ``NO_FS_GLOBALS`` definitions in your projects
when updgrading core versions.
SPIFFS file system limitations
------------------------------
@ -198,8 +219,8 @@ use esptool.py.
- To upload a LittleFS filesystem use Tools > ESP8266 LittleFS Data Upload
File system object (SPIFFS/LittleFS)
------------------------------------
File system object (SPIFFS/LittleFS/SD/SDFS)
--------------------------------------------
setConfig
~~~~~~~~~
@ -369,41 +390,6 @@ rename
Renames file from ``pathFrom`` to ``pathTo``. Paths must be absolute.
Returns *true* if file was renamed successfully.
info
~~~~
.. code:: cpp
FSInfo fs_info;
SPIFFS.info(fs_info);
or LittleFS.info(fs_info);
Fills `FSInfo structure <#filesystem-information-structure>`__ with
information about the file system. Returns ``true`` is successful,
``false`` otherwise.
Filesystem information structure
--------------------------------
.. code:: cpp
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
This is the structure which may be filled using FS::info method. -
``totalBytes`` — total size of useful data on the file system -
``usedBytes`` — number of bytes used by files - ``blockSize`` — filesystem
block size - ``pageSize`` — filesystem logical page size - ``maxOpenFiles``
— max number of files which may be open simultaneously -
``maxPathLength`` — max file name length (including one byte for zero
termination)
gc
~~
@ -429,6 +415,81 @@ Only implemented in SPIFFS. Performs an in-depth check of the filesystem metada
correct what is repairable. Not normally needed, and not guaranteed to actually fix
anything should there be corruption.
info
~~~~
.. code:: cpp
FSInfo fs_info;
SPIFFS.info(fs_info);
or LittleFS.info(fs_info);
Fills `FSInfo structure <#filesystem-information-structure>`__ with
information about the file system. Returns ``true`` if successful,
``false`` otherwise.
Filesystem information structure
--------------------------------
.. code:: cpp
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
This is the structure which may be filled using FS::info method. -
``totalBytes`` — total size of useful data on the file system -
``usedBytes`` — number of bytes used by files - ``blockSize`` — filesystem
block size - ``pageSize`` — filesystem logical page size - ``maxOpenFiles``
— max number of files which may be open simultaneously -
``maxPathLength`` — max file name length (including one byte for zero
termination)
info64
~~~~~~
.. code:: cpp
FSInfo64 fsinfo;
SD.info(fsinfo);
or LittleFS(fsinfo);
Performs the same operation as ``info`` but allows for reporting greater than
4GB for filesystem size/used/etc. Should be used with the SD and SDFS
filesystems since most SD cards today are greater than 4GB in size.
setTimeCallback(time_t (*cb)(void))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: cpp
time_t myTimeCallback() {
return 1455451200; // UNIX timestamp
}
void setup () {
LittleFS.setTimeCallback(myTimeCallback);
...
// Any files will now be made with Pris' incept date
}
The SD, SDFS, and LittleFS filesystems support a file timestamp, updated when the file is
opened for writing. By default, the ESP8266 will use the internal time returned from
``time(NULL)`` (i.e. local time, not UTC, to conform to the existing FAT filesystem), but this
can be overridden to GMT or any other standard you'd like by using ``setTimeCallback()``.
If your app sets the system time using NTP before file operations, then
you should not need to use this function. However, if you need to set a specific time
for a file, or the system clock isn't correct and you need to read the time from an external
RTC or use a fixed time, this call allows you do to so.
In general use, with a functioning ``time()`` call, user applications should not need
to use this function.
Directory object (Dir)
----------------------
@ -468,6 +529,12 @@ fileSize
Returns the size of the current file pointed to
by the internal iterator.
fileTime
~~~~~~~~
Returns the time_t write time of the current file pointed
to by the internal iterator.
isFile
~~~~~~
@ -491,6 +558,13 @@ rewind
Resets the internal pointer to the start of the directory.
setTimeCallback(time_t (*cb)(void))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the time callback for any files accessed from this Dir object via openNextFile.
Note that the SD and SDFS filesystems only support a filesystem-wide callback and
calls to ``Dir::setTimeCallback`` may produce unexpected behavior.
File object
-----------
@ -562,6 +636,12 @@ fullName
Returns the full path file name as a ``const char*``.
getLastWrite
~~~~~~~~~~~~
Returns the file last write time, and only valid for files opened in read-only
mode. If a file is opened for writing, the returned time may be indeterminate.
isFile
~~~~~~
@ -616,3 +696,10 @@ rewindDirectory (compatibiity method, not recommended for new code)
Resets the ``openNextFile`` pointer to the top of the directory. Only
valid when ``File.isDirectory() == true``.
setTimeCallback(time_t (*cb)(void))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the time callback for this specific file. Note that the SD and
SDFS filesystems only support a filesystem-wide callback and calls to
``Dir::setTimeCallback`` may produce unexpected behavior.