esp8266 / Arduino

ESP8266 core for Arduino
GNU Lesser General Public License v2.1
16.04k stars 13.33k forks source link

ESP8266HTTPUpdateServer won't upload SPIFFS - core 2.6.3 #6991

Closed mrWheel closed 4 years ago

mrWheel commented 4 years ago

Hi, I have used 2.5.2 ESP8266HTTPUpdateServer for some time with the mod. from PA4WD to be able to upload SPIFFS.

I now switched to core 2.6.3 and the upload SPIFFS functionality is now build in to the update server. Nice! .. But it is no longer possible to upload SPIFFS (uploading sketches is ok).

Errors I get are:

Update error: ERROR[10]: Magic byte is wrong, not 0xE9

and a complains that there is not enough room.

Tried it with 4M flash, 1M SPIFFS and 2M SPIFFS ...

I can update SPIFFS wired

earlephilhower commented 4 years ago

I am unable to repro any problem (SPIFFS upload went fine) with the current update examples.

Since you mentioned using a patched version before, please look at the code in the WebUpdater. You need to call Update.begin(size, U_FS,...) to have the updater write a filesystem (it checks the magic byte on a defaule U_FLASH app upload).

mrWheel commented 4 years ago

@earlephilhower I must be blind but I don't see an Update.begin() method in the example or in de src ...

Can you please elaborate?

earlephilhower commented 4 years ago

The Updater method is here: https://github.com/esp8266/Arduino/blob/8242d7227198dca2db39cf86d0b34f0e07e634cd/cores/esp8266/Updater.h#L64

The 2nd param needs to be U_FS. If unspecified, it will default to U_FLASH (app) which will check it's a valid executable.

The update server class calls it with U_FS here... https://github.com/esp8266/Arduino/blob/8242d7227198dca2db39cf86d0b34f0e07e634cd/libraries/ESP8266HTTPUpdateServer/src/ESP8266HTTPUpdateServer-impl.h#L94-L99

mrWheel commented 4 years ago

@earlephilhower My fault!

earlephilhower commented 4 years ago

No problem. Closing, then.

mrWheel commented 4 years ago

I blindly copied the form from my patched version and did not see the changes in the input fields

<input type='file' accept='spiffs.bin' name='filesystem'>

This is what is needed!

Just for your information: I have cloned your library and added two methods to insert a tailermade serverIndex and successRespond page.

That gives me the freedom to adapt the style of these forms (and the reboot delay) to the firmware I'm working on..

https://github.com/mrWheel/ModUpdateServer/blob/master/README.md

arlaor commented 4 years ago

Hi @earlephilhower @mrWheel

One question. I have uploaded three pages html through FS.h to the memory of esp8266, among which is the page that updates the code (.bin file) of esp8266, but when calling the file .bin, it does not update the code of esp8266. What extra code should I write to get the update information of the page mounted in the ESP memory? Or what line of extra code should I implement on the update.html page, so that when executing the binary file, it is assimilated by esp8266?

This is my code

#include <ESP8266HTTPUpdateServer.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#define DEBUG_SERIAL //uncomment for Serial debugging statements
#ifdef DEBUG_SERIAL
#define DEBUG_BEGIN Serial.begin(115200)
#define DEBUG_PRINT(x) Serial.println(x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_BEGIN
#endif
//includes
#include <PersWiFiManager.h>
#include <ArduinoJson.h>
#include <EasySSDP.h> // http://ryandowning.net/EasySSDP/
//extension of ESP8266WebServer with SPIFFS handlers built in
#include <SPIFFSReadServer.h> // http://ryandowning.net/SPIFFSReadServer/
// upload data folder to chip with Arduino ESP8266 filesystem uploader
// https://github.com/esp8266/arduino-esp8266fs-plugin
#include <DNSServer.h>
#include <FS.h>
#define DEVICE_NAME "ESP8266 DEVICE"
//server objects
SPIFFSReadServer server(80);
DNSServer dnsServer;
PersWiFiManager persWM(server, dnsServer);

const char* host = "Light";
const char* update_path = "/update";
const char* update_username = "xx";
const char* update_password = "xxxxxxx";

IPAddress ip = WiFi.localIP(); // desired IP Address
IPAddress mask = WiFi.subnetMask(); //Mascara de red
IPAddress gat = WiFi.gatewayIP();//gateway

MDNSResponder mdns;
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;

void setup(void){

//******************perswifimanager CODE INI*****************
  DEBUG_BEGIN; //for terminal debugging
  DEBUG_PRINT();

  //optional code handlers to run everytime wifi is connected...
  persWM.onConnect([]() {
    DEBUG_PRINT("wifi connected");
    DEBUG_PRINT(ip);
    DEBUG_PRINT(gat);
    DEBUG_PRINT(mask);
    EasySSDP::begin(server);
  });
  //...or AP mode is started
  persWM.onAp([](){
    DEBUG_PRINT("AP MODE");
    DEBUG_PRINT(persWM.getApSsid());
  });

  //allows serving of files from SPIFFS
  SPIFFS.begin();
  //SPIFFS.format();
  //sets network name for AP mode
 // persWM.setApCredentials(DEVICE_NAME);
  persWM.setApCredentials(DEVICE_NAME, "password"); //optional password

  //make connecting/disconnecting non-blocking
  persWM.setConnectNonBlock(true);

  //in non-blocking mode, program will continue past this point without waiting
  persWM.begin();

This is the part of the page in the memory of the ESP8266

  server.serveStatic("/", SPIFFS, "/page1.html");
  server.serveStatic("/update", SPIFFS, "/update.html");
  server.serveStatic("/page3", SPIFFS, "/page3.html");

  server.begin();
  DEBUG_PRINT("setup complete.");

 httpServer.on("/", [](){
page = String(ldt); //publish the value in text
 httpServer.send(200, "text/html", page);
});
 httpServer.begin();
Serial.println("Web server started!");

    httpUpdater.setup(&httpServer, update_path, update_username, update_password);
    httpServer.onNotFound(handleNotFound);
 //   httpServer.begin();
}

void loop(void){
//*************perswifimanager CODE INI******************
  //in non-blocking mode, handleWiFi must be called in the main loop
  persWM.handleWiFi();

  dnsServer.processNextRequest();
  server.handleClient();

  //DEBUG_PRINT(millis());

  // do stuff with x and y
//************perswifimanager CODE END******************

ldt = analogRead(A0);
mov = digitalRead(D5);
Serial.println(ldt);
Serial.print("mvto ");
Serial.println(mov);
delay(1000);

 httpServer.handleClient();
}

void handleNotFound() {
  //  server.serveStatic("/page3", SPIFFS, "/page3.html");
  httpServer.send(404, "text/plain", "404: Not found");
}

This is the code in the page UPDATE.HTML

<!DOCTYPE html>
     <html lang='en'>
     <head>
         <meta charset='utf-8'>
         <meta name='viewport' content='width=device-width,initial-scale=1'/>
     </head>
     <body>
     <form method='POST' action='' enctype='multipart/form-data'>
         Firmware:<br>
         <input type='file' accept='.bin' name='firmware'>
         <input type='submit' value='Update Firmware'>
     </form>
     <form method='POST' action='' enctype='multipart/form-data'>
         FileSystem:<br>
         <input type='file' accept='.bin' name='filesystem'>
         <input type='submit' value='Update FileSystem'>
     </form>
        <a href="javascript:history.back()">Back</a> | 
        <a href="/">Home</a>
     </body>
     </html>