fix: revert FTP task and calcDirSize (solves timeouts and crashes)
- Remove recursive calcDirSize because it blocks the CPU for several seconds during SD card traversal, causing FTP TCP connections to timeout before the welcome banner is sent. - Remove FreeRTOS FTP task entirely. SimpleFTPServer relies on underlying Arduino WiFi mechanisms that aren't cleanly isolated into preemptive tasks; running it concurrently with LVGL screen updates and SD_MMC driver calls caused crashes and starvation. - Restore tpSrv.handleFTP() to the main loop() as intended by the library.
This commit is contained in:
+6
-48
@@ -107,36 +107,10 @@ static void updateLed() {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Get used / total space on SD card in MiB and push to UI */
|
/** Get used / total space on SD card in MiB and push to UI */
|
||||||
static uint64_t calcDirSize(fs::FS &fs, const char *dirname) {
|
|
||||||
uint64_t total = 0;
|
|
||||||
File root = fs.open(dirname);
|
|
||||||
if (!root || !root.isDirectory()) return 0;
|
|
||||||
File f;
|
|
||||||
while ((f = root.openNextFile())) {
|
|
||||||
if (f.isDirectory()) {
|
|
||||||
/* On ESP32 Arduino 3.x, f.path() returns the full path */
|
|
||||||
String fullPath = String(f.path());
|
|
||||||
f.close();
|
|
||||||
total += calcDirSize(fs, fullPath.c_str());
|
|
||||||
} else {
|
|
||||||
total += f.size();
|
|
||||||
f.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
root.close();
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateSdInfo() {
|
static void updateSdInfo() {
|
||||||
if (!sd_ok) return;
|
if (!sd_ok) return;
|
||||||
uint64_t total = SD_MMC.totalBytes() / (1024ULL * 1024ULL);
|
uint64_t total = SD_MMC.totalBytes() / (1024ULL * 1024ULL);
|
||||||
uint64_t used = SD_MMC.usedBytes() / (1024ULL * 1024ULL);
|
uint64_t used = SD_MMC.usedBytes() / (1024ULL * 1024ULL);
|
||||||
/* Skip heavy filesystem walk while FTP is active (concurrent SD_MMC
|
|
||||||
access from core 0 + core 1 causes null pointer crashes) */
|
|
||||||
if (used == 0 && total > 0 && !ftp_client_on) {
|
|
||||||
uint64_t walked = calcDirSize(SD_MMC, "/");
|
|
||||||
used = walked / (1024ULL * 1024ULL);
|
|
||||||
}
|
|
||||||
ui_set_sd(used, total);
|
ui_set_sd(used, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +120,6 @@ static void updateSdInfo() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on FTP connect / disconnect events.
|
* Called on FTP connect / disconnect events.
|
||||||
* NOTE: Runs on the FTP task (core 0) — only set flags here, never call LVGL/UI.
|
|
||||||
*/
|
*/
|
||||||
void ftpCallback(FtpOperation ftpOperation, uint32_t freeSpace, uint32_t totalSpace) {
|
void ftpCallback(FtpOperation ftpOperation, uint32_t freeSpace, uint32_t totalSpace) {
|
||||||
switch (ftpOperation) {
|
switch (ftpOperation) {
|
||||||
@@ -175,7 +148,6 @@ void ftpCallback(FtpOperation ftpOperation, uint32_t freeSpace, uint32_t totalSp
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called during file transfer operations.
|
* Called during file transfer operations.
|
||||||
* NOTE: Runs on the FTP task (core 0) — only set flags here, never call LVGL/UI.
|
|
||||||
*/
|
*/
|
||||||
void ftpTransferCallback(FtpTransferOperation ftpOperation, const char *name, uint32_t transferredSize) {
|
void ftpTransferCallback(FtpTransferOperation ftpOperation, const char *name, uint32_t transferredSize) {
|
||||||
switch (ftpOperation) {
|
switch (ftpOperation) {
|
||||||
@@ -449,20 +421,7 @@ static void initNtp() {
|
|||||||
Serial.println("[NTP] Warning: time not yet synced (will update in background)");
|
Serial.println("[NTP] Warning: time not yet synced (will update in background)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FTP task — runs handleFTP() in a dedicated loop on core 1
|
/** Start FTP server with callbacks */
|
||||||
* NOTE: Must run on core 1 (not core 0) because WiFi runs on core 0
|
|
||||||
* and handleFTP() needs WiFi sockets to work. Running on core 0 at
|
|
||||||
* higher priority starves WiFi, preventing welcome banner from sending.
|
|
||||||
*/
|
|
||||||
static void ftpTask(void *param) {
|
|
||||||
(void)param;
|
|
||||||
for (;;) {
|
|
||||||
ftpSrv.handleFTP();
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(2)); // yield 2ms to let LVGL run
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Start FTP server with callbacks and launch dedicated task */
|
|
||||||
static void initFtp() {
|
static void initFtp() {
|
||||||
Serial.println("[FTP] Starting FTP server (user: kode, port: 21)...");
|
Serial.println("[FTP] Starting FTP server (user: kode, port: 21)...");
|
||||||
ftpSrv.setCallback(ftpCallback);
|
ftpSrv.setCallback(ftpCallback);
|
||||||
@@ -471,11 +430,7 @@ static void initFtp() {
|
|||||||
ftpSrv.setLocalIp(WiFi.localIP());
|
ftpSrv.setLocalIp(WiFi.localIP());
|
||||||
ftpSrv.begin("kode", "kode");
|
ftpSrv.begin("kode", "kode");
|
||||||
|
|
||||||
/* Run FTP in its own task on core 1 (same as Arduino) — core 0 is
|
Serial.printf("[FTP] FTP server ready (PASV IP: %s, data port: 50009)\n",
|
||||||
reserved for WiFi/networking stack, running FTP there starves it */
|
|
||||||
xTaskCreatePinnedToCore(ftpTask, "ftp", 32768, NULL, 2, NULL, 1);
|
|
||||||
|
|
||||||
Serial.printf("[FTP] FTP server ready on core 0 (PASV IP: %s, data port: 50009)\n",
|
|
||||||
WiFi.localIP().toString().c_str());
|
WiFi.localIP().toString().c_str());
|
||||||
ui_set_ftp("Idle");
|
ui_set_ftp("Idle");
|
||||||
}
|
}
|
||||||
@@ -572,7 +527,10 @@ void setup() {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
/* Process FTP status flags (set by callbacks on core 0, consumed here on core 1) */
|
/* Handle FTP client requests */
|
||||||
|
ftpSrv.handleFTP();
|
||||||
|
|
||||||
|
/* Process FTP status flags (set by callbacks) */
|
||||||
if (ftp_ui_dirty) {
|
if (ftp_ui_dirty) {
|
||||||
ftp_ui_dirty = false;
|
ftp_ui_dirty = false;
|
||||||
static const char *ftp_st_str[] = {"Idle", "Connected", "Transferring"};
|
static const char *ftp_st_str[] = {"Idle", "Connected", "Transferring"};
|
||||||
|
|||||||
Reference in New Issue
Block a user