Basic working SD card.'
This commit is contained in:
@@ -228,6 +228,115 @@ fs::FS& SDManager::fs()
|
||||
}
|
||||
|
||||
|
||||
StorageCardType SDManager::cardType() const
|
||||
{
|
||||
if (mounted && backend != nullptr)
|
||||
{
|
||||
return backend->cardType();
|
||||
}
|
||||
return StorageCardType::None;
|
||||
}
|
||||
|
||||
|
||||
const char* SDManager::cardTypeName() const
|
||||
{
|
||||
return cardTypeName(cardType());
|
||||
}
|
||||
|
||||
|
||||
uint64_t SDManager::totalBytes() const
|
||||
{
|
||||
if (mounted && backend != nullptr)
|
||||
{
|
||||
return backend->totalBytes();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t SDManager::usedBytes() const
|
||||
{
|
||||
if (mounted && backend != nullptr)
|
||||
{
|
||||
return backend->usedBytes();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t SDManager::freeBytes() const
|
||||
{
|
||||
uint64_t total = totalBytes();
|
||||
uint64_t used = usedBytes();
|
||||
return (total > used) ? (total - used) : 0;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SDManager::measureWriteSpeed()
|
||||
{
|
||||
if (!mounted || backend == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs::FS& files = backend->fs();
|
||||
|
||||
const char* scratchPath = STORAGE_SPEED_MEASURE_PATH;
|
||||
const size_t bufferSize = 16 * 1024;
|
||||
|
||||
// Remove any leftover from a previous crashed run.
|
||||
files.remove(scratchPath);
|
||||
|
||||
uint8_t* buffer = (uint8_t*)malloc(bufferSize);
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(buffer, 0xA5, bufferSize);
|
||||
|
||||
File file = files.open(scratchPath, FILE_WRITE);
|
||||
if (!file)
|
||||
{
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t remaining = STORAGE_SPEED_MEASURE_BYTES;
|
||||
uint32_t startUs = micros();
|
||||
|
||||
while (remaining > 0)
|
||||
{
|
||||
size_t toWrite = (remaining < bufferSize) ? remaining : bufferSize;
|
||||
size_t written = file.write(buffer, toWrite);
|
||||
|
||||
if (written == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
remaining -= written;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
uint32_t elapsedUs = micros() - startUs;
|
||||
Serial.print("Elapsed microseconds: ");
|
||||
Serial.println(elapsedUs);
|
||||
|
||||
files.remove(scratchPath);
|
||||
free(buffer);
|
||||
|
||||
if (remaining != 0 || elapsedUs == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t writtenBytes = (uint64_t)STORAGE_SPEED_MEASURE_BYTES - remaining;
|
||||
return (uint32_t)((writtenBytes * 1000000ULL) / elapsedUs);
|
||||
}
|
||||
|
||||
|
||||
const char* SDManager::cardTypeName(StorageCardType type)
|
||||
{
|
||||
switch (type)
|
||||
|
||||
@@ -49,6 +49,17 @@ public:
|
||||
|
||||
fs::FS& fs();
|
||||
|
||||
StorageCardType cardType() const;
|
||||
const char* cardTypeName() const;
|
||||
uint64_t totalBytes() const;
|
||||
uint64_t usedBytes() const;
|
||||
uint64_t freeBytes() const;
|
||||
|
||||
// Writes a scratch file of STORAGE_SPEED_MEASURE_BYTES and returns the
|
||||
// achieved write throughput in bytes/second (0 on failure). The scratch
|
||||
// file is deleted before returning.
|
||||
uint32_t measureWriteSpeed();
|
||||
|
||||
void printCardInfo();
|
||||
void listFiles();
|
||||
|
||||
|
||||
@@ -97,3 +97,18 @@
|
||||
// Maximum directory depth printed during the recursive boot listing. Guards
|
||||
// the StorageTask stack against pathological directory nesting.
|
||||
#define STORAGE_LIST_MAX_DEPTH 10
|
||||
|
||||
// --- Write-speed estimation -------------------------------------------------
|
||||
|
||||
// Path of the temporary scratch file used to measure write throughput. It is
|
||||
// created, written, measured, then deleted, so it never appears in listings.
|
||||
#define STORAGE_SPEED_MEASURE_PATH STORAGE_MOUNT_POINT "/.writespeed.tmp"
|
||||
|
||||
// Size of the scratch file written per measurement (bytes).
|
||||
#define STORAGE_SPEED_MEASURE_BYTES (0.5 * 1024 * 1024)
|
||||
|
||||
// How often to re-measure write speed (ms). This is a bring-up ESTIMATE only:
|
||||
// it writes STORAGE_SPEED_MEASURE_BYTES to the card on every tick. Once real
|
||||
// logging exists, throughput should be derived from actual logging writes and
|
||||
// this benchmark disabled by setting the interval to 0 (measure once at boot).
|
||||
#define STORAGE_SPEED_MEASURE_INTERVAL_MS 0
|
||||
|
||||
Reference in New Issue
Block a user