-
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
ESP32 OTA Firmware Update Issue: SIM800L, ThingsBoard, and Chunk Size Anomalies #169
Comments
Hard to say what exactly could be the problem, would it be possible to set And then add the log messages that occur, once the firmware size is 0 bytes. It might help solve the exact issue. The only thing I could imagine is that there is not enough heap memory after a while. Would be nice if you could add this line to your main file as well. See more information on Heap Debugging on ESP32 #include "esp_heap_caps.h"
void heap_caps_alloc_failed_hook(size_t requested_size, uint32_t caps, const char *function_name)
{
printf("%s was called but failed to allocate %d bytes with 0x%X capabilities. \n",function_name, requested_size, caps);
}
void app_main()
{
...
esp_err_t error = heap_caps_register_failed_alloc_callback(heap_caps_alloc_failed_hook);
...
void *ptr = heap_caps_malloc(allocation_size, MALLOC_CAP_DEFAULT);
...
} |
Thank you for your guidance. I've implemented the recommended changes, including setting THINGSBOARD_ENABLE_DEBUG to 1 before including <Thingsboard.h>, adding log messages to track the issue when the firmware size becomes 0 bytes, and incorporating memory debugging using esp_heap_caps. I encountered the problem again, and below is the output from the Serial Monitor when the issue occurred: 08:41:49.912 -> [TB] Received data from server over topic (v2/fw/response/0/chunk/42) Additionally, I observed that the checksum is reported as invalid, and the system attempts to download the firmware again, but it continues to receive 0 bytes. Any insights or suggestions to address this issue would be greatly appreciated. |
Here is the serial monitor output illustrating the issue with the invalid checksum. 08:52:20.631 -> [TB] Received data from server over topic (v2/fw/response/0/chunk/258) |
The invalid checksum is a follow up issue because we do not receive the correct binary data, that of course makes sense because we do not receive any binary data and therefore having a incorrect checksum at the end is expected behaviour. And it seems that allocating the payload is also not a problem either, because if it were the Would it be possible to add the log messages below to the inline void process_firmware_response(char * const topic, uint8_t * const payload, size_t const & length) {
char test[Helper::detectSize("Receiving payload with original length %lu", length)] = {};
snprintf(test, sizeof(test), "Receiving payload with original length %lu", length);
Logger::log(test);
...
} But It seems that I should probably add a check, that ensures the packet has the expected size because it should always be 4096 bytes big (if configuration was not changed) and perhaps less for the last packet. If it is not that size I could add special log messages. I will do that once we could debug the exact issue that is occurring and fix it. |
Thank you for your insights. I previously incorporated log messages into the process_firmware_response callback, and similarly, it consistently displayed 0 bytes received. Despite these efforts, the issue persists Below I show you the serial monitor: 11:06:58.368 -> [TB] Received data from server over topic (v2/fw/response/0/chunk/43) |
Okay that is already a bad sign, because it hints to a more underlying issue with the MQTT client. Can you print the length in the inline void onMQTTMessage(char * const topic, uint8_t * const payload, unsigned int length) {
char test[Helper::detectSize("Receiving payload with original length %lu", length)] = {};
snprintf(test, sizeof(test), "Receiving payload with original length %lu", length);
Logger::log(test);
...
} Because that is the earliest place we receive the message if it is already 0 bytes then, then that hints that the problem lies with the Are you using Arduino? Are you using the default |
I am using Arduino IDE to program the ESP32. The ESP32 is utilizing FreeRTOS. These are some isolated lines used in the program: #include <Arduino_MQTT_Client.h>
#if THINGSBOARD_ENABLE_PROGMEM
constexpr uint16_t MAX_MESSAGE_SIZE PROGMEM = 512U;
#else
constexpr uint16_t MAX_MESSAGE_SIZE = 512U;
#endif
// Initialize GSM client with TinyGSMClient
TinyGsmClient client(modem);
// Initialize the MQTT client instance
Arduino_MQTT_Client mqttClientgprs(client);
// Initialize ThingsBoard instance with the MQTT client and maximum message size
ThingsBoard tb_gprs(mqttClientgprs, MAX_MESSAGE_SIZE);
// Start firmware update with ThingsBoard instance and a callback function
tb_gprs.Start_Firmware_Update(callback); Should you require further information, I am at your disposal. |
After incorporating the suggested modification to the onMQTTMessage function, the serial monitor still displays empty chunks, indicating that the issue persists. "12:23:58.451 -> [TB] Receiving payload with original length 4096 |
Would it be possible to enable verbose logging for the framework. |
The Enabling those might show some messages that can help discern why the packages are length 0 after a while. |
I added the verbose, but it still shows the same thing when the issue occurs. "10:41:46.316 -> [TB] Receiving payload with original length 4096 |
Can you adjust the void Process_Firmware_Packet(size_t const & current_chunk, uint8_t *payload, size_t const & total_bytes) {
...
else if ((m_requested_chunks + 1 < m_total_chunks && total_bytes != m_fw_callback->Get_Chunk_Size()) || (m_requested_chunks + 1 >= m_total_chunks && total_bytes != (m_fw_size % m_fw_callback->Get_Chunk_Size()))) {
char message[Helper::detectSize("Expected chunk size of %u, but got %u", m_fw_callback->Get_Chunk_Size(), total_bytes)];
snprintf(message, sizeof(message), "Expected chunk size of %u, but got %u", m_fw_callback->Get_Chunk_Size(), total_bytes);
Logger::log(message);
return;
}
...
} If this method solves the problem it would be nice if you could try the below method as well. void Process_Firmware_Packet(size_t const & current_chunk, uint8_t *payload, size_t const & total_bytes) {
...
else if ((m_requested_chunks + 1 < m_total_chunks && total_bytes != m_fw_callback->Get_Chunk_Size()) || (m_requested_chunks + 1 >= m_total_chunks && total_bytes != (m_fw_size % m_fw_callback->Get_Chunk_Size()))) {
char message[Helper::detectSize("Expected chunk size of %u, but got %u", m_fw_callback->Get_Chunk_Size(), total_bytes)];
snprintf(message, sizeof(message), "Expected chunk size of %u, but got %u", m_fw_callback->Get_Chunk_Size(), total_bytes);
Logger::log(message);
(void)m_send_fw_state_callback(FW_STATE_FAILED, message);
return Handle_Failure(OTA_Failure_Response::RETRY_CHUNK);
}
...
} |
I'm pleased to share that the issue has been successfully resolved, and I want to extend my gratitude to you for the invaluable support. The solution involved updating the 'ArduinoJson' library from version 6.20.1 to the latest version, 6.21.4. Your consistent and prompt responses were greatly appreciated throughout this process. Thank you for your expertise. |
Good to know thanks a lot for the information, it's nice to know it wasn't an internal library issue. |
Hello community! I'm currently using a SIM800L module to establish a connection with ThingsBoard for performing OTA firmware updates on my ESP32. My program is based on the following example from the ThingsBoard Client SDK: 'thingsboard-client-sdk/examples/0009-esp8266_esp32_process_OTA_MQTT/'. The process seems to work fine initially, successfully downloading the firmware 2 or 3 times. However, at some point, I encounter an issue where the device starts receiving chunks with a size of 0 bytes. Any insights or suggestions for troubleshooting this intermittent challenge would be greatly appreciated. Thank you!"
The text was updated successfully, but these errors were encountered: