diff --git a/cores/esp8266/FS.cpp b/cores/esp8266/FS.cpp index 6ae11e1782..6374b29445 100644 --- a/cores/esp8266/FS.cpp +++ b/cores/esp8266/FS.cpp @@ -96,6 +96,13 @@ size_t File::position() const { return _p->position(); } +time_t File::getLastWrite() { + if (!_p) + return 0; + + return _p->getLastWrite(); +} + size_t File::size() const { if (!_p) return 0; diff --git a/cores/esp8266/FS.h b/cores/esp8266/FS.h index 79620f96c8..a10d05d828 100644 --- a/cores/esp8266/FS.h +++ b/cores/esp8266/FS.h @@ -59,6 +59,7 @@ class File : public Stream int read() override; int peek() override; void flush() override; + time_t getLastWrite(); size_t readBytes(char *buffer, size_t length) override { return read((uint8_t*)buffer, length); } diff --git a/cores/esp8266/FSImpl.h b/cores/esp8266/FSImpl.h index e5694b5f68..f79ddf8f10 100644 --- a/cores/esp8266/FSImpl.h +++ b/cores/esp8266/FSImpl.h @@ -34,6 +34,7 @@ class FileImpl { virtual bool seek(uint32_t pos, SeekMode mode) = 0; virtual size_t position() const = 0; virtual size_t size() const = 0; + virtual time_t getLastWrite() = 0; virtual void close() = 0; virtual const char* name() const = 0; }; diff --git a/cores/esp8266/spiffs/spiffs_config.h b/cores/esp8266/spiffs/spiffs_config.h index c3343fe2fe..29ca788c2b 100644 --- a/cores/esp8266/spiffs/spiffs_config.h +++ b/cores/esp8266/spiffs/spiffs_config.h @@ -176,7 +176,7 @@ typedef uint8_t u8_t; // logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) + // spiffs_object_ix_header fields + at least some LUT entries) #ifndef SPIFFS_OBJ_META_LEN -#define SPIFFS_OBJ_META_LEN (0) +#define SPIFFS_OBJ_META_LEN (4) #endif // Size of buffer allocated on stack used when copying data. diff --git a/cores/esp8266/spiffs_api.cpp b/cores/esp8266/spiffs_api.cpp index 390a6412fd..7e2b3d833f 100644 --- a/cores/esp8266/spiffs_api.cpp +++ b/cores/esp8266/spiffs_api.cpp @@ -49,6 +49,16 @@ FileImplPtr SPIFFSImpl::open(const char* path, OpenMode openMode, AccessMode acc fd, path, openMode, accessMode, _fs.err_code); return FileImplPtr(); } +#if SPIFFS_OBJ_META_LEN > 0 + if (!(mode & SPIFFS_O_RDONLY)) + { + time_t t = time(NULL); + struct tm tmr; + localtime_r(&t, &tmr); + time_t meta = mktime(&tmr); + SPIFFS_fupdate_meta(&_fs, fd, &meta); + } +#endif return std::make_shared(this, fd); } diff --git a/cores/esp8266/spiffs_api.h b/cores/esp8266/spiffs_api.h index 612b014b8a..ba5571faa7 100644 --- a/cores/esp8266/spiffs_api.h +++ b/cores/esp8266/spiffs_api.h @@ -32,6 +32,9 @@ #include "spiffs/spiffs.h" #include "debug.h" #include "flash_utils.h" +#if SPIFFS_OBJ_META_LEN > 0 +#include +#endif using namespace fs; @@ -375,6 +378,16 @@ class SPIFFSFileImpl : public FileImpl return (const char*) _stat.name; } + time_t getLastWrite() + { + time_t t =0; +#if SPIFFS_OBJ_META_LEN > 0 + _getStat() ; + memcpy(&t, _stat.meta, sizeof(time_t)); +#endif + return t; + } + protected: void _getStat() const { diff --git a/libraries/ESP8266WiFi/examples/SPIFFS_time/SPIFFS_time.ino b/libraries/ESP8266WiFi/examples/SPIFFS_time/SPIFFS_time.ino new file mode 100644 index 0000000000..19cbbd3809 --- /dev/null +++ b/libraries/ESP8266WiFi/examples/SPIFFS_time/SPIFFS_time.ino @@ -0,0 +1,163 @@ +#include "FS.h" +#include +#include + +const char* ssid = "your-ssid"; +const char* password = "your-password"; + +long timezone = 2; +byte daysavetime = 1; + + +bool getLocalTime(struct tm * info, uint32_t ms) +{ + uint32_t count = ms / 10; + time_t now; + + time(&now); + localtime_r(&now, info); + + if(info->tm_year > (2016 - 1900)){ + return true; + } + + while(count--) { + delay(10); + time(&now); + localtime_r(&now, info); + if(info->tm_year > (2016 - 1900)){ + return true; + } + } + return false; +} + + +void listDir(const char * dirname){ + Serial.printf("Listing directory: %s\n", dirname); + + Dir root = SPIFFS.openDir(dirname); + + while(root.next()){ + File file = root.openFile("r"); + Serial.print(" FILE: "); + Serial.print(root.fileName()); + Serial.print(" SIZE: "); + Serial.print(file.size()); + time_t t= file.getLastWrite(); + struct tm * tmstruct = localtime(&t); + file.close(); + Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec); + } +} + + +void readFile(const char * path){ + Serial.printf("Reading file: %s\n", path); + + File file = SPIFFS.open(path, "r"); + if(!file){ + Serial.println("Failed to open file for reading"); + return; + } + + Serial.print("Read from file: "); + while(file.available()){ + Serial.write(file.read()); + } + file.close(); +} + +void writeFile(const char * path, const char * message){ + Serial.printf("Writing file: %s\n", path); + + File file = SPIFFS.open(path, "w"); + if(!file){ + Serial.println("Failed to open file for writing"); + return; + } + if(file.print(message)){ + Serial.println("File written"); + } else { + Serial.println("Write failed"); + } + file.close(); +} + +void appendFile(const char * path, const char * message){ + Serial.printf("Appending to file: %s\n", path); + + File file = SPIFFS.open(path, "a"); + if(!file){ + Serial.println("Failed to open file for appending"); + return; + } + if(file.print(message)){ + Serial.println("Message appended"); + } else { + Serial.println("Append failed"); + } + file.close(); +} + +void renameFile(const char * path1, const char * path2){ + Serial.printf("Renaming file %s to %s\n", path1, path2); + if (SPIFFS.rename(path1, path2)) { + Serial.println("File renamed"); + } else { + Serial.println("Rename failed"); + } +} + +void deleteFile(const char * path){ + Serial.printf("Deleting file: %s\n", path); + if(SPIFFS.remove(path)){ + Serial.println("File deleted"); + } else { + Serial.println("Delete failed"); + } +} + +void setup(){ + Serial.begin(115200); + // We start by connecting to a WiFi network + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println("Contacting Time Server"); + configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); + struct tm tmstruct ; + delay(2000); + tmstruct.tm_year = 0; + getLocalTime(&tmstruct, 5000); + Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec); + Serial.println(""); + + if(!SPIFFS.begin()){ + Serial.println("Card Mount Failed"); + return; + } + + listDir("/"); + deleteFile("/hello.txt"); + writeFile("/hello.txt", "Hello "); + appendFile("/hello.txt", "World!\n"); + listDir("/"); +} + +void loop(){ + +} + +