-
Notifications
You must be signed in to change notification settings - Fork 124
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
OTA update Fails with [TB: preparing for update fails, Attributes might be NULL] #183
Comments
This seems to be a case of the const OTA_Update_Callback callback(&progressCallback, &updatedCallback, CURRENT_FIRMWARE_TITLE, CURRENT_FIRMWARE_VERSION, &updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE); Especially important are the Ensure you pass valid |
ok that was the first failure , corrected and now it works, but the device didn't download the Version 0.0.2 . If I use the example I got the failure: not for us: Title different... but I use in device and thingsboard-cloud the same title... eg: "Test" |
Are you really sure the title are the same. The title configured in the To check can you add a print to Serial.printf("Received fw title: (%s), curr_fw_title: (%s)\n", fw_title, curr_fw_title); |
curr_fw_title : �!@ |
As mentioned above in less detail, because the More simply the memory to the string has been erased already and it is now garbage and is then compared with from the cloud received JSON data. This results in the comparison failing, because the 2 strings can not be the same. If you need further help I would need your main file and especially the location your |
I use the orgiginal example 0009-esp8266-esp32-proceess_ota.ino without StreamUtil support. |
Okay good to know, perhaps there is some issue with flash strings, can you add this line on top of your main file. #define THINGSBOARD_ENABLE_PROGMEM 0 |
is by default, because i use platformio and board=d1_mini that has #define ESP8266... i see it higlighted in editor |
Ah good to know you are on ESP8266. For now as a dirty fix can you go into the const char *m_fwTitel; // Current firmware title of device to std::string m_fwTitel; // Current firmware title of device and additionally add an include to |
i tried to alter m_fwTitle but i got an compiler_error:
.pio\libdeps\d1_mini\ThingsBoard\src\OTA_Update_Callback.cpp: In member function 'void OTA_Update_Callback::Set_Firmware_Title(const char*)': |
Sorry my bad simply change void OTA_Update_Callback::Set_Firmware_Title(const char *currFwTitle) {
m_fwTitel = currFwTitle;
} to this instead void OTA_Update_Callback::Set_Firmware_Title(std::string currFwTitle) {
m_fwTitel = currFwTitle;
} |
I altered all depending functions on std::string currFwTitle , and pushed to my fork in branch "testing". What now happens is that my ESP8266 abort due to some runtime errors. compilation works fine...
and:
|
I am not 100% sure but perhaps it is an issue with the constness. const std::string Get_Firmware_Title() const; Will return a const copy-by-value. Which means the one calling the method can not make the received value non-const. To fix that please adjust the method like this. std::string Get_Firmware_Title() const; For the second error I am unsure, but for now simply go into the |
now it seems as fixed, OTA-Update works |
The problem is the But the underlying issue of the string being mangled even tough it should be in global scope still happens and that is what shouldn't occur. The problem is that I can't really reproduce your issue and as you mentioned you use the OTA example from the library so I am also not really sure were the error could be. For now can you check out your branch without the And then retry if it works, because I am assuming it has to do something with this. I currently can't imagine anything else, because that is the only real difference between the |
I was facing the same issue and could get it working with the changes proposed by the two of you, thank you very much! 😊 When I solved this, I got the same issue that I got in the past (see #159) where I was getting the error Given firmaware was NULL, then solved it in the same way by doing the initialization of the |
I am also getting the same error but can't fix it either by changing const OTA_Update_Callback callback(&progressCallback, &updatedCallback, CURRENT_FIRMWARE_TITLE, CURRENT_FIRMWARE_VERSION, &updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE); in the global scope. Still getting the same error message:
Although I made sure the value of |
What are you using Subscribe_Firmware, or Update_Firmware. Because to start the udpate the device needs to have certain attributes set server side. The attributes found with this link in the INITIATED state need to be set. Additionally which version of the library are you using? |
@MathewHDYT I'm using Thanks for the tip regarding the required attributes, I'll double check they are present in ThingsBoard and see if that helps. |
Okay good to know. Can you set |
Enabling debug, I'm getting one more line of log. Here is what
|
It seems that the If everything worked it should return true, that does not seem to be the case tough. Can you add additional log messages in the So it looks something like this. The likely case is that sending the telemtry did not work correctly. bool Prepare_Firmware_Settings(OTA_Update_Callback const & callback) {
char const * const currFwTitle = callback.Get_Firmware_Title();
char const * const currFwVersion = callback.Get_Firmware_Version();
if (Helper::stringIsNullorEmpty(currFwTitle) || Helper::stringIsNullorEmpty(currFwVersion)) {
Logger::printfln("Invalid callback attributes");
return false;
}
else if (!Firmware_Send_Info(currFwTitle, currFwVersion)) {
Logger::printfln("Sending failed :("); // This message will probably be printed.
return false;
}
m_fw_callback = callback;
return true;
} If the aforementioned message is printed can you ensure that you called the connect method on the ThingsBoard Instance, before trying to start the OTA firmware update. And additionally check if the connection is established with the connected() method and only then start the OTA firmware update. |
Many thanks @MathewHDYT ! I feel so stupid, I indeed forgot to call Anyway, now that I make sure the MQTT connexion is established before attempting to flash OTA, the problem seems to arise from the partition scheme of the ESP32 not being set properly. Here is the log (there is not additional log set in
Two things:
and the project is using the Arduino framework (no ESP-IDF). I think you might need the full picture to understand the context: I used to perform OTA flashing with this project by having the ESP32 broadcasting a Wifi SSID and running a webserver that allows user to upload a firmware file through a form that is being served by the ESP32. There is also a config file in SPIFFS that holds a few variables allowing to tweak the firmware at runtime and that config file can also be updated through the form served by the ESP32. Now we want to move to ThingsBoard, mainly because we need to be able to flash a lot of devices with a new firmware at once. With that background story in mind, I'm not sure what to do with the partition scheme. Maybe I can get ridd of the config file in SPIFFS and rely on Shared Attributes in ThingsBoard instead. That would be neat. But is there a Many thanks already for your support, that's really appreciated! |
The method fails because the call to the specific implementation of Mainly because that is the one recommended in the examples, because the Arduino Update version is not implemented very well. Additonally I do not think it is because of the app partitions because the Arduino Framework min_spiffs.csv should contain 2 OTA app portions which is correct. To actually find the underlying issue, can you adjust the bool Espressif_Updater::begin(size_t const & firmware_size) {
printf("Attempting to start flashing binary data");
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) {
printf("Configured boot partition does not contain a valid app, running partition was choosen as a fallback. We do not want to overwrite fallback partition, so we do not update");
return false;
}
esp_partition_t const * const update_partition = esp_ota_get_next_update_partition(nullptr);
if (update_partition == nullptr) {
printf("Invalid OTA data partition, or no eligible OTA app slot partition was found");
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("Initializing OTA update failed, because of error (%s)", esp_err_to_name(error));
return false;
}
printf("Starting to flash binary data successfull");
m_ota_handle = ota_handle;
m_update_partition = update_partition;
return true;
} |
I realise I'm actually using the Here is the relevant code: #include <Espressif_Updater.h>
...
Espressif_Updater updater();
...
// FIXME: compilation error here
const OTA_Update_Callback callback(&progressCallback, &updatedCallback, "myproject-fw", "1.0", &updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE); More specifically, class Espressif_Updater : public IUpdater
... Full compilation error:
|
But I don't get why probably some problems depending on the compiler used, because normally it should convert from the class to its interface wihtout any problem, because it is public. Fow now to fix it you can simply add this line to make sure it has the expected type. const OTA_Update_Callback callback(&progressCallback, &updatedCallback, "myproject-fw", "1.0", (IUpdater *)&updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE); |
Ok now I'm getting an error from the linker
|
Does the code look like this? Espressif_Updater updater;
const OTA_Update_Callback callback(&progressCallback, &updatedCallback, "myproject-fw", "1.0", (IUpdater *)&updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE); |
Ok super cool, there is some progress :-) Here is the complete log
and it goes on. I am going to investigate any access restriction on the server side. |
Can you increase the timeout? Simply adjust the constructor like this. I've increased it to 30 seconds now, perhaps this helps. Espressif_Updater updater;
const OTA_Update_Callback callback(&progressCallback, &updatedCallback, "myproject-fw", "1.0", (IUpdater *)&updater, FIRMWARE_FAILURE_RETRIES, FIRMWARE_PACKET_SIZE, 30000000UL); |
Apparently that helps, but this is extremely slow and we still experience timeouts on some chunks, even with the 30s value.
At this pace it would require 30 min to flash a single device... I wonder if this is not related to the ESP32 broadcasting a Wifi SSID while running the update, hence putting a lot of load on the RF unit. I'll try to switch off the Wifi broadcast before starting the update and see if that helps. EDIT: I disabled the Wifi SSID from the ESP but that doesn't help reduce the download time. |
I'm not sure I can help with this, because if the underlying connection is slow this library can't do anything about it. Are you doing anything else besides updating OTA with the same device and it's WiFi connection and is it possible to pause that behaviour while the udpate is ongoing? Perhaps reducing or increasing the packet size changes something. Simply change this attribute |
I've looked for all failures but I didn't get any idea for fixing this. On demo.thingsboard.io i have Version: esp8266_pt1k 0.0.2 and on my device ( D1 mini) there is version esp8266_pt1k 0.0.1.. the code is like yours.
The text was updated successfully, but these errors were encountered: