Skocz do zawartości

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


Pomocna odpowiedź

Napisano (edytowany)

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
(edytowany)
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
(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

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"

 

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?

 

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

 

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).

 

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/

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

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...