18
18
//
19
19
// Please use the following Arduino IDE configuration
20
20
//
21
- // * Board: ESP32 Dev Module
22
- // * Partition Scheme: Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
21
+ // * Board: " ESP32 Dev Module" or other board with ESP32
22
+ // * Partition Scheme: " Default 4MB with spiffs" or any other scheme with spiffs or FAT
23
23
// but LittleFS will be used in the partition (not SPIFFS)
24
24
// * other setting as applicable
25
25
//
26
26
// Changelog:
27
27
// 21.07.2021 creation, first version
28
28
// 08.01.2023 ESP32 version with ETag
29
+ // 02.08.2024 support LitteFS and FAT file systems (on large Flash chips)
29
30
30
31
#include < Arduino.h>
31
32
#include < WebServer.h>
32
33
#include < WiFi.h>
33
34
34
35
#include " secrets.h" // add WLAN Credentials in here.
35
36
37
+ #include " esp_partition.h" // to check existing data partitions in Flash memory
38
+
36
39
#include < FS.h> // File System for Web Server Files
37
- #include < LittleFS.h> // This file system is used.
40
+ #include < LittleFS.h> // Use LittleFSThis file system is used.
41
+ #include < FFat.h> // or.. FAT
38
42
39
43
// mark parameters not used in example
40
44
#define UNUSED __attribute__ ((unused))
51
55
// need a WebServer for http access on port 80.
52
56
WebServer server (80 );
53
57
58
+ // The file system in use...
59
+ fs::FS *fsys = nullptr ;
60
+
54
61
// The text of builtin files are in this header file
55
62
#include " builtinfiles.h"
56
63
@@ -65,7 +72,7 @@ void handleRedirect() {
65
72
TRACE (" Redirect...\n " );
66
73
String url = " /index.htm" ;
67
74
68
- if (!LittleFS. exists (url)) {
75
+ if (!fsys-> exists (url)) {
69
76
url = " /$upload.htm" ;
70
77
}
71
78
@@ -76,7 +83,7 @@ void handleRedirect() {
76
83
// This function is called when the WebServer was requested to list all existing files in the filesystem.
77
84
// a JSON array with file information is returned.
78
85
void handleListFiles () {
79
- File dir = LittleFS. open (" /" , " r" );
86
+ File dir = fsys-> open (" /" , " r" );
80
87
String result;
81
88
82
89
result += " [\n " ;
@@ -107,8 +114,15 @@ void handleSysInfo() {
107
114
result += " \" Chip Revision\" : " + String (ESP.getChipRevision ()) + " ,\n " ;
108
115
result += " \" flashSize\" : " + String (ESP.getFlashChipSize ()) + " ,\n " ;
109
116
result += " \" freeHeap\" : " + String (ESP.getFreeHeap ()) + " ,\n " ;
110
- result += " \" fsTotalBytes\" : " + String (LittleFS.totalBytes ()) + " ,\n " ;
111
- result += " \" fsUsedBytes\" : " + String (LittleFS.usedBytes ()) + " ,\n " ;
117
+
118
+ if (fsys == (fs::FS *)&FFat) {
119
+ result += " \" fsTotalBytes\" : " + String (FFat.totalBytes ()) + " ,\n " ;
120
+ result += " \" fsUsedBytes\" : " + String (FFat.usedBytes ()) + " ,\n " ;
121
+ } else {
122
+ result += " \" fsTotalBytes\" : " + String (LittleFS.totalBytes ()) + " ,\n " ;
123
+ result += " \" fsUsedBytes\" : " + String (LittleFS.usedBytes ()) + " ,\n " ;
124
+ }
125
+
112
126
result += " }" ;
113
127
114
128
server.sendHeader (" Cache-Control" , " no-cache" );
@@ -132,11 +146,11 @@ public:
132
146
// @param requestMethod method of the http request line.
133
147
// @param requestUri request resource from the http request line.
134
148
// @return true when method can be handled.
135
- bool canHandle (HTTPMethod requestMethod, String UNUSED uri) override {
149
+ bool canHandle (WebServer &server, HTTPMethod requestMethod, String uri) override {
136
150
return ((requestMethod == HTTP_POST) || (requestMethod == HTTP_DELETE));
137
151
} // canHandle()
138
152
139
- bool canUpload (String uri) override {
153
+ bool canUpload (WebServer &server, String uri) override {
140
154
// only allow upload on root fs level.
141
155
return (uri == " /" );
142
156
} // canUpload()
@@ -148,15 +162,13 @@ public:
148
162
fName = " /" + fName ;
149
163
}
150
164
151
- TRACE (" handle %s\n " , fName .c_str ());
152
-
153
165
if (requestMethod == HTTP_POST) {
154
166
// all done in upload. no other forms.
155
167
156
168
} else if (requestMethod == HTTP_DELETE) {
157
- if (LittleFS. exists (fName )) {
169
+ if (fsys-> exists (fName )) {
158
170
TRACE (" DELETE %s\n " , fName .c_str ());
159
- LittleFS. remove (fName );
171
+ fsys-> remove (fName );
160
172
}
161
173
} // if
162
174
@@ -165,7 +177,7 @@ public:
165
177
} // handle()
166
178
167
179
// uploading process
168
- void upload (WebServer UNUSED &server, String UNUSED _requestUri , HTTPUpload &upload) override {
180
+ void upload (WebServer UNUSED &server, String requestUri , HTTPUpload &upload) override {
169
181
// ensure that filename starts with '/'
170
182
static size_t uploadSize;
171
183
@@ -178,10 +190,10 @@ public:
178
190
}
179
191
TRACE (" start uploading file %s...\n " , fName .c_str ());
180
192
181
- if (LittleFS. exists (fName )) {
182
- LittleFS. remove (fName );
193
+ if (fsys-> exists (fName )) {
194
+ fsys-> remove (fName );
183
195
} // if
184
- _fsUploadFile = LittleFS. open (fName , " w" );
196
+ _fsUploadFile = fsys-> open (fName , " w" );
185
197
uploadSize = 0 ;
186
198
187
199
} else if (upload.status == UPLOAD_FILE_WRITE) {
@@ -198,7 +210,7 @@ public:
198
210
if (!fName .startsWith (" /" )) {
199
211
fName = " /" + fName ;
200
212
}
201
- LittleFS. remove (fName );
213
+ fsys-> remove (fName );
202
214
}
203
215
uploadSize += upload.currentSize ;
204
216
// TRACE("free:: %d of %d\n", LittleFS.usedBytes(), LittleFS.totalBytes());
@@ -207,7 +219,7 @@ public:
207
219
} // if
208
220
209
221
} else if (upload.status == UPLOAD_FILE_END) {
210
- TRACE (" finished .\n " );
222
+ TRACE (" upload done .\n " );
211
223
// Close the file
212
224
if (_fsUploadFile) {
213
225
_fsUploadFile.close ();
@@ -231,14 +243,49 @@ void setup(void) {
231
243
232
244
TRACE (" Starting WebServer example...\n " );
233
245
246
+ // ----- check partitions for finding the fileystem type -----
247
+ esp_partition_iterator_t i;
248
+
249
+ i = esp_partition_find (ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, nullptr );
250
+ if (i) {
251
+ TRACE (" FAT partition found." );
252
+ fsys = &FFat;
253
+
254
+ } else {
255
+ i = esp_partition_find (ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, nullptr );
256
+ if (i) {
257
+ TRACE (" SPIFFS partition found." );
258
+ fsys = &LittleFS;
259
+
260
+ } else {
261
+ TRACE (" no partition found." );
262
+ }
263
+ }
264
+ esp_partition_iterator_release (i);
265
+
266
+ // mount and format as needed
234
267
TRACE (" Mounting the filesystem...\n " );
235
- if (!LittleFS.begin ()) {
268
+ if (!fsys) {
269
+ TRACE (" need to change the board configuration to include a partition for files.\n " );
270
+ delay (30000 );
271
+
272
+ } else if ((fsys == (fs::FS *)&FFat) && (!FFat.begin ())) {
273
+ TRACE (" could not mount the filesystem...\n " );
274
+ delay (2000 );
275
+ TRACE (" formatting FAT...\n " );
276
+ FFat.format ();
277
+ delay (2000 );
278
+ TRACE (" restarting...\n " );
279
+ delay (2000 );
280
+ ESP.restart ();
281
+
282
+ } else if ((fsys == (fs::FS *)&LittleFS) && (!LittleFS.begin ())) {
236
283
TRACE (" could not mount the filesystem...\n " );
237
284
delay (2000 );
238
- TRACE (" formatting...\n " );
285
+ TRACE (" formatting LittleFS ...\n " );
239
286
LittleFS.format ();
240
287
delay (2000 );
241
- TRACE (" restart .\n " );
288
+ TRACE (" restarting.. .\n " );
242
289
delay (2000 );
243
290
ESP.restart ();
244
291
}
@@ -286,7 +333,7 @@ void setup(void) {
286
333
// UPLOAD and DELETE of files in the file system using a request handler.
287
334
server.addHandler (new FileServerHandler ());
288
335
289
- // // enable CORS header in webserver results
336
+ // enable CORS header in webserver results
290
337
server.enableCORS (true );
291
338
292
339
// enable ETAG header in webserver results (used by serveStatic handler)
@@ -306,7 +353,7 @@ void setup(void) {
306
353
#endif
307
354
308
355
// serve all static files
309
- server.serveStatic (" /" , LittleFS , " /" );
356
+ server.serveStatic (" /" , *fsys , " /" );
310
357
311
358
TRACE (" Register default (not found) answer...\n " );
312
359
0 commit comments