Skip to content

Compressed binary and SPIFFS image upload via wifi fails with ESP8266HTTPUpdateServer #7178

@jan-gerard

Description

@jan-gerard
  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: ESP-12-F
  • Core Version: 2.6.3
  • Development Env: Arduino IDE 1.8.12
  • Operating System: Windows

Settings in IDE

  • Module: Generic ESP8266 Module
  • Flash Mode: dout
  • Flash Size: 4MB
  • lwip Variant: v2 Lower Memory
  • Reset Method: nodemcu
  • Flash Frequency: 40Mhz
  • CPU Frequency: 80Mhz
  • Upload Using: OTA

Problem Description

Compressed binaries (.gz, using gzip) sketch binaries and SPIFFS FS image files are not processed correctly by ESP8266HTTPUpdateServer. If I upload the uncompressed .bin file, it's working fine, but if I compress the .bin file with gzip (or 7zip), it's uploading, but the result is an empty file system on my ESP8266 for SPIFFS images files, and no program update for binaries (the old code keeps running). I have compiled my sketch with a line
#define ATOMIC_FS_UPDATE
included as described in
https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#compression Then I first uploaded the program with a wired serial interface (as described in the documentation), and later ran the actual test with a wireless connection.

I use a "Generic EPS8266 module" with setting "Flash size = 4MB (FS:2MB
OTA:~1019KB)".

I created the SPIFFS image .bin file with

%sketchdir%\mkspiffs.exe --size 0x1FA000 --page 256 --block 8192 -d 5
--create %sketchdir%\data %sketchdir%\spiffs.file.bin
%gzip% a -tgzip -mx9 %sketchdir%\spiffs.file.bin.gz
%sketchdir%\spiffs.file.bin

where %sketchdir% is the sketch folder (I copied mkspiffs.exe there for
convenience) and %gzip% points to 7z.exe on my machine. I also tried Linux' gzip.

I based my sketch upon
https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer/examples/SecureWebUpdater
When I connect to it, and go to the update folder, I see four buttons. I
select the spiffs.file.bin.gz file with the FileSystem button, and press
"Update FileSystem". Then I wait, until the confirmation comes that it
was successful. I reboot, but then the FS is empty. While if I upload
the non-compressed file spiffs.file.bin, the filesystem contains the
desired files correctly. So the SPIFFS image is good, but the compressed version seems corrupt.
Similar for binaries: I can load a new program with the uncompressed .bin file, but compressed, the binary is transferred but not deployed over the original program.

According to
https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html#compression
this should work when I define ATOMIC_FS_UPDATE. However, I cannot find
an example anywhere of of a sketch that includes this option.

I'm using Arduino 1.8.12 (latest), and ESP8266 2.6.3 (latest).

MCVE Sketch

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ESP8266HTTPUpdateServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);

ESP8266HTTPUpdateServer httpUpdater;
#define ATOMIC_FS_UPDATE

char *ap_ssid = "xxx";
char *ap_password = "xxx";
const byte softAP_maxConnections = 8;
struct station_info *stat_info;
char *ap_hostname = "xxx.xx";
const char* update_path = "/update";
const char* update_username = "xxx";
const char* update_password = "xxx";

File fsUploadFile;

void setup() {
  Serial.begin(115200);
  setup_FileSystem();
  setup_WiFi();

  if (!MDNS.begin(ap_hostname))
    Serial.println("Error setting up MDNS responder!");
  else
    Serial.println("mDNS responder started");
  httpUpdater.setup(&webServer, update_path, update_username, update_password);
  setup_Webserver();
  webServer.begin();
  MDNS.addService("http", "tcp", 80);
  Serial.printf("HTTPUpdateServer ready! Open http://%s.local%s in your browser and login with username '%s' and password '%s'\n", ap_hostname, update_path, update_username, update_password);
}

void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
  MDNS.update();
  delay(10); // ms
  yield();
}

void setup_WiFi() {
  byte softAP_channel = 0;
  bool ap_hidden = false;
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP(ap_ssid, ap_password, softAP_channel, ap_hidden, softAP_maxConnections);
  Serial.println("Connect to " + (String)ap_ssid + " with '" + (String)ap_password + "'");
  dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
  dnsServer.start(DNS_PORT, "*", apIP);
}

void setup_FileSystem() {
  if (!SPIFFS.begin())
    Serial.println("Failed to mount file system");
  else
    Serial.println("Started spiff.");
  Dir dir = SPIFFS.openDir("/");
  while (dir.next()) {
    Serial.println(dir.fileName());
  }
}

void setup_Webserver() {
  webServer.onNotFound([]() {
    dirList();
  });
}

void dirList() {
  String html =
    "<html><head>\n"
    "</head><body>\n"
    "DIRECTORY LISTING:<br /><table>\n";
  Dir dir = SPIFFS.openDir("/");
  while (dir.next()) {
    html += "<tr><td><a href='." + (String)dir.fileName() + "'>";
    File f = dir.openFile("r");
    html += (String)dir.fileName() + "</a></td><td>(" + (String)f.size() + ")</td></tr>\n";
  }
  html +=
    "</table></body>\n"
    "</html>\n";
  webServer.send(200, "text/html", html);
  webServer.client().stop();
}

.... the rest of the code is not relevant for this topic (I think).

I tried to test everything thoroughly, and include all relevant information. But maybe I am still making a stupid mistake. However, I'm a bit surprised that I cannot find any online examples. @earlephilhower I think you are the expert on this topic since I see a lot of replies and updates on this topic.

Metadata

Metadata

Labels

waiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions