Skip to content

setTimeCallback is not working for ESP8266 with both SD.h and SDFS too #7682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
akoro opened this issue Oct 29, 2020 · 2 comments · Fixed by #7686
Closed

setTimeCallback is not working for ESP8266 with both SD.h and SDFS too #7682

akoro opened this issue Oct 29, 2020 · 2 comments · Fixed by #7686
Assignees
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.

Comments

@akoro
Copy link

akoro commented Oct 29, 2020

Basic Infos

  • [x ] This issue complies with the issue POLICY doc.
  • [x ] I have read the documentation at readthedocs and the issue is not addressed there.
  • [x ] I have tested that the issue is present in current master branch (aka latest git).
  • [x ] I have searched the issue tracker for a similar issue.
  • [x ] If there is a stack dump, I have decoded it.
  • [x ] I have filled out all fields below.

Platform

  • Hardware: ESP-12
  • Core Version: 2.6.2
  • Development Env: Platformio
  • Operating System: Windows

Settings in IDE

  • Module: Generic ESP8266 Module
  • Flash Mode: dio
  • Flash Size: 4MB
  • lwip Variant: v1.4
  • Reset Method: nodemcu
  • Flash Frequency: 40Mhz
  • CPU Frequency: 80Mhz
  • Upload Using: SERIAL
  • Upload Speed: 460800

Problem Description

setTimeCallback is not working for ESP8266 with both SD.h and SDFS too
TimeCallback function isn't calling at all

#include <SPI.h>
#include <time.h>
#include <SDFS.h>
using namespace sdfs;

SDFSConfig cfg(SS);

// TimeCallback function:
time_t my_time(void)
{
  struct tm t;
  t.tm_year = 120;
  t.tm_mon  = 9;
  t.tm_mday = 22;
  t.tm_hour = 12;
  t.tm_min  = 13;
  t.tm_sec  = 14;
  Serial.print("*");
  return mktime(&t);
}

void setup()
{
  Serial.begin(115200);
  while (!Serial) yield();
...
  // SD card init
  SDFS.setConfig(cfg);
  SDFS.setTimeCallback(my_time); // does not work!!!
  SDFS.begin();
...
  String fname = "new_file.txt"

  File file = SDFS.open(fname, "w");
  if (file)
  {
    file.write("12457845122\r\n");
    file.write("12457845122\r\n");
    file.write("12457845122\r\n");
    file.write("12457845122\r\n");
    file.write("12457845122\r\n");
    file.close();
    Serial.printf("create %s OK\n", fname.c_str());
  }
  else
    Serial.printf("create %s failed\n", fname.c_str());
...
    
}

The file created normal but his timestamp is not expected.
And "*" is not printing, so my_time() does not call.

The part of the directory list output:
1961-11-25 17:32:20 new_file.txt 65

Similar issue

earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Oct 30, 2020
The SDFS implementation didn't include plumbing to support user-supplied
timestamp generators (for file create/write times) because the SDFat
library doesn't support a callback parameter.

Work around it by using a single, global (inside sdfs namespace) that
the static timestamp callback member can see and use.

Add a test of the feature in CI.

Fixes esp8266#7682
@earlephilhower
Copy link
Collaborator

Please give the PR above a try and report back. The plumbing for SDFat<->userTimeCallback wasn't built originally, as commented in the header. It's hooked in now in the PR with a CI test.

@earlephilhower earlephilhower added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label Oct 30, 2020
@earlephilhower earlephilhower self-assigned this Oct 30, 2020
@akoro
Copy link
Author

akoro commented Oct 31, 2020

Thank you!
It does work now.
I have made patches in SDFS.cpp and SDFS.h
Testing code is below. I have "OK OK" in the output. And my origin project works too.

#include <SPI.h>
#include <FS.h>
#include "SDFS.h"

// SDFS timestamp setter (#7682)
static time_t _my_time(void)
{
    struct tm t;
    bzero(&t, sizeof(t));
    t.tm_year = 120;
    t.tm_mon  = 9;
    t.tm_mday = 22;
    t.tm_hour = 12;
    t.tm_min  = 13;
    t.tm_sec  = 14;
    return mktime(&t);
}

SDFSConfig cfg(SS);

void setup(void)
{
  Serial.begin(115200);
  while (!Serial) yield();
  Serial.println();

  SDFS.setConfig(cfg);
  if(SDFS.begin())
  {
    SDFS.setTimeCallback(_my_time);

    File f = SDFS.open("/file.txt", "w");
    f.write("Had we but world enough, and time,");
    f.close();
    time_t expected = _my_time();
    f = SDFS.open("/file.txt", "r");
    if(abs(f.getCreationTime() - expected) < 60)
      Serial.println("OK");
    else
      Serial.println("?");
    if(abs(f.getLastWrite() - expected) < 60)
      Serial.println("OK");
    else
      Serial.println("?");
    
    f.close();
  }
}

void loop(){}

earlephilhower added a commit that referenced this issue Oct 31, 2020
The SDFS implementation didn't include plumbing to support user-supplied
timestamp generators (for file create/write times) because the SDFat
library doesn't support a callback parameter.

Work around it by using a single, global (inside sdfs namespace) that
the static timestamp callback member can see and use.

Add a test of the feature in CI.

Fixes #7682
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants