Skocz do zawartości

PlatformIO ESP-12 4MB - zły rozmiar pliku bin przy http update


Bullseye

Pomocna odpowiedź

Znowu ja. Mam problem z http Update, wgrywam ładnie plik przez PlatformIO, ale gdy wrzucę ten plik na serwer www dostaję informacje: HTTP_UPDATE_FAILED Error (-107): New Binary Does Not Fit Flash Size

Wiem co ten błąd oznacza, ale nie mam pojęcia jak go naprawić 😞
Cały kod zajmuje: Flash: [=====     ]  51.7% (used 540409 bytes from 1044464 bytes), chip ma 4MB pamięci. W teorii powinno działać a nie działa 😞


PlatformIO.ini

[env:d1_mini_pro]
platform = espressif8266
board = nodemcu
board_build.filesystem = littlefs
board_build.partitions = min_spiffs.csv
build_type = debug
framework = arduino
monitor_speed = 115200
upload_speed = 921600

Kod do www ota:
 

void checkForUpdates() {
  // Create a WiFiClientSecure object to connect to the server
  WiFiClientSecure client;
  client.setInsecure();

  Serial.print("Connecting to ");
  Serial.println(hostup);

  // Connect to the server
  if (!client.connect(hostup, httpsPort)) {
    Serial.println("Connection failed");
    return;
  }

  Serial.println("Connected to server");

  // Send a GET request for the version file
  String url = "https://" + String(hostup) + String(versionPath);
  Serial.println("Requesting version file: " + url);
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + hostup + "\r\n" +
               "User-Agent: ESP8266\r\n" +
               "Connection: close\r\n\r\n");

  // Read the response from the server
  String response;
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      break;
    }
  }
  while (client.available()) {
    char c = client.read();
    response += c;
  }

  Serial.println("Response: " + response);

  // Get the version number from the response
  int newVersion = response.toInt();

  // Compare the new version with the current version
  if (newVersion > currentVersion) {
    Serial.println("New firmware available");

    // Send a GET request for the firmware file
    String url = "https://" + String(hostup) + String(firmwarePath);
    Serial.println("Requesting firmware file: " + url);
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + hostup + "\r\n" +
                 "User-Agent: ESP8266\r\n" +
                 "Connection: close\r\n\r\n");

    // Update the firmware from the response
    int updateAttempts = 0;
    while (updateAttempts < maxUpdateAttempts) {
      t_httpUpdate_return ret = ESPhttpUpdate.update(client, url);

      switch (ret) {
        case HTTP_UPDATE_FAILED:
          Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
          updateAttempts++;
          break;
        case HTTP_UPDATE_NO_UPDATES:
          Serial.println("HTTP_UPDATE_NO_UPDATES");
          updateAttempts = maxUpdateAttempts;
          break;
        case HTTP_UPDATE_OK:
          Serial.println("HTTP_UPDATE_OK");
          updateAttempts = maxUpdateAttempts;
          break;
      }
    }
  }
}

 

Edytowano przez Bullseye
Link do komentarza
Share on other sites

13 minut temu, Bullseye napisał:

Cały kod zajmuje: Flash: [=====     ]  51.7%

Czyli za dużo.

Miejsce w pamięci musi się znaleźć na obie wersje - starą i nową (tylko na czas ładowania oczywiście).

 

Edytowano przez jand
Link do komentarza
Share on other sites

(edytowany)

Dodałem linijkę: board_build.partitions = min_spiffs:128k(64k),app0:2.5MB(1MB),ota:2048k(1024k)

Teraz mam: Flash: [=====     ]  47.6% (used 497033 bytes from 1044464 bytes)

A mimo to wyskakuje ten sam błąd 😞 Wydaje mi się że PlatformIO nie reaguje na zmianę rozmiaru partycji i cały czas mam tyle samo na flash.

Edytowano przez Bullseye
Link do komentarza
Share on other sites

Nie jestem znawcą PlatformIO, ale wydaje mi się że podział na partycje robi się inaczej dla ESP8266, a inaczej dla ESP32. Zastosowałeś właściwą metodę?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Porobiłem zmiany i zamiast więcej to mam mniej 😕
PlatformIO:

[env:d1_mini_pro]
platform = espressif8266
board = nodemcu
board_build.filesystem = littlefs
board_build.partitions = custom.csv
board_build.ldscript = eagle.flash.D1.mini
framework = arduino
monitor_speed = 115200
upload_speed = 921600

custom.csv:

nvs,      0x9000,  0x3000,  0x3000,  0, 
otadata,  0xC000,  0x1000,  0x1000,  0, 
app0,     0x10000, 0x300000, 0x200000, 0,
spiffs,   0x310000, 0x3F000,  0x1000,   0,
ota_0,    0x400000, 0x1800000, 0xE80000, 0

i eagle.flash.D1.mini:

/* Flash Split for 2M chips */
/* sketch @0x40200000 (~1536KB) (1572864B) */
/* empty  @0x4023F000 (~224KB) (229376B) */
/* spiffs @0x4027B000 (~256KB) (262144B) */
/* eeprom @0x402BF000 (4KB) */
/* rfcal  @0x402C0000 (4KB) */
/* wifi   @0x402C1000 (12KB) */

MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  irom0_0_seg :                         org = 0x40201010, len = 0xEFEF0
}

PROVIDE ( _FS_start = 0x4027B000 );
PROVIDE ( _FS_end = 0x402BF000 );
PROVIDE ( _FS_page = 0x100 );
PROVIDE ( _FS_block = 0x2000 );
PROVIDE ( _EEPROM_start = 0x402BF000 );
/* The following symbols are DEPRECATED and will be REMOVED in a future release */
PROVIDE ( _SPIFFS_start = 0x4027B000 );
PROVIDE ( _SPIFFS_end = 0x402BF000 );
PROVIDE ( _SPIFFS_page = 0x100 );
PROVIDE ( _SPIFFS_block = 0x2000 );

INCLUDE "local.eagle.app.v6.common.ld"

 

Link do komentarza
Share on other sites

Dla 8266 nie używa się csv z układem partycji

Jeżeli dasz board_build.ldscript = eagle.flash.4m2m.ld

to będziesz miał dwie partycje ota po około 1MB i fs 2MB

Więc te 570k na luzie wejdzie. Jesteś pewien że masz 4MB pamięci?

 

Link do komentarza
Share on other sites

53 minuty temu, kostuch napisał:

Dla 8266 nie używa się csv z układem partycji

Jeżeli dasz board_build.ldscript = eagle.flash.4m2m.ld

to będziesz miał dwie partycje ota po około 1MB i fs 2MB

Więc te 570k na luzie wejdzie. Jesteś pewien że masz 4MB pamięci?

 

Dałem, faktycznie działa. Ale z tego co widzę to soft się nie aktualizuje po pobraniu pliku. Zostaje w tej samej wersji co był przed pobraniem.

Co robię źle ?

 

void checkForUpdates() {
  // Create a WiFiClientSecure object to connect to the server
  WiFiClientSecure client;
  client.setInsecure();

  Serial.print("Connecting to ");
  Serial.println(hostup);

  // Connect to the server
  if (!client.connect(hostup, httpsPort)) {
    Serial.println("Connection failed");
    return;
  }

  Serial.println("Connected to server");

  // Send a GET request for the version file
  String url = "https://" + String(hostup) + String(versionPath);
  Serial.println("Requesting version file: " + url);
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + hostup + "\r\n" +
               "User-Agent: ESP8266\r\n" +
               "Connection: close\r\n\r\n");

  // Read the response from the server
  String response;
  while (client.connected()) {
    String line = client.readStringUntil('\n');
    if (line == "\r") {
      break;
    }
  }
  while (client.available()) {
    char c = client.read();
    response += c;
  }

  Serial.println("Response: " + response);

  // Get the version number from the response
  int newVersion = response.toInt();

  // Compare the new version with the current version
  if (newVersion > currentVersion) {
    Serial.println("New firmware available");

    // Send a GET request for the firmware file
    String url = "https://" + String(hostup) + String(firmwarePath);
    Serial.println("Requesting firmware file: " + url);

    // Open the OTA partition for writing
    File otaFile = LittleFS.open("/firmware.bin", "w");
    if (!otaFile) {
      Serial.println("Failed to open OTA file");
      return;
    }

    // Download the firmware file and write it to the OTA partition
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + hostup + "\r\n" +
                 "User-Agent: ESP8266\r\n" +
                 "Connection: close\r\n\r\n");

    while (client.connected()) {
      String line = client.readStringUntil('\n');
      if (line == "\r") {
        break;
      }
    }
    while (client.available()) {
      char c = client.read();
      otaFile.write(c);
    }

    // Close the OTA file
    otaFile.close();

    // Update the firmware from the OTA partition
    ESPhttpUpdate.rebootOnUpdate(true);
    t_httpUpdate_return ret = ESPhttpUpdate.update(client, url);

    switch (ret) {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
        break;
      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;
      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
  }
}
Connected to server
Requesting version file: https://ota.pl/version.txt
Response: 120
New firmware available
Requesting firmware file: https://ota.pl/firmware.bin
HTTP_UPDATE_OK

 

Link do komentarza
Share on other sites

Na pierwszy rzut oka mieszasz jabłka z bananami 🙂

Wgrywasz na partycję z filesystemem plik z obrazem programu.

Plik bin ma być umieszczony w jednej z partycji zawierającej program (a nie pliki).

 

Link do komentarza
Share on other sites

Ale to tak nie działa. Nie wiem, czy wogóle da się zrobić aktualizację z pliku na filesystemie.

Masz mieć dwie partycje ota na program bieżący i ten aktualizujący (plus małe partycje na metadane). Po aktualizacji po prostu zmieniana jest aktywna partycja i wykonuje się zaktualizowany program. Na upartego można wrócić do poprzedniej wersji ponownie zmieniając aktywną partycję.

To czy masz dodatkowo partycję z filesystemem nie ma żadnego znaczenia.

4MB to mnóstwo miejsca. Co prawda najprostsze puste setup(){} loop(){} zajmie na dzień dobry jakieś 200kB, ale żeby potem dobić do 1MB trzeba naprawdę DUŻO kodu naklepać.

Poczytaj:

https://arduino-esp8266.readthedocs.io/en/latest/ota_updates/readme.html

https://randomnerdtutorials.com/esp8266-ota-updates-with-arduino-ide-over-the-air/

Link do komentarza
Share on other sites

Pierwszy raz zawsze jest trudny 😉

Funkcja update to coś takiego (callbacki onCośtam są opcjonalne):

void update()

{

  WiFiClient wifi_client;

  // Add optional callback notifiers

  ESPhttpUpdate.onStart(update_started);

  ESPhttpUpdate.onEnd(update_finished);

  ESPhttpUpdate.onProgress(update_progress);

  ESPhttpUpdate.onError(update_error);

  String new_file = F("http://www.tam.gdzie/jest/plik/firmware.bin");

  t_httpUpdate_return ret = ESPhttpUpdate.update(wifi_client, new_file);



  switch (ret)

  {

  case HTTP_UPDATE_FAILED:

    Serial.printf(PSTR("HTTP_UPDATE_FAILED Error (%d): %s"), ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());

    break;



  case HTTP_UPDATE_NO_UPDATES:

    Serial.println("HTTP_UPDATE_NO_UPDATES");

    break;



  case HTTP_UPDATE_OK:

    break;

  }

}

I to tyle... 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.