Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using 0009 ESP32 OTA Process #218

Closed
hassanaansari opened this issue Sep 11, 2024 · 28 comments
Closed

Using 0009 ESP32 OTA Process #218

hassanaansari opened this issue Sep 11, 2024 · 28 comments

Comments

@hassanaansari
Copy link

I am using an ESP32 Dev Module
Tried this code on

  • 4Mb with spiffs
  • Minimal
  • Minimal with spiffs
  • Custom partition

Name, Type, SubType, Offset, Size, Flags

nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x170000,

This is what I am getting with I update the firmware over thingsboard, I am using thingsboard configured locally on docker
[TB] Failed to initalize flash updater, ensure that the partition scheme has two app sections

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Sep 11, 2024

I am assuming you are using an instance of the Espressif_Updater.h? If you are it would be a good idea to add log message to the begin() method.

[TB] Failed to initalize flash updater, ensure that the partition scheme has two app sections

Because this log message means that method failed to find out the exact reason (because the 2 app sections seem good in your partitions file) we have to debug further.

In the EspressifUpdater.cpp could you adjust your code like this and then run the update again:

bool Espressif_Updater::begin(size_t const & firmware_size) {
    esp_partition_t const * const running = esp_ota_get_running_partition();
    esp_partition_t const * const configured = esp_ota_get_boot_partition();

    if (configured != running) {
        // The two results are not equal if the configured boot partition does not contain a valid app (meaning that the running partition will be an app that the bootloader chose via fallback). If the OTA data partition is not present or not valid then the result is the first app partition found in the partition table.
        printf("The running partition and the parition we wanted to boot into were not the same meaning the previous update failed and choose the fallback partition instead. Aborting update\n");
        return false;
    }

    esp_partition_t const * const update_partition = esp_ota_get_next_update_partition(nullptr);

    if (update_partition == nullptr) {
        //  NULL result indicates invalid OTA data partition, or that no eligible OTA app slot partition was found
        printf("Missing second ota app or app was invalid\n");
        return false;
    }

    // Temporary handle is used, because it allows using a void* as the actual ota_handle,
    // allowing us to only include the esp_ota_ops header in the defintion (.cpp) file,
    // instead of also needing to declare it in the declaration (.h) header file
    esp_ota_handle_t ota_handle;
    esp_err_t const error = esp_ota_begin(update_partition, firmware_size, &ota_handle);

    if (error != ESP_OK) {
        printf("Beginning update failed with error reason (%s)", esp_err_to_name(error));
        return false;
    }

    m_ota_handle = ota_handle;
    m_update_partition = update_partition;
    return true;
}

@hassanaansari
Copy link
Author

Beginning update failed with error reason (ESP_ERR_INVALID_SIZE)[TB] Failed to initalize flash updater, ensure that the partition scheme has two app sections

Getting this now

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Sep 11, 2024

The answer lies here ESP_ERR_INVALID_SIZE on this method is only returned, because of this ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.

Meaning the partitions file you confgured is invalid because it uses more flash memory than you actually have on the device. If possible you need to decrease the amount of flash the spiffs or the 2 ota app partitions get so it fits into 4MB

@hassanaansari

This comment was marked as off-topic.

@MathewHDYT
Copy link
Contributor

I am new with this esp32 thing. This is my sketch can you send me a proper custom partitions.csv

What exact flash size do you have, because after having a look again at the partitions file it should fit into 4MB. So perhaps you have even less.

Could you use this command esptool.py --port <serial_port> flash_id where the serial port is the port your device is connected over. It should print the actual flash size of your device.

@hassanaansari
Copy link
Author

The device I am using is ESP32-D0WD-V3 (revision v3.1)

@hassanaansari
Copy link
Author

esptool.py v4.7.0
Serial port COM4
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......................
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 24:dc:c3:45:81:50
Uploading stub...
Running stub...
Stub running...
Manufacturer: 68
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...

@MathewHDYT
Copy link
Contributor

Perfect so the flash size is 4MB. I'm confused why it then says that this partition is to big for that. Are you really sure that you are flashing this partitions file.

And what tooling are you using to upload the file ArduinoIDE or PlattformIO?

nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
spiffs, data, spiffs, 0x290000,0x170000,

@hassanaansari
Copy link
Author

I am using Arduino IDE. All I am doing is making a .csv file named partitions.csv and copying it into the folder of the sketch and choose Custom from the Device partition scheme in Arduino IDE.
Even tried to use Factory two OTA partition as well which I found in the ESP-IDF library.

Name, Type, SubType, Offset, Size

Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap

nvs, data, nvs, , 0x4000
otadata, data, ota, , 0x2000
phy_init, data, phy, , 0x1000
factory, 0, 0, , 1M
coredump, data, coredump,, 64K
ota_0, 0, ota_0, , 1M
ota_1, 0, ota_1, , 1M

@MathewHDYT
Copy link
Contributor

Perhaps you need to take additional steps and it doesn't actually upload the partitions file you expect. Here is a guide on how to make the ArduinoIDE use a custom partitions schema, perhaps you missed one of thoose steps.

Besides that possible issue I'm also not sure what else it could be, the only thing I'm relatively sure of is that the code of this library is probably not wrong, because the esp_ota_begin call fails and that is a call to the underlying api and not implemented by this library.

@hassanaansari
Copy link
Author

What I just want to do is perform an OTA from the thingsboard localhost. Can you recommend the right direction for that?

@MathewHDYT
Copy link
Contributor

No clue, I normally use demo.thingsboard.io to test he features of the library. I've never worked with trying to download from localhost before.

@rayene01
Copy link

rayene01 commented Sep 11, 2024

Hello i use esp-idf to perform the OTA and i get his same error
[TB] Failed to initalize flash updater, ensure that the partition scheme has two app sections

and i used the espressif exemple of thingsboard
this is my partition table
458512607_530000786091554_5398818438961600459_n

@MathewHDYT
Copy link
Contributor

Can you also adjust the code as mentioned in this comment.

@rayene01
Copy link

rayene01 commented Sep 11, 2024

i did but i get the same line
[TB] Failed to initialize flash updater, ensure that the partition scheme has two app sections
in the example he didn't include Espressif_Updater.h
but in Arduino example he did

@MathewHDYT
Copy link
Contributor

What are you using the Arduino_ESP32_Updater or the Espressif_Updater? And if you are using the first option can you switch to the latter and then try again.

@rayene01
Copy link

rayene01 commented Sep 11, 2024

#include <esp_netif.h>
#include <esp_log.h>
#include <esp_wifi.h>
#include <nvs_flash.h>

// Whether the given script is using encryption or not,
// generally recommended as it increases security (communication with the server is not in clear text anymore),
// it does come with an overhead tough as having an encrypted session requires a lot of memory,
// which might not be avaialable on lower end devices.
#define ENCRYPTED false

#include <SDCard_Updater.h>
#include <Espressif_MQTT_Client.h>
#include <ThingsBoard.h>
#include "esp_ota_ops.h"

// Firmware title and version used to compare with remote version, to check if an update is needed.
// Title needs to be the same and version needs to be different --> downgrading is possible
constexpr char CURRENT_FIRMWARE_TITLE[] = "ESP32";
constexpr char CURRENT_FIRMWARE_VERSION[] = "1.0.0";

// Maximum amount of retries we attempt to download each firmware chunck over MQTT
constexpr uint8_t FIRMWARE_FAILURE_RETRIES = 12U;
// Size of each firmware chunck downloaded over MQTT,
// increased packet size, might increase download speed
constexpr uint16_t FIRMWARE_PACKET_SIZE = 4096U;

// Examples using arduino used PROGMEM to save constants into flash memory,
// this is not needed when using Espressif IDF because per default
// all read only variables will be saved into DROM (flash memory).
// See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/memory-types.html#drom-data-stored-in-flash
// for more information about the aforementioned feature
constexpr char WIFI_SSID[] = "DROGO";
constexpr char WIFI_PASSWORD[] = "123456789";

// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
constexpr char TOKEN[] = "KHiTdpMD6sLKpjfuNlDW";

// Thingsboard we want to establish a connection too
constexpr char THINGSBOARD_SERVER[] = "demo.thingsboard.io";

// MQTT port used to communicate with the server, 1883 is the default unencrypted MQTT port,
// whereas 8883 would be the default encrypted SSL MQTT port
#if ENCRYPTED
constexpr uint16_t THINGSBOARD_PORT = 8883U;
#else
constexpr uint16_t THINGSBOARD_PORT = 1883U;
#endif

// Maximum size packets will ever be sent or received by the underlying MQTT client,
// if the size is to small messages might not be sent or received messages will be discarded.
// The Espressif_MQTT_Client, currently has an issue with the underlying library used, where it is not possible
// to change the buffer size once the client has been initalized, meaning the buffer size can only be set before calling connect(),
// for the first time. Therefore when using the OTA update mechanism it is required to increase the buffer size to the size of the received firmware packets
// and a little bit more for the topic we received the message on.
// This has to be done at least until the issue espressif/esp-mqtt#267 has been fixed in the esp-mqtt client,
// or if an older version of the esp-mqtt client is used that does not include the possible fixes to the aforementioned issue yet.
constexpr uint16_t MAX_MESSAGE_SIZE = FIRMWARE_PACKET_SIZE + 50U;

#if ENCRYPTED
// See https://comodosslstore.com/resources/what-is-a-root-ca-certificate-and-how-do-i-download-it/
// on how to get the root certificate of the server we want to communicate with,
// this is needed to establish a secure connection and changes depending on the website.
constexpr char ROOT_CERT[] = R"(-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)";
#endif

constexpr char FW_STATE_UPDATED[] = "UPDATED";
constexpr char UPDAT_FILE_PATH[] = "/sd/update.bin";

// Initalize the Mqtt client instance
Espressif_MQTT_Client mqttClient;
// Initialize ThingsBoard instance with the maximum needed buffer size
ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE);
// Initalize the Updater client instance used to flash binary to flash memory
SDCard_Updater updater(UPDAT_FILE_PATH);

// Status for successfully connecting to the given WiFi
bool wifi_connected = false;
// Statuses for updating
bool currentFWSent = false;
bool updateRequestSent = false;

struct binary_data_t {
size_t size;
size_t remaining_size;
void * data;
};

/// @brief Attempts to write all received data on the given file into flash memory,
/// allows to write binary data from an sd card into flash memory
/// @param pvParameter Always null
void otaSDToFlashTask(void* pvParameter) {
FILE * ota_bin_file = fopen(UPDAT_FILE_PATH, "rb");
esp_ota_handle_t update_handle;
esp_partition_t const * update_partition = esp_ota_get_next_update_partition(NULL);
binary_data_t data;

if (ota_bin_file == nullptr) {
    ESP_LOGE("MAIN", "Failed to open file for Update");
    vTaskDelete(NULL);
} else {
    esp_err_t error = ESP_OK;
    ESP_LOGI("MAIN", "Opened File for Update");
    fseek(ota_bin_file, 0, SEEK_END);
    data.size = ftell(ota_bin_file);
    data.remaining_size = data.size;
    ESP_LOGI("MAIN", "Update Size: %u", data.size);
    data.data = malloc(FIRMWARE_PACKET_SIZE);
    fseek(ota_bin_file, 0, SEEK_SET);
    esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    while (data.remaining_size > 0) {
        size_t const size = data.remaining_size <= FIRMWARE_PACKET_SIZE ? data.remaining_size : FIRMWARE_PACKET_SIZE;
        fread(data.data, size, 1, ota_bin_file);
        error = esp_ota_write(update_handle, data.data, size);
        if (data.remaining_size <= FIRMWARE_PACKET_SIZE) {
            break;
        }
        data.remaining_size -= FIRMWARE_PACKET_SIZE;
        vTaskDelay(0);
    }
    if (error != ESP_OK) {
        ESP_LOGE("MAIN", "Failed to write OTA data: 0x%X (%s)", error, esp_err_to_name(error));
    }
    error = esp_ota_end(update_handle);
    if (error != ESP_OK) {
        ESP_LOGE("MAIN", "Failed to end OTA update: 0x%X (%s)", error, esp_err_to_name(error));
    }

    error = esp_ota_set_boot_partition(update_partition);
    if (error != ESP_OK) {
        ESP_LOGE("MAIN", "Failed to set boot partition: 0x%X (%s)", error, esp_err_to_name(error));
    } else {
        ESP_LOGI("MAIN", "Updated with data from SD card, Restarting");
        esp_restart();
    }
    vTaskDelete(NULL);
    return;
}

}

/// @brief Updated callback that will be called as soon as the firmware update finishes
/// @param success Either true (update successful) or false (update failed)
void updatedCallback(const bool& success) {
if (success) {
ESP_LOGI("MAIN", "Done updated to sd card. Write from SD card to flash");
xTaskCreate(otaSDToFlashTask, "OTA_SD_TO_FLASH", FIRMWARE_PACKET_SIZE + 1024 * 1, NULL, 16, NULL);
return;
}
ESP_LOGI("MAIN", "Downloading firmware failed");
}

/// @brief Progress callback that will be called every time we downloaded a new chunk successfully
/// @param currentChunk
/// @param totalChuncks
void progressCallback(const size_t& currentChunk, const size_t& totalChuncks) {
ESP_LOGI("MAIN", "Downwloading firmware progress %.2f%%", static_cast(currentChunk * 100U) / totalChuncks);
}

/// @brief Callback method that is called if we got an ip address from the connected WiFi meaning we successfully established a connection
/// @param event_handler_arg User data registered to the event
/// @param event_base Event base for the handler
/// @param event_id The id for the received event
/// @param event_data The data for the event, esp_event_handler_t
void on_got_ip(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
wifi_connected = true;
}

/// @brief Initalizes WiFi connection,
// will endlessly delay until a connection has been successfully established
void InitWiFi() {
const wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));

esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *netif = esp_netif_new(&netif_config);
assert(netif);

ESP_ERROR_CHECK(esp_netif_attach_wifi_station(netif));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ip_event_t::IP_EVENT_STA_GOT_IP, &on_got_ip, NULL));
ESP_ERROR_CHECK(esp_wifi_set_default_wifi_sta_handlers());
ESP_ERROR_CHECK(esp_wifi_set_storage(wifi_storage_t::WIFI_STORAGE_RAM));

wifi_config_t wifi_config;
memset(&wifi_config, 0, sizeof(wifi_config));
strncpy(reinterpret_cast<char*>(wifi_config.sta.ssid), WIFI_SSID, strlen(WIFI_SSID) + 1);
strncpy(reinterpret_cast<char*>(wifi_config.sta.password), WIFI_PASSWORD, strlen(WIFI_PASSWORD) + 1);

ESP_LOGI("MAIN", "Connecting to %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK(esp_wifi_set_mode(wifi_mode_t::WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(wifi_interface_t::WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_connect());
}

extern "C" void app_main() {
ESP_LOGI("MAIN", "[APP] Startup..");
ESP_LOGI("MAIN", "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
ESP_LOGI("MAIN", "[APP] IDF version: %s", esp_get_idf_version());

esp_log_level_set("*", ESP_LOG_INFO);

ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());

InitWiFi();

#if ENCRYPTED
mqttClient.set_server_certificate(ROOT_CERT);
#endif // ENCRYPTED

for (;;) {
    // Wait until we connected to WiFi
    if (!wifi_connected) {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        continue;
    }

    if (!tb.connected()) {
        tb.connect(THINGSBOARD_SERVER, TOKEN, THINGSBOARD_PORT);
    }

    if (!currentFWSent) {
        // Firmware state send at the start of the firmware, to inform the cloud about the current firmware and that it was installed correctly,
        // especially important when using OTA update, because the OTA update sends the last firmware state as UPDATING, meaning the device is restarting
        // if the device restarted correctly and has the new given firmware title and version it should then send thoose to the cloud with the state UPDATED,
        // to inform any end user that the device has successfully restarted and does actually contain the version it was flashed too
        currentFWSent = tb.Firmware_Send_Info(CURRENT_FIRMWARE_TITLE, CURRENT_FIRMWARE_VERSION) && tb.Firmware_Send_State(FW_STATE_UPDATED);
    }

    if (!updateRequestSent) {
        const OTA_Update_Callback callback(&progressCallback, &updatedCallback, CURRENT_FIRMWARE_TITLE, CURRENT_FIRMWARE_VERSION, &updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE);
        // See https://thingsboard.io/docs/user-guide/ota-updates/
        // to understand how to create a new OTA pacakge and assign it to a device so it can download it.
        updateRequestSent = tb.Start_Firmware_Update(callback);
    }

    tb.loop();
    
    vTaskDelay(10000 / portTICK_PERIOD_MS);
}

}
`

this is the code from TB and none of the two above is called

@MathewHDYT
Copy link
Contributor

Do you want to update to the SD card first, because that is what the example shows. If you don't you can create an instance of the Espressif_Updater instead of the SDCard_Updater and adjust the updatedCallback method like this.

void updatedCallback(const bool& success) {
    if (success) {
        ESP_LOGI("MAIN", "Done updated to flash");
        esp_restart()
        return;
    }
    ESP_LOGI("MAIN", "Downloading firmware failed");
}

@rayene01
Copy link

it work, but I'm confused because i tried your solution a while ago and didn't work hhh
any way thank you

@MathewHDYT
Copy link
Contributor

Why it works is pretty clear you tried to update to an sd card, which does not exist. So of course initialization of that sd card failed.

Now you update to flash and it works like it should.

@rayene01
Copy link

Yeah thank you again.
But a little question i want to make the device when i perform an update from the server he do it automatically

@MathewHDYT
Copy link
Contributor

Yeah thank you again. But a little question i want to make the device when i perform an update from the server he do it automatically

Simple instead of Start_Firnware_Update call Subscribe_Firmware_Update.

The first option immefiately starts the update if it is assigned but else does nothing and the latter does nothing until a new firnware is assigned and then instantly updates.

The best option is to combine both so you always update the device if a new firmware is assigned. Even if it was assigned while the device was offline.

@hassanaansari
Copy link
Author

Hey Mathew, my issue was resolved using Arduino_ESP32_updater.h and removing Espressif_updater.h
I have one question, how does the OTA partitions work? Like do I have to set the OTA configurations, FW_TITLE and VERSION in every binary file that I upload. Or just do it in the first sketch and later use my regular old code of interacting GPIOs with the dashboard??? If you can share a link or documentation or just a quick explanation of it.

Thanks in Advance

@hassanaansari
Copy link
Author

And secondly, when I add my binary file to the Assigned version it doesnt catch the Shared Attributes, however when I use Firmware exampleV1.1 or V1.2 from the thingsboard library, it gets it into the shared attributes. What can I do to fix that?

@MathewHDYT
Copy link
Contributor

How does the OTA partitions work? Like do I have to set the OTA configurations, FW_TITLE and FW_VERSION in every binary file that I upload. Or just do it in the first sketch and later use my regular old code of interacting GPIOs with the dashboard?

The FW_TITLE and FW_VERSION is an argument to the OTA_Update_Callback and you need to pass that instance to both methods that can start an update (Start_Firmware_Update, Subscribe_Firmware_Update).

So if you want your device to keep the ability to update you need to save your current FW_VERSION and FW_TITLE in the binary. If you don't pass these arguments or pass a nullptr then calling any of the methods that start an update will simply fail and do nothing.

When I add my binary file to the Assigned version it doesnt catch the Shared Attributes, however when I use Firmware exampleV1.1 or V1.2 from the thingsboard library, it gets it into the shared attributes. What can I do to fix that?

Are you calling Subscribe_Firmware_Update, because if you want to catch Shared Attribute Updates, while the device is connected you need to call that method.

If you only want to check if new firmware is assigned and you missed an update while the device was offline you can use Start_Firmware_Update instead. The recommended way is to call both at startup one time, once the device is connected.

@hassanaansari
Copy link
Author

hassanaansari commented Sep 12, 2024

I think I explained it the wrong way.
My device is offline and I am just setting up the shared attributes of the device on thingsboard.
When I set firmware examples from the esp32-ota library of things board, it is automatically setting up the shared attributes and even updating it when I assign a new firmware. But when I am assigning the firmware file that I exported from my arduino IDE after deleting the existing shared attributes, It is not setting up the shared attributes which I set in my sketch automatically like it did with the examples firmware binary files. Keeping in mind that my device is offline the whole time.

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Sep 12, 2024

I'm really confused how you assign an update to your device. I would advise you to use this Firmware Update Dashboard by thingsboard instead of deleting and changing shared attributes by hand.

The dashboard itself is documented on the offical ThingsBoard Documentation

@hassanaansari
Copy link
Author

Thankyou so much Mathew, my issue was resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants