Public Access
A failed mount retries for ~2.5 s, which froze the UI every 15 s while no card was inserted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
64 lines
1.4 KiB
C++
64 lines
1.4 KiB
C++
#include "storage_service.h"
|
|
|
|
#include <SD.h>
|
|
|
|
#include "platform/pins.h"
|
|
#include "platform/shared_spi.h"
|
|
|
|
namespace roro {
|
|
|
|
void StorageService::start() {
|
|
if (task_) return;
|
|
lock_ = xSemaphoreCreateMutex();
|
|
xTaskCreate(taskEntry, "storage", 4096, this, 1, &task_);
|
|
}
|
|
|
|
void StorageService::stop() {
|
|
if (!task_) return;
|
|
vTaskDelete(task_);
|
|
task_ = nullptr;
|
|
if (mounted_) SD.end();
|
|
mounted_ = false;
|
|
}
|
|
|
|
StorageState StorageService::state() const {
|
|
xSemaphoreTake(lock_, portMAX_DELAY);
|
|
StorageState copy = monitor_.state();
|
|
xSemaphoreGive(lock_);
|
|
return copy;
|
|
}
|
|
|
|
void StorageService::taskEntry(void* self) {
|
|
auto* service = static_cast<StorageService*>(self);
|
|
for (;;) {
|
|
service->poll();
|
|
vTaskDelay(pdMS_TO_TICKS(kPollMs));
|
|
}
|
|
}
|
|
|
|
bool StorageService::mount() {
|
|
return SD.begin(pins::kSdCs, sharedSpi(), 20000000, "/sd", 5, false);
|
|
}
|
|
|
|
void StorageService::poll() {
|
|
if (mounted_) {
|
|
// Detect removal: the root can no longer be opened.
|
|
File root = SD.open("/");
|
|
if (!root) {
|
|
SD.end();
|
|
mounted_ = false;
|
|
}
|
|
}
|
|
if (!mounted_) mounted_ = mount();
|
|
|
|
bool present = mounted_;
|
|
uint64_t total = present ? SD.totalBytes() : 0;
|
|
uint64_t used = present ? SD.usedBytes() : 0;
|
|
|
|
xSemaphoreTake(lock_, portMAX_DELAY);
|
|
monitor_.update(present, total, used);
|
|
xSemaphoreGive(lock_);
|
|
}
|
|
|
|
} // namespace roro
|