Created
November 28, 2020 22:06
-
-
Save ciniml/6cd9dc15e58d9b3ab2abae65a6873ce4 to your computer and use it in GitHub Desktop.
M5Paper Storage Benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <M5EPD.h> | |
#include <Free_Fonts.h> | |
#include <WiFi.h> | |
#include <lwip/sockets.h> | |
#include <lwip/netdb.h> | |
#include <cstdio> | |
#include <cstdlib> | |
#include <cstdint> | |
#include <cstring> | |
#include <memory> | |
#include <array> | |
#include <cstdarg> | |
#include <SPIFFS.h> | |
#include <SD.h> | |
#include <esp_spi_flash.h> | |
#define TFCARD_CS_PIN 4 | |
class CBFSBench | |
{ | |
public: | |
String tmpFile{"/lovyanLauncherBench"}; | |
virtual const char* name() = 0; | |
uint64_t getWriteTime(fs::FS& fs, const String& filepath, long filesize, int loop) volatile { | |
File f; | |
uint64_t res = 0; | |
uint8_t buf[SPI_FLASH_SEC_SIZE]; | |
for (int i = 0; i < SPI_FLASH_SEC_SIZE; ++i) { buf[i] = uint8_t(i & 0xFF); } | |
for (int i = 0; i < loop; ++i) { | |
long rest = filesize; | |
uint64_t start = micros(); | |
f = fs.open(filepath + String(i), FILE_WRITE); | |
do { | |
long size = rest > SPI_FLASH_SEC_SIZE ? SPI_FLASH_SEC_SIZE : rest; | |
f.write(&buf[0], size); | |
rest -= size; | |
} while (rest > 0); | |
f.flush(); | |
f.close(); | |
res += micros() - start; | |
} | |
return res / loop; | |
} | |
uint64_t getReadTime(fs::FS& fs, const String& filepath, long filesize, int loop) volatile { | |
File f; | |
uint64_t res = 0; | |
uint8_t buf[SPI_FLASH_SEC_SIZE]; | |
for ( int i = 0; i < loop; ++i) { | |
long rest = filesize; | |
uint64_t start = micros(); | |
f = fs.open(filepath + String(i), FILE_READ); | |
do { | |
long size = rest > SPI_FLASH_SEC_SIZE ? SPI_FLASH_SEC_SIZE : rest; | |
f.read(&buf[0], size); | |
rest -= size; | |
} while (rest > 0); | |
f.close(); | |
res += micros() - start; | |
fs.remove(filepath + String(i)); | |
} | |
return res / loop; | |
} | |
uint64_t getCreateTime(fs::FS& fs, const String& filepath, int loop) volatile { | |
uint64_t start = micros(); | |
for ( int i = 0; i < loop; ++i) { | |
fs.open(filepath + String(i), FILE_WRITE).close(); | |
} | |
return (micros() - start) / loop; | |
} | |
uint64_t getOpenCloseTime(fs::FS& fs, const String& filepath, int loop) volatile { | |
uint64_t start = micros(); | |
for ( int i = 0; i < loop; ++i) { | |
fs.open(filepath + String(i), FILE_READ).close(); | |
} | |
return (micros() - start) / loop; | |
} | |
uint64_t getRemoveTime(fs::FS& fs, const String& filepath, int loop) volatile { | |
uint64_t start = micros(); | |
for (int i = 0; i < loop; ++i) { | |
fs.remove(filepath + String(i)); | |
} | |
return (micros() - start) / loop; | |
} | |
virtual fs::FS& getFS() = 0; | |
virtual void init() = 0; | |
virtual uint64_t totalBytes() { return 0; } | |
virtual uint64_t usedBytes() { return 0; } | |
}; | |
class CBFSBenchSD : public CBFSBench | |
{ | |
const char* name() { return "SD"; } | |
fs::FS& getFS() override { return SD; } | |
uint64_t totalBytes() override { return SD.totalBytes(); } | |
uint64_t usedBytes() override { return SD.usedBytes(); } | |
void init() override | |
{ | |
SD.end(); | |
SD.begin( TFCARD_CS_PIN, SPI, 40000000); | |
} | |
}; | |
class CBFSBenchSPIFFS : public CBFSBench | |
{ | |
const char* name() { return "SPIFFS"; } | |
fs::FS& getFS() override { return SPIFFS; } | |
uint64_t totalBytes() override{ return SPIFFS.totalBytes(); } | |
uint64_t usedBytes() override { return SPIFFS.usedBytes(); } | |
void init() override | |
{ | |
SPIFFS.begin(true); | |
} | |
}; | |
static CBFSBenchSD bench_sd; | |
static CBFSBenchSPIFFS bench_spiffs; | |
static CBFSBench* const benches[] = {&bench_sd, &bench_spiffs}; | |
struct ReadWriteResult | |
{ | |
std::uint64_t read_time; | |
std::uint64_t write_time; | |
std::uint64_t size_in_kib; | |
}; | |
static void printLine(M5EPD_Canvas& canvas, char* line_buffer, int x, int y, const char* fmt, ...) | |
{ | |
va_list arg; | |
va_start(arg, fmt); | |
std::vsprintf(line_buffer, fmt, arg); | |
canvas.fillCanvas(0); | |
canvas.drawString(line_buffer, 0, 0); | |
canvas.pushCanvas(x, y, m5epd_update_mode_t::UPDATE_MODE_DU); | |
va_end(arg); | |
} | |
void setup() | |
{ | |
pinMode(M5EPD_MAIN_PWR_PIN, OUTPUT); | |
M5.enableMainPower(); | |
pinMode(M5EPD_EXT_PWR_EN_PIN, OUTPUT); | |
pinMode(M5EPD_EPD_PWR_EN_PIN, OUTPUT); | |
pinMode(M5EPD_KEY_RIGHT_PIN, INPUT); | |
pinMode(M5EPD_KEY_PUSH_PIN, INPUT); | |
pinMode(M5EPD_KEY_LEFT_PIN, INPUT); | |
delay(100); | |
M5.enableEXTPower(); | |
M5.enableEPDPower(); | |
delay(1000); | |
// M5.begin(); | |
// M5.EPD.Clear(true); | |
// M5.EPD.SetRotation(IT8951_ROTATE_90); | |
// M5EPD_Canvas canvas(&M5.EPD); | |
// canvas.createCanvas(540, 50); | |
// //canvas.setFreeFont(FF18); | |
// //canvas.setTextSize(1); | |
// canvas.setTextSize(1); | |
// canvas.setTextDatum(TL_DATUM); | |
// canvas.setTextColor(15); | |
// canvas.drawString("Hoge Fuga Piyo", 0, 0); | |
// canvas.pushCanvas(0, 0, m5epd_update_mode_t::UPDATE_MODE_DU); | |
SPI.begin(14, 13, 12, 4); | |
SD.begin( TFCARD_CS_PIN, SPI, 40000000); | |
Serial.begin(115200); | |
const int loop = 20; | |
const int height = 20; | |
int y = height; | |
char buffer[80]; | |
for(auto bench : benches) { | |
// y += height; printLine(canvas, buffer, 0, y, "FS: %s", bench->name()); | |
Serial.printf("FS: %s\r\n", bench->name()); | |
bench->init(); | |
auto create_time = bench->getCreateTime(bench->getFS(), bench->tmpFile, loop); | |
auto open_close_time = bench->getOpenCloseTime(bench->getFS(), bench->tmpFile, loop); | |
auto remove_time = bench->getRemoveTime(bench->getFS(), bench->tmpFile, loop); | |
std::array<ReadWriteResult, 5> read_write_times; | |
for ( int i = 0; i < read_write_times.max_size(); ++i ) { | |
auto& read_write_time = read_write_times[i]; | |
read_write_time.write_time = bench->getWriteTime(bench->getFS(), bench->tmpFile, (4 << i) * 1024, 8 - i); | |
read_write_time.read_time = bench->getReadTime(bench->getFS(), bench->tmpFile, (4 << i) * 1024, 8 - i); | |
read_write_time.size_in_kib = 4 << i; | |
} | |
// y += height; printLine(canvas, buffer, 0, y, "Create : %llu [us] %llu [counts/s]", create_time, 1000000ul / create_time); | |
// y += height; printLine(canvas, buffer, 0, y, "OpenClose: %llu [us] %llu [counts/s]", open_close_time, 1000000ul / open_close_time); | |
// y += height; printLine(canvas, buffer, 0, y, "Remove : %llu [us] %llu [counts/s]", remove_time, 1000000ul / remove_time); | |
// for(const auto& read_write_time : read_write_times) { | |
// y += height; printLine(canvas, buffer, 0, y, "Read %llu[KiB]: %llu [us] %llu [KiB/s]", read_write_time.size_in_kib, read_write_time.read_time, 1000000ul * read_write_time.size_in_kib / read_write_time.read_time); | |
// y += height; printLine(canvas, buffer, 0, y, "Write %llu[KiB]: %llu [us] %llu [KiB/s]", read_write_time.size_in_kib, read_write_time.write_time, 1000000ul * read_write_time.size_in_kib / read_write_time.write_time); | |
// } | |
Serial.printf("Create : %llu [us] %llu [counts/s]\r\n", create_time, 1000000ull / create_time); | |
Serial.printf("OpenClose: %llu [us] %llu [counts/s]\r\n", open_close_time, 1000000ull / open_close_time); | |
Serial.printf("Remove : %llu [us] %llu [counts/s]\r\n", remove_time, 1000000ull / remove_time); | |
for(const auto& read_write_time : read_write_times) { | |
Serial.printf("Read %llu[KiB]: %llu [us] %llu [KiB/s]\r\n", read_write_time.size_in_kib, read_write_time.read_time, 1000000ull * read_write_time.size_in_kib / read_write_time.read_time); | |
Serial.printf("Write %llu[KiB]: %llu [us] %llu [KiB/s]\r\n", read_write_time.size_in_kib, read_write_time.write_time, 1000000ull * read_write_time.size_in_kib / read_write_time.write_time); | |
} | |
} | |
} | |
void loop() | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment