|
|
@@ -55,6 +55,29 @@ static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partiti
|
|
|
ESP_LOGI(TAG, "finish the copy process");
|
|
|
}
|
|
|
|
|
|
+/* @brief Copies a current app to next partition using handle.
|
|
|
+ *
|
|
|
+ * @param[in] update_handle - Handle of API ota.
|
|
|
+ * @param[in] cur_app - Current app.
|
|
|
+ */
|
|
|
+static void copy_app_partition_with_offset(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
|
|
|
+{
|
|
|
+ const void *partition_bin = NULL;
|
|
|
+ spi_flash_mmap_handle_t data_map;
|
|
|
+ ESP_LOGI(TAG, "start the copy process");
|
|
|
+ uint32_t offset = 0, bytes_to_write = curr_app->size;
|
|
|
+ uint32_t write_bytes;
|
|
|
+ while (bytes_to_write > 0) {
|
|
|
+ write_bytes = (bytes_to_write > (4 * 1024)) ? (4 * 1024) : bytes_to_write;
|
|
|
+ TEST_ESP_OK(esp_partition_mmap(curr_app, offset, write_bytes, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
|
|
|
+ TEST_ESP_OK(esp_ota_write_with_offset(update_handle, (const void *)partition_bin, write_bytes, offset));
|
|
|
+ spi_flash_munmap(data_map);
|
|
|
+ bytes_to_write -= write_bytes;
|
|
|
+ offset += write_bytes;
|
|
|
+ }
|
|
|
+ ESP_LOGI(TAG, "finish the copy process");
|
|
|
+}
|
|
|
+
|
|
|
#if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
|
|
|
/* @brief Copies partition from source partition to destination partition.
|
|
|
*
|
|
|
@@ -105,6 +128,26 @@ static void copy_current_app_to_next_part(const esp_partition_t *cur_app_partiti
|
|
|
TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
|
|
|
}
|
|
|
|
|
|
+/* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
|
|
|
+ *
|
|
|
+ * @param[in] cur_app_partition - Current app.
|
|
|
+ * @param[in] next_app_partition - Next app for boot.
|
|
|
+ */
|
|
|
+static void copy_current_app_to_next_part_with_offset(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
|
|
|
+{
|
|
|
+ esp_ota_get_next_update_partition(NULL);
|
|
|
+ TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
|
|
|
+ ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
|
|
|
+
|
|
|
+ esp_ota_handle_t update_handle = 0;
|
|
|
+ TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
|
|
+
|
|
|
+ copy_app_partition_with_offset(update_handle, cur_app_partition);
|
|
|
+
|
|
|
+ TEST_ESP_OK(esp_ota_end(update_handle));
|
|
|
+ TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
|
|
|
+}
|
|
|
+
|
|
|
/* @brief Erase otadata partition
|
|
|
*/
|
|
|
static void erase_ota_data(void)
|
|
|
@@ -133,6 +176,16 @@ static void copy_current_app_to_next_part_and_reboot(void)
|
|
|
reboot_as_deep_sleep();
|
|
|
}
|
|
|
|
|
|
+/* @brief Copies a current app to next partition (OTA0-15) using esp_ota_write_with_offest(), after that ESP is rebooting and run this (the next) OTAx.
|
|
|
+ */
|
|
|
+static void copy_current_app_to_next_part_with_offset_and_reboot(void)
|
|
|
+{
|
|
|
+ const esp_partition_t *cur_app = esp_ota_get_running_partition();
|
|
|
+ ESP_LOGI(TAG, "copy current app to next part");
|
|
|
+ copy_current_app_to_next_part_with_offset(cur_app, get_next_update_partition());
|
|
|
+ reboot_as_deep_sleep();
|
|
|
+}
|
|
|
+
|
|
|
/* @brief Get running app.
|
|
|
*
|
|
|
* @return The next partition of OTA(OTA0-15).
|
|
|
@@ -740,3 +793,32 @@ static void test_erase_last_app_rollback(void)
|
|
|
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
|
|
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
|
|
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
|
|
+
|
|
|
+static void test_flow6(void)
|
|
|
+{
|
|
|
+ boot_count++;
|
|
|
+ ESP_LOGI(TAG, "boot count %d", boot_count);
|
|
|
+ const esp_partition_t *cur_app = get_running_firmware();
|
|
|
+ switch (boot_count) {
|
|
|
+ case 2:
|
|
|
+ ESP_LOGI(TAG, "Factory");
|
|
|
+ TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
|
|
+ copy_current_app_to_next_part_with_offset_and_reboot();
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ ESP_LOGI(TAG, "OTA0");
|
|
|
+ TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
|
|
+ mark_app_valid();
|
|
|
+ erase_ota_data();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ erase_ota_data();
|
|
|
+ TEST_FAIL_MESSAGE("Unexpected stage");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
|
|
+// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
|
|
+// 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
|
|
+TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0 using esp_ota_write_with_offset", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow6, test_flow6);
|