Page 1 of 1

Error while trying to update the firmware via OTA

Posted: Mon May 20, 2024 12:33 pm
by Heet_Shukla
Currently I'm wroking on ESP32 wroom 16mb.
I'm fetching firmware file from Web Server for OTA using GSM Module Cavli C16Qs. Cavli C16Qs is Connected with ESP32 via ESP Serial1.
I Configure HTTP Connection with cavli C16Qs to server using AT COMMAND. I also able to download file from server. Esp32 is getting file from ATSerial(ESP32 Serial1). My Firmware file size is 250KB. So i need to append that file. I tried but File is corrupted.
The size of the file being appended is the same as my BIN file. But when I am read that file, the data in that file is corrupted.
If any normal words are appended or used in read, they are being appended correctly. But when I try to append my firmware file it is not appending correctly. it is corrupted.
I'm use Partition Scheme: 16MB flash (3MB APP/9.9MB FATFS) for Append file.
I'm append file using FFat file system, And 16mb file partition.
so basically Issue why I'm not able to append data of file properly?
  1. #include "FS.h"
  2. #include "FFat.h"
  3. #include <freertos/FreeRTOS.h>
  4. #include <freertos/task.h>
  5. #include <freertos/queue.h>
  6.  
  7. #include "soc/timer_group_struct.h"
  8. #include "soc/timer_group_reg.h"
  9.  
  10. #define BUFFER_SIZE 256
  11. #define QUEUE_SIZE 300
  12.  
  13. unsigned long lastSerial1Time = 0;
  14. QueueHandle_t QueueHandle;
  15.  
  16. File FF;
  17.  
  18. struct DataPacket {
  19.   uint8_t data[BUFFER_SIZE];
  20.   size_t bytesRead;
  21. };
  22.  
  23. bool packet_start = false;
  24. String currentSTR = "";
  25. #define FORMAT_FFAT true
  26.  
  27. void dataprocesa(void *pvParameters);
  28. void TaskReadFromSerial(void *pvParameters);
  29. void checkSPIFFSFreeSpace();
  30. void listDir(fs::FS &fs, const char *dirname, uint8_t levels);
  31. void readFile(fs::FS &fs, const char *path);
  32. void feedTheDog();
  33.  
  34. void checkSPIFFSFreeSpace() {
  35.   size_t totalBytes = FFat.totalBytes();
  36.   size_t usedBytes = FFat.usedBytes();
  37.   size_t freeBytes = totalBytes - usedBytes;
  38.  
  39.   Serial.print("Total space: ");
  40.   Serial.print(totalBytes);
  41.   Serial.println(" bytes");
  42.  
  43.   Serial.print("Used space: ");
  44.   Serial.print(usedBytes);
  45.   Serial.println(" bytes");
  46.  
  47.   Serial.print("Free space: ");
  48.   Serial.print(freeBytes);
  49.   Serial.println(" bytes");
  50. }
  51.  
  52. void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
  53.   Serial.printf("Listing directory: %s\r\n", dirname);
  54.  
  55.   File root = fs.open(dirname);
  56.   if (!root) {
  57.     Serial.println("- failed to open directory");
  58.     return;
  59.   }
  60.   if (!root.isDirectory()) {
  61.     Serial.println(" - not a directory");
  62.     return;
  63.   }
  64.  
  65.   File file = root.openNextFile();
  66.   while (file) {
  67.     if (file.isDirectory()) {
  68.       Serial.print("  DIR : ");
  69.       Serial.println(file.name());
  70.       if (levels) {
  71.         listDir(fs, file.path(), levels - 1);
  72.       }
  73.     } else {
  74.       Serial.print("  FILE: ");
  75.       Serial.print(file.name());
  76.       Serial.print("\tSIZE: ");
  77.       Serial.println(file.size());
  78.     }
  79.     file = root.openNextFile();
  80.   }
  81. }
  82.  
  83. void readFile(fs::FS &fs, const char *path) {
  84.   Serial.printf("Reading file: %s\r\n", path);
  85.  
  86.   File file = fs.open(path);
  87.   if (!file || file.isDirectory()) {
  88.     Serial.println("- failed to open file for reading");
  89.     return;
  90.   }
  91.  
  92.   Serial.println("- read from file:");
  93.   while (file.available()) {
  94.     Serial.write(file.read());
  95.   }
  96.   file.close();
  97. }
  98.  
  99. void feedTheDog() {
  100.   // feed dog 0
  101.   TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;  // write enable
  102.   TIMERG0.wdt_feed = 1;                        // feed dog
  103.   TIMERG0.wdt_wprotect = 0;                    // write protect
  104.   // feed dog 1
  105.   TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE;  // write enable
  106.   TIMERG1.wdt_feed = 1;                        // feed dog
  107.   TIMERG1.wdt_wprotect = 0;                    // write protect
  108. }
  109.  
  110. void setup() {
  111.   pinMode(PWRKEY, OUTPUT);
  112.   digitalWrite(PWRKEY, LOW);
  113.   delay(550);
  114.   digitalWrite(PWRKEY, HIGH);
  115.  
  116.   pinMode(RST_PIL, OUTPUT);
  117.   digitalWrite(RST_PIL, LOW);
  118.   delay(150);
  119.   digitalWrite(RST_PIL, HIGH);
  120.  
  121.   Serial.begin(230400);
  122.   Serial1.begin(230400, SERIAL_8N1, ESP_GPIO_RX, ESP_GPIO_TX);
  123.  
  124.   pinMode(2, OUTPUT);
  125.   digitalWrite(2, LOW);
  126.   delay(500);
  127.   digitalWrite(2, HIGH);
  128.  
  129.   if (FORMAT_FFAT) {
  130.     FFat.format();
  131.   }
  132.   if (!FFat.begin(true)) { // Format SPIFFS if mount fails
  133.     Serial.println("SPIFFS Mount Failed");
  134.     return;
  135.   }
  136.   checkSPIFFSFreeSpace();
  137.   // listDir(FFat, "/", 0);
  138.   Serial.println("Setup complete");
  139.   Serial.println("Start Configuration of Task");
  140.  
  141.   QueueHandle = xQueueCreate(QUEUE_SIZE, sizeof(DataPacket));
  142.  
  143.   if (QueueHandle == NULL) {
  144.     Serial.println("Queue could not be created. Halt.");
  145.     while (1) delay(1000);
  146.   }
  147.  
  148.   xTaskCreatePinnedToCore(
  149.     dataprocesa, "Task Write To Serial",
  150.     8192, NULL, 1, NULL, 0);
  151.  
  152.   xTaskCreatePinnedToCore(
  153.     TaskReadFromSerial, "Task Read From Serial",
  154.     8192, NULL, 2, NULL, 1);
  155. }
  156.  
  157. void loop() {
  158.   delay(1000);
  159. }
  160.  
  161. void dataprocesa(void *pvParameters) {
  162.   DataPacket receivedBuffer;
  163.   int datalen = 0;
  164.   FF = FFat.open("/file.bin", FILE_WRITE);
  165.   if (!FF) {
  166.     Serial.println("Failed to open file for appending");
  167.     return;
  168.   }
  169.  
  170.   for (;;) {
  171.     if (QueueHandle != NULL) {
  172.       if (xQueueReceive(QueueHandle, &receivedBuffer, portMAX_DELAY) == pdPASS) {
  173.         FF.write(receivedBuffer.data, receivedBuffer.bytesRead);
  174.       } else {
  175.         Serial.println("The `dataprocesa` was unable to receive data from the Queue");
  176.       }
  177.     }
  178.   }
  179. }
  180.  
  181. void TaskReadFromSerial(void *pvParameters) {
  182.   int pcktlen = 0;
  183.   DataPacket dataBuffer;
  184.   for (;;) {
  185.     feedTheDog();
  186.     // Read one byte at a time from Serial1
  187.     while (Serial1.available()) {
  188.       String header = Serial1.readStringUntil('\n');
  189.       if (header.startsWith("+CIPRECEIVE:")) {
  190.         pcktlen = header.substring(header.lastIndexOf(',') + 1).toInt();
  191.         while (pcktlen > 0) {
  192.           dataBuffer.bytesRead = Serial1.readBytes(dataBuffer.data, min(BUFFER_SIZE, pcktlen));
  193.           pcktlen -= dataBuffer.bytesRead;
  194.  
  195.           int ret = xQueueSend(QueueHandle, &dataBuffer, portMAX_DELAY);
  196.           if (ret != pdTRUE) {
  197.             Serial.println("The `TaskReadFromSerial` was unable to send data into the Queue");
  198.           }
  199.         }
  200.       }
  201.       lastSerial1Time = millis();
  202.     }
  203.  
  204.     // Echo any user input from Serial to Cavli module via Serial1
  205.     while (Serial.available()) {
  206.       char c = Serial.read();
  207.       Serial1.write(c);
  208.     }
  209.  
  210.     // Check for timeout to close the file
  211.     if (millis() - lastSerial1Time >= 30000) {
  212.       FF.close();  // Close the file
  213.       delay(500);
  214.       checkSPIFFSFreeSpace();
  215.       Serial.println("File closed due to Serial1 timeout.");
  216.       delay(1000);
  217.       readFile(FFat, "/file.bin");
  218.     }
  219.  
  220.     vTaskDelay(1);
  221.   }
  222. }

Re: Error while trying to update the firmware via OTA

Posted: Tue May 21, 2024 2:16 am
by ESP_Sprite
I split the post into its own topic as it didn't have much to do with the orighinal topic you posted this in.

For your code: I'd take a good look at line 192/193 and what happens to dataBuffer.bytesRead if the data needs to be read over multiple Serial1.readBytes iterations/