mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-08-11 23:49:02 +08:00
SD wrapper backbone
This commit is contained in:
parent
99bcdd47af
commit
c02e922aa4
@ -62,6 +62,11 @@
|
||||
#define ESP_FAT_FILESYSTEM 2
|
||||
#define ESP_LITTLEFS_FILESYSTEM 3
|
||||
|
||||
//SD
|
||||
#define ESP_SD_NATIVE 1
|
||||
#define ESP_SDIO 2
|
||||
#define ESP_SDFAT 3
|
||||
|
||||
//Notifications
|
||||
#define ESP_PUSHOVER_NOTIFICATION 1
|
||||
#define ESP_EMAIL_NOTIFICATION 2
|
||||
|
188
esp3d/src/modules/sd/esp_sd.cpp
Normal file
188
esp3d/src/modules/sd/esp_sd.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
esp_sd.cpp - ESP3D SD support class
|
||||
|
||||
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "../../include/esp3d_config.h"
|
||||
#ifdef SD_FEATURE
|
||||
#include "esp_sd.h"
|
||||
#include "../../core/genLinkedList.h"
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
#include <time.h>
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
#include <FS.h>
|
||||
|
||||
|
||||
#define ESP_MAX_SD_OPENHANDLE 4
|
||||
File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
|
||||
|
||||
bool ESP_SD::_started = false;
|
||||
|
||||
//constructor
|
||||
ESP_SD::ESP_SD()
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
ESP_SD::~ESP_SD()
|
||||
{
|
||||
}
|
||||
|
||||
//helper to format size to readable string
|
||||
String & ESP_SD::formatBytes (uint64_t bytes)
|
||||
{
|
||||
static String res;
|
||||
if (bytes < 1024) {
|
||||
res = String ((uint16_t)bytes) + " B";
|
||||
} else if (bytes < (1024 * 1024) ) {
|
||||
res = String ((float)(bytes / 1024.0),2) + " KB";
|
||||
} else if (bytes < (1024 * 1024 * 1024) ) {
|
||||
res = String ((float)(bytes / 1024.0 / 1024.0),2) + " MB";
|
||||
} else {
|
||||
res = String ((float)(bytes / 1024.0 / 1024.0 / 1024.0),2) + " GB";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ESP_SDFile::ESP_SDFile(const char * name, const char * filename, bool isdir, size_t size)
|
||||
{
|
||||
_isdir = isdir;
|
||||
_dirlist = "";
|
||||
_isfakedir = isdir;
|
||||
_index = -1;
|
||||
_filename = filename;
|
||||
_name = name;
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
memset (&_lastwrite,0,sizeof(time_t));
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
_iswritemode = false;
|
||||
_size = size;
|
||||
}
|
||||
|
||||
ESP_SDFile::~ESP_SDFile()
|
||||
{
|
||||
//log_esp3d("Destructor %s index %d",(_isdir)?"Dir":"File", _index);
|
||||
}
|
||||
|
||||
ESP_SDFile::operator bool() const
|
||||
{
|
||||
if ((_index != -1) || (_filename.length() > 0)) {
|
||||
//log_esp3d("Bool yes %d %d",_index, _filename.length());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ESP_SDFile::isOpen()
|
||||
{
|
||||
return !(_index == -1);
|
||||
}
|
||||
|
||||
const char* ESP_SDFile::name() const
|
||||
{
|
||||
return _name.c_str();
|
||||
}
|
||||
|
||||
const char* ESP_SDFile::filename() const
|
||||
{
|
||||
return _filename.c_str();
|
||||
}
|
||||
|
||||
bool ESP_SDFile::isDirectory()
|
||||
{
|
||||
return _isdir;
|
||||
}
|
||||
|
||||
size_t ESP_SDFile::size()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
time_t ESP_SDFile::getLastWrite()
|
||||
{
|
||||
return _lastwrite;
|
||||
}
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
|
||||
int ESP_SDFile::available()
|
||||
{
|
||||
if (_index == -1 || _isdir) {
|
||||
return 0;
|
||||
}
|
||||
return tSDFile_handle[_index].available();
|
||||
}
|
||||
|
||||
size_t ESP_SDFile::write(uint8_t i)
|
||||
{
|
||||
if ((_index == -1) || _isdir) {
|
||||
return 0;
|
||||
}
|
||||
return tSDFile_handle[_index].write (i);
|
||||
}
|
||||
|
||||
size_t ESP_SDFile::write(const uint8_t *buf, size_t size)
|
||||
{
|
||||
if ((_index == -1) || _isdir) {
|
||||
return 0;
|
||||
}
|
||||
return tSDFile_handle[_index].write (buf, size);
|
||||
}
|
||||
|
||||
int ESP_SDFile::read()
|
||||
{
|
||||
if ((_index == -1) || _isdir) {
|
||||
return -1;
|
||||
}
|
||||
return tSDFile_handle[_index].read();
|
||||
}
|
||||
|
||||
size_t ESP_SDFile::read(uint8_t* buf, size_t size)
|
||||
{
|
||||
if ((_index == -1) || _isdir) {
|
||||
return -1;
|
||||
}
|
||||
return tSDFile_handle[_index].read(buf, size);
|
||||
}
|
||||
|
||||
void ESP_SDFile::flush()
|
||||
{
|
||||
if ((_index == -1) || _isdir) {
|
||||
return;
|
||||
}
|
||||
tSDFile_handle[_index].flush();
|
||||
}
|
||||
|
||||
ESP_SDFile& ESP_SDFile::operator=(const ESP_SDFile & other)
|
||||
{
|
||||
//log_esp3d("Copy %s", other._filename.c_str());
|
||||
_isdir = other._isdir;
|
||||
_isfakedir = other._isfakedir;
|
||||
_index = other._index;
|
||||
_filename = other._filename;
|
||||
_name = other._name;
|
||||
_size = other._size;
|
||||
_iswritemode = other._iswritemode;
|
||||
_dirlist = other._dirlist;
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
memcpy(&_lastwrite, &(other._lastwrite), sizeof (time_t));
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif //SD_FEATURE
|
100
esp3d/src/modules/sd/esp_sd.h
Normal file
100
esp3d/src/modules/sd/esp_sd.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
esp_sd.h - ESP3D SD support class
|
||||
|
||||
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _ESP_SD_H
|
||||
#define _ESP_SD_H
|
||||
#include "../../include/esp3d_config.h"
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
#include <time.h>
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
#define ESP_SD_FILE_READ 0
|
||||
#define ESP_SD_FILE_WRITE 1
|
||||
#define ESP_SD_FILE_APPEND 2
|
||||
|
||||
#define ESP_SD_HEADER "/SD:"
|
||||
|
||||
#define ESP_MAX_SD_OPENHANDLE 4
|
||||
|
||||
class ESP_SDFile
|
||||
{
|
||||
public:
|
||||
ESP_SDFile(void * handle = nullptr, bool isdir =false, bool iswritemode = false, const char * path = nullptr);
|
||||
ESP_SDFile(const char * name, const char * filename, bool isdir = true, size_t size =0);
|
||||
~ESP_SDFile();
|
||||
operator bool() const;
|
||||
bool isDirectory();
|
||||
const char* name() const;
|
||||
const char* filename() const;
|
||||
void close();
|
||||
bool isOpen();
|
||||
ESP_SDFile & operator=(const ESP_SDFile & other);
|
||||
size_t size();
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
time_t getLastWrite();
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
int available();
|
||||
size_t write(uint8_t i);
|
||||
size_t write(const uint8_t *buf, size_t size);
|
||||
int read();
|
||||
size_t read(uint8_t* buf, size_t size);
|
||||
void flush();
|
||||
ESP_SDFile openNextFile();
|
||||
private:
|
||||
String _dirlist;
|
||||
bool _isdir;
|
||||
bool _isfakedir;
|
||||
bool _iswritemode;
|
||||
int8_t _index;
|
||||
String _filename;
|
||||
String _name;
|
||||
size_t _size;
|
||||
#ifdef SD_TIMESTAMP_FEATURE
|
||||
time_t _lastwrite;
|
||||
#endif //SD_TIMESTAMP_FEATURE
|
||||
};
|
||||
|
||||
class ESP_SD
|
||||
{
|
||||
public:
|
||||
static String & formatBytes (uint64_t bytes);
|
||||
ESP_SD();
|
||||
~ESP_SD();
|
||||
static bool begin();
|
||||
static void end();
|
||||
static size_t totalBytes();
|
||||
static size_t usedBytes();
|
||||
static size_t freeBytes()
|
||||
{
|
||||
return totalBytes()-usedBytes();
|
||||
};
|
||||
static const char * FilesystemName();
|
||||
static bool format();
|
||||
static ESP_File open(const char* path, uint8_t mode = ESP_SD_FILE_READ);
|
||||
static bool exists(const char* path);
|
||||
static bool remove(const char *path);
|
||||
static bool mkdir(const char *path);
|
||||
static bool rmdir(const char *path);
|
||||
static void closeAll();
|
||||
private:
|
||||
static bool _started;
|
||||
};
|
||||
|
||||
|
||||
#endif //_ESP_SD_H
|
295
esp3d/src/modules/sd/sd_esp32.cpp
Normal file
295
esp3d/src/modules/sd/sd_esp32.cpp
Normal file
@ -0,0 +1,295 @@
|
||||
/*
|
||||
sd_native_esp32.cpp - ESP3D sd support class
|
||||
|
||||
Copyright (c) 2014 Luc Lebosse. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "../../include/esp3d_config.h"
|
||||
#if defined (ARCH_ESP32) && defined(SD_FEATURE)
|
||||
#if (SD_FEATURE == ESP_SD_NATIVE)
|
||||
#include "esp_sd.h"
|
||||
#include "FS.h"
|
||||
#include "SD.h"
|
||||
|
||||
extern File tSDFile_handle[ESP_MAX_SD_OPENHANDLE];
|
||||
|
||||
bool ESP_SDFileSystem::begin()
|
||||
{
|
||||
_started = SD.begin();
|
||||
return _started;
|
||||
}
|
||||
|
||||
void ESP_SDFileSystem::end()
|
||||
{
|
||||
SD.end();
|
||||
_started = false;
|
||||
}
|
||||
|
||||
size_t ESP_SDFileSystem::totalBytes()
|
||||
{
|
||||
return SD.totalBytes();
|
||||
}
|
||||
|
||||
size_t ESP_SDFileSystem::usedBytes()
|
||||
{
|
||||
return (SD.totalBytes() - SD.freeBytes());
|
||||
}
|
||||
|
||||
|
||||
const char * ESP_SDFileSystem::FilesystemName()
|
||||
{
|
||||
return "FAT";
|
||||
}
|
||||
|
||||
bool ESP_SDFileSystem::format()
|
||||
{
|
||||
return SD.format();
|
||||
}
|
||||
|
||||
ESP_SDFile ESP_SDFileSystem::open(const char* path, uint8_t mode)
|
||||
{
|
||||
//do some check
|
||||
if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) {
|
||||
return ESP_SDFile();
|
||||
}
|
||||
// path must start by '/'
|
||||
if (path[0] != '/') {
|
||||
return ESP_SDFile();
|
||||
}
|
||||
if (mode != ESP_FILE_READ) {
|
||||
//check container exists
|
||||
String p = path;
|
||||
p.remove(p.lastIndexOf('/') +1);
|
||||
if (!exists(p.c_str())) {
|
||||
log_esp3d("Error opening: %s", path);
|
||||
return ESP_SDFile();
|
||||
}
|
||||
}
|
||||
File tmp = SD.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND);
|
||||
ESP_SDFile esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path);
|
||||
return esptmp;
|
||||
}
|
||||
|
||||
bool ESP_SDFileSystem::exists(const char* path)
|
||||
{
|
||||
bool res = false;
|
||||
//root should always be there if started
|
||||
if (strcmp(path, "/") == 0) {
|
||||
return _started;
|
||||
}
|
||||
res = SD.exists(path);
|
||||
if (!res) {
|
||||
ESP_SDFile root = ESP_SDFileSystem::open(path, ESP_FILE_READ);
|
||||
if (root) {
|
||||
res = root.isDirectory();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool ESP_SDFileSystem::remove(const char *path)
|
||||
{
|
||||
return SD.remove(path);
|
||||
}
|
||||
|
||||
bool ESP_SDFileSystem::mkdir(const char *path)
|
||||
{
|
||||
return SD.mkdir(path);
|
||||
}
|
||||
|
||||
bool ESP_SDFileSystem::rmdir(const char *path)
|
||||
{
|
||||
if (!exists(path)) {
|
||||
return false;
|
||||
}
|
||||
bool res = true;
|
||||
GenLinkedList<String > pathlist;
|
||||
String p = path;
|
||||
pathlist.push(p);
|
||||
while (pathlist.count() > 0) {
|
||||
File dir = SD.open(pathlist.getLast().c_str());
|
||||
File f = dir.openNextFile();
|
||||
bool candelete = true;
|
||||
while (f) {
|
||||
if (f.isDirectory()) {
|
||||
candelete = false;
|
||||
String newdir = f.name();
|
||||
pathlist.push(newdir);
|
||||
f.close();
|
||||
f = File();
|
||||
} else {
|
||||
SD.remove(f.name());
|
||||
f.close();
|
||||
f = dir.openNextFile();
|
||||
}
|
||||
}
|
||||
if (candelete) {
|
||||
if (pathlist.getLast() !="/") {
|
||||
res = SD.rmdir(pathlist.getLast().c_str());
|
||||
}
|
||||
pathlist.pop();
|
||||
}
|
||||
dir.close();
|
||||
}
|
||||
p = String();
|
||||
log_esp3d("count %d", pathlist.count());
|
||||
return res;
|
||||
}
|
||||
|
||||
void ESP_SDFileSystem::closeAll()
|
||||
{
|
||||
for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) {
|
||||
tSDFile_handle[i].close();
|
||||
tSDFile_handle[i] = File();
|
||||
}
|
||||
}
|
||||
|
||||
ESP_SDFile::ESP_SDFile(void* handle, bool isdir, bool iswritemode, const char * path)
|
||||
{
|
||||
_isdir = isdir;
|
||||
_dirlist = "";
|
||||
_isfakedir = false;
|
||||
_index = -1;
|
||||
_filename = "";
|
||||
_name = "";
|
||||
#ifdef FILESYSTEM_TIMESTAMP_FEATURE
|
||||
memset (&_lastwrite,0,sizeof(time_t));
|
||||
#endif //FILESYSTEM_TIMESTAMP_FEATURE
|
||||
_iswritemode = iswritemode;
|
||||
_size = 0;
|
||||
if (!handle) {
|
||||
return ;
|
||||
}
|
||||
bool set =false;
|
||||
for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) {
|
||||
if (!tSDFile_handle[i]) {
|
||||
tSDFile_handle[i] = *((File*)handle);
|
||||
//filename
|
||||
_filename = tSDFile_handle[i].name();
|
||||
|
||||
//if root
|
||||
if (_filename == "/") {
|
||||
_filename = "/.";
|
||||
}
|
||||
if (_isdir) {
|
||||
if (_filename[_filename.length()-1] != '.') {
|
||||
if (_filename[_filename.length()-2] != '/') {
|
||||
_filename+="/";
|
||||
}
|
||||
_filename+=".";
|
||||
}
|
||||
}
|
||||
//name
|
||||
if (_filename == "/.") {
|
||||
_name = "/";
|
||||
} else {
|
||||
_name = _filename;
|
||||
if (_name.endsWith("/.")) {
|
||||
_name.remove( _name.length() - 2,2);
|
||||
_isfakedir = true;
|
||||
_isdir = true;
|
||||
}
|
||||
if (_name[0] == '/') {
|
||||
_name.remove( 0, 1);
|
||||
}
|
||||
int pos = _name.lastIndexOf('/');
|
||||
if (pos != -1) {
|
||||
_name.remove( 0, pos+1);
|
||||
}
|
||||
}
|
||||
//size
|
||||
_size = tSDFile_handle[i].size();
|
||||
//time
|
||||
#ifdef FILESYSTEM_TIMESTAMP_FEATURE
|
||||
_lastwrite = tSDFile_handle[i].getLastWrite();
|
||||
#endif //FILESYSTEM_TIMESTAMP_FEATURE
|
||||
_index = i;
|
||||
//log_esp3d("Opening File at index %d",_index);
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ESP_SDFile::close()
|
||||
{
|
||||
if (_index != -1) {
|
||||
//log_esp3d("Closing File at index %d", _index);
|
||||
tSDFile_handle[_index].close();
|
||||
//reopen if mode = write
|
||||
//udate size + date
|
||||
if (_iswritemode && !_isdir) {
|
||||
File ftmp = SD.open(_filename.c_str());
|
||||
if (ftmp) {
|
||||
_size = ftmp.size();
|
||||
#ifdef FILESYSTEM_TIMESTAMP_FEATURE
|
||||
_lastwrite = ftmp.getLastWrite();
|
||||
#endif //FILESYSTEM_TIMESTAMP_FEATURE
|
||||
ftmp.close();
|
||||
}
|
||||
}
|
||||
tSDFile_handle[_index] = File();
|
||||
//log_esp3d("Closing File at index %d",_index);
|
||||
_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_SDFile ESP_SDFile::openNextFile()
|
||||
{
|
||||
if ((_index == -1) || !_isdir) {
|
||||
log_esp3d("openNextFile failed");
|
||||
return ESP_SDFile();
|
||||
}
|
||||
File tmp = tSDFile_handle[_index].openNextFile();
|
||||
while (tmp) {
|
||||
log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile");
|
||||
ESP_SDFile esptmp(&tmp, tmp.isDirectory());
|
||||
esptmp.close();
|
||||
String sub = esptmp.filename();
|
||||
sub.remove(0,_filename.length()-1);
|
||||
int pos = sub.indexOf("/");
|
||||
if (pos!=-1) {
|
||||
//is subdir
|
||||
sub = sub.substring(0,pos);
|
||||
//log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
|
||||
String tag = "*" + sub + "*";
|
||||
//test if already in directory list
|
||||
if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info
|
||||
_dirlist+= tag;
|
||||
String fname = _filename.substring(0,_filename.length()-1) + sub + "/.";
|
||||
//log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str());
|
||||
esptmp = ESP_SDFile(sub.c_str(), fname.c_str());
|
||||
return esptmp;
|
||||
} else { //already in list so ignore it
|
||||
//log_esp3d("Dir name: %s already in list", sub.c_str());
|
||||
tmp = tSDFile_handle[_index].openNextFile();
|
||||
}
|
||||
} else { //is file
|
||||
//log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str());
|
||||
if (sub == ".") {
|
||||
//log_esp3d("Dir tag, ignore it");
|
||||
tmp = tSDFile_handle[_index].openNextFile();
|
||||
} else {
|
||||
return esptmp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return ESP_SDFile();
|
||||
}
|
||||
|
||||
|
||||
#endif //SD_FEATURE == ESP_SD_NATIVE
|
||||
#endif //ARCH_ESP32 && SD_FEATURE
|
Loading…
x
Reference in New Issue
Block a user