test_switch_ota.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*
  7. * Tests for switching between partitions: factory, OTAx, test.
  8. */
  9. #include <esp_types.h>
  10. #include <stdio.h>
  11. #include "string.h"
  12. #include "sdkconfig.h"
  13. #include "esp_rom_spiflash.h"
  14. #include "freertos/FreeRTOS.h"
  15. #include "freertos/task.h"
  16. #include "freertos/semphr.h"
  17. #include "freertos/queue.h"
  18. #include "unity.h"
  19. #include "bootloader_common.h"
  20. #include "../bootloader_flash/include/bootloader_flash_priv.h"
  21. #include "esp_log.h"
  22. #include "esp_ota_ops.h"
  23. #include "esp_partition.h"
  24. #include "esp_flash_partitions.h"
  25. #include "esp_image_format.h"
  26. #include "nvs_flash.h"
  27. #include "driver/gpio.h"
  28. #include "esp_sleep.h"
  29. #include "test_utils.h"
  30. #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
  31. //IDF-5131
  32. RTC_DATA_ATTR static int boot_count = 0;
  33. static const char *TAG = "ota_test";
  34. /* @brief Copies a current app to next partition using handle.
  35. *
  36. * @param[in] update_handle - Handle of API ota.
  37. * @param[in] cur_app - Current app.
  38. */
  39. static void copy_app_partition(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
  40. {
  41. const void *partition_bin = NULL;
  42. spi_flash_mmap_handle_t data_map;
  43. ESP_LOGI(TAG, "start the copy process");
  44. TEST_ESP_OK(esp_partition_mmap(curr_app, 0, curr_app->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
  45. TEST_ESP_OK(esp_ota_write(update_handle, (const void *)partition_bin, curr_app->size));
  46. spi_flash_munmap(data_map);
  47. ESP_LOGI(TAG, "finish the copy process");
  48. }
  49. /* @brief Copies a current app to next partition using handle.
  50. *
  51. * @param[in] update_handle - Handle of API ota.
  52. * @param[in] cur_app - Current app.
  53. */
  54. static void copy_app_partition_with_offset(esp_ota_handle_t update_handle, const esp_partition_t *curr_app)
  55. {
  56. const void *partition_bin = NULL;
  57. spi_flash_mmap_handle_t data_map;
  58. ESP_LOGI(TAG, "start the copy process");
  59. uint32_t offset = 0, bytes_to_write = curr_app->size;
  60. uint32_t write_bytes;
  61. while (bytes_to_write > 0) {
  62. write_bytes = (bytes_to_write > (4 * 1024)) ? (4 * 1024) : bytes_to_write;
  63. TEST_ESP_OK(esp_partition_mmap(curr_app, offset, write_bytes, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
  64. TEST_ESP_OK(esp_ota_write_with_offset(update_handle, (const void *)partition_bin, write_bytes, offset));
  65. spi_flash_munmap(data_map);
  66. bytes_to_write -= write_bytes;
  67. offset += write_bytes;
  68. }
  69. ESP_LOGI(TAG, "finish the copy process");
  70. }
  71. #if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
  72. /* @brief Copies partition from source partition to destination partition.
  73. *
  74. * Partitions can be of any types and subtypes.
  75. * @param[in] dst_partition - Destination partition
  76. * @param[in] src_partition - Source partition
  77. */
  78. static void copy_partition(const esp_partition_t *dst_partition, const esp_partition_t *src_partition)
  79. {
  80. const void *partition_bin = NULL;
  81. spi_flash_mmap_handle_t data_map;
  82. TEST_ESP_OK(esp_partition_mmap(src_partition, 0, src_partition->size, SPI_FLASH_MMAP_DATA, &partition_bin, &data_map));
  83. TEST_ESP_OK(esp_partition_erase_range(dst_partition, 0, dst_partition->size));
  84. TEST_ESP_OK(esp_partition_write(dst_partition, 0, (const void *)partition_bin, dst_partition->size));
  85. spi_flash_munmap(data_map);
  86. }
  87. #endif
  88. /* @brief Get the next partition of OTA for the update.
  89. *
  90. * @return The next partition of OTA(OTA0-15).
  91. */
  92. static const esp_partition_t * get_next_update_partition(void)
  93. {
  94. const esp_partition_t *update_partition = esp_ota_get_next_update_partition(NULL);
  95. TEST_ASSERT_NOT_EQUAL(NULL, update_partition);
  96. ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", update_partition->subtype, update_partition->address);
  97. return update_partition;
  98. }
  99. /* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
  100. *
  101. * @param[in] cur_app_partition - Current app.
  102. * @param[in] next_app_partition - Next app for boot.
  103. */
  104. static void copy_current_app_to_next_part(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
  105. {
  106. esp_ota_get_next_update_partition(NULL);
  107. TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
  108. ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
  109. esp_ota_handle_t update_handle = 0;
  110. TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
  111. copy_app_partition(update_handle, cur_app_partition);
  112. TEST_ESP_OK(esp_ota_end(update_handle));
  113. TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
  114. }
  115. /* @brief Copies a current app to next partition (OTA0-15) and then configure OTA data for a new boot partition.
  116. *
  117. * @param[in] cur_app_partition - Current app.
  118. * @param[in] next_app_partition - Next app for boot.
  119. */
  120. static void copy_current_app_to_next_part_with_offset(const esp_partition_t *cur_app_partition, const esp_partition_t *next_app_partition)
  121. {
  122. esp_ota_get_next_update_partition(NULL);
  123. TEST_ASSERT_NOT_EQUAL(NULL, next_app_partition);
  124. ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", next_app_partition->subtype, next_app_partition->address);
  125. esp_ota_handle_t update_handle = 0;
  126. TEST_ESP_OK(esp_ota_begin(next_app_partition, OTA_SIZE_UNKNOWN, &update_handle));
  127. copy_app_partition_with_offset(update_handle, cur_app_partition);
  128. TEST_ESP_OK(esp_ota_end(update_handle));
  129. TEST_ESP_OK(esp_ota_set_boot_partition(next_app_partition));
  130. }
  131. /* @brief Erase otadata partition
  132. */
  133. static void erase_ota_data(void)
  134. {
  135. const esp_partition_t *data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
  136. TEST_ASSERT_NOT_EQUAL(NULL, data_partition);
  137. TEST_ESP_OK(esp_partition_erase_range(data_partition, 0, 2 * SPI_FLASH_SEC_SIZE));
  138. }
  139. /* @brief Reboots ESP using mode deep sleep. This mode guaranty that RTC_DATA_ATTR variables is not reset.
  140. */
  141. static void reboot_as_deep_sleep(void)
  142. {
  143. ESP_LOGI(TAG, "reboot as deep sleep");
  144. esp_sleep_enable_timer_wakeup(2000);
  145. esp_deep_sleep_start();
  146. }
  147. /* @brief Copies a current app to next partition (OTA0-15), after that ESP is rebooting and run this (the next) OTAx.
  148. */
  149. static void copy_current_app_to_next_part_and_reboot(void)
  150. {
  151. const esp_partition_t *cur_app = esp_ota_get_running_partition();
  152. ESP_LOGI(TAG, "copy current app to next part");
  153. copy_current_app_to_next_part(cur_app, get_next_update_partition());
  154. reboot_as_deep_sleep();
  155. }
  156. /* @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.
  157. */
  158. static void copy_current_app_to_next_part_with_offset_and_reboot(void)
  159. {
  160. const esp_partition_t *cur_app = esp_ota_get_running_partition();
  161. ESP_LOGI(TAG, "copy current app to next part");
  162. copy_current_app_to_next_part_with_offset(cur_app, get_next_update_partition());
  163. reboot_as_deep_sleep();
  164. }
  165. /* @brief Get running app.
  166. *
  167. * @return The next partition of OTA(OTA0-15).
  168. */
  169. static const esp_partition_t* get_running_firmware(void)
  170. {
  171. const esp_partition_t *configured = esp_ota_get_boot_partition();
  172. const esp_partition_t *running = esp_ota_get_running_partition();
  173. ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
  174. running->type, running->subtype, running->address);
  175. ESP_LOGI(TAG, "Configured partition type %d subtype %d (offset 0x%08x)",
  176. configured->type, configured->subtype, configured->address);
  177. TEST_ASSERT_NOT_EQUAL(NULL, configured);
  178. TEST_ASSERT_NOT_EQUAL(NULL, running);
  179. if (running->subtype != ESP_PARTITION_SUBTYPE_APP_TEST) {
  180. TEST_ASSERT_EQUAL_PTR(running, configured);
  181. }
  182. return running;
  183. }
  184. // type of a corrupt ota_data
  185. typedef enum {
  186. CORR_CRC_1_SECTOR_OTA_DATA = (1 << 0), /*!< Corrupt CRC only 1 sector of ota_data */
  187. CORR_CRC_2_SECTOR_OTA_DATA = (1 << 1), /*!< Corrupt CRC only 2 sector of ota_data */
  188. } corrupt_ota_data_t;
  189. /* @brief Get two copies ota_data from otadata partition.
  190. *
  191. * @param[in] otadata_partition - otadata partition.
  192. * @param[out] ota_data_0 - First copy from otadata_partition.
  193. * @param[out] ota_data_1 - Second copy from otadata_partition.
  194. */
  195. static void get_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data_0, esp_ota_select_entry_t *ota_data_1)
  196. {
  197. uint32_t offset = otadata_partition->address;
  198. uint32_t size = otadata_partition->size;
  199. if (offset != 0) {
  200. const esp_ota_select_entry_t *ota_select_map;
  201. ota_select_map = bootloader_mmap(offset, size);
  202. TEST_ASSERT_NOT_EQUAL(NULL, ota_select_map);
  203. memcpy(ota_data_0, ota_select_map, sizeof(esp_ota_select_entry_t));
  204. memcpy(ota_data_1, (uint8_t *)ota_select_map + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
  205. bootloader_munmap(ota_select_map);
  206. }
  207. }
  208. /* @brief Writes a ota_data into required sector of otadata_partition.
  209. *
  210. * @param[in] otadata_partition - Partition information otadata.
  211. * @param[in] ota_data - otadata structure.
  212. * @param[in] sec_id - Sector number 0 or 1.
  213. */
  214. static void write_ota_data(const esp_partition_t *otadata_partition, esp_ota_select_entry_t *ota_data, int sec_id)
  215. {
  216. esp_partition_write(otadata_partition, SPI_FLASH_SEC_SIZE * sec_id, &ota_data[sec_id], sizeof(esp_ota_select_entry_t));
  217. }
  218. /* @brief Makes a corrupt of ota_data.
  219. * @param[in] err - type error
  220. */
  221. static void corrupt_ota_data(corrupt_ota_data_t err)
  222. {
  223. esp_ota_select_entry_t ota_data[2];
  224. const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
  225. TEST_ASSERT_NOT_EQUAL(NULL, otadata_partition);
  226. get_ota_data(otadata_partition, &ota_data[0], &ota_data[1]);
  227. if (err & CORR_CRC_1_SECTOR_OTA_DATA) {
  228. ota_data[0].crc = 0;
  229. }
  230. if (err & CORR_CRC_2_SECTOR_OTA_DATA) {
  231. ota_data[1].crc = 0;
  232. }
  233. TEST_ESP_OK(esp_partition_erase_range(otadata_partition, 0, otadata_partition->size));
  234. write_ota_data(otadata_partition, &ota_data[0], 0);
  235. write_ota_data(otadata_partition, &ota_data[1], 1);
  236. }
  237. #if defined(CONFIG_BOOTLOADER_FACTORY_RESET) || defined(CONFIG_BOOTLOADER_APP_TEST)
  238. /* @brief Sets the pin number to output and sets output level as low. After reboot (deep sleep) this pin keep the same level.
  239. *
  240. * The output level of the pad will be force locked and can not be changed.
  241. * Power down or call gpio_hold_dis will disable this function.
  242. *
  243. * @param[in] num_pin - Pin number
  244. */
  245. static void set_output_pin(uint32_t num_pin)
  246. {
  247. TEST_ESP_OK(gpio_hold_dis(num_pin));
  248. gpio_config_t io_conf;
  249. io_conf.intr_type = GPIO_INTR_DISABLE;
  250. io_conf.mode = GPIO_MODE_OUTPUT;
  251. io_conf.pin_bit_mask = (1ULL << num_pin);
  252. io_conf.pull_down_en = 0;
  253. io_conf.pull_up_en = 0;
  254. TEST_ESP_OK(gpio_config(&io_conf));
  255. TEST_ESP_OK(gpio_set_level(num_pin, 0));
  256. TEST_ESP_OK(gpio_hold_en(num_pin));
  257. }
  258. /* @brief Unset the pin number hold function.
  259. */
  260. static void reset_output_pin(uint32_t num_pin)
  261. {
  262. TEST_ESP_OK(gpio_hold_dis(num_pin));
  263. TEST_ESP_OK(gpio_reset_pin(num_pin));
  264. }
  265. #endif
  266. static void mark_app_valid(void)
  267. {
  268. #ifdef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  269. TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
  270. #endif
  271. }
  272. /* @brief Checks and prepares the partition so that the factory app is launched after that.
  273. */
  274. static void start_test(void)
  275. {
  276. ESP_LOGI(TAG, "boot count 1 - reset");
  277. boot_count = 1;
  278. erase_ota_data();
  279. ESP_LOGI(TAG, "ota_data erased");
  280. reboot_as_deep_sleep();
  281. }
  282. static void test_flow1(void)
  283. {
  284. boot_count++;
  285. ESP_LOGI(TAG, "boot count %d", boot_count);
  286. const esp_partition_t *cur_app = get_running_firmware();
  287. switch (boot_count) {
  288. case 2:
  289. ESP_LOGI(TAG, "Factory");
  290. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  291. copy_current_app_to_next_part_and_reboot();
  292. break;
  293. case 3:
  294. ESP_LOGI(TAG, "OTA0");
  295. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  296. mark_app_valid();
  297. copy_current_app_to_next_part_and_reboot();
  298. break;
  299. case 4:
  300. ESP_LOGI(TAG, "OTA1");
  301. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
  302. mark_app_valid();
  303. copy_current_app_to_next_part_and_reboot();
  304. break;
  305. case 5:
  306. ESP_LOGI(TAG, "OTA0");
  307. mark_app_valid();
  308. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  309. erase_ota_data();
  310. break;
  311. default:
  312. erase_ota_data();
  313. TEST_FAIL_MESSAGE("Unexpected stage");
  314. break;
  315. }
  316. }
  317. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  318. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  319. // 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
  320. // 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
  321. // 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
  322. TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
  323. static void test_flow2(void)
  324. {
  325. boot_count++;
  326. ESP_LOGI(TAG, "boot count %d", boot_count);
  327. const esp_partition_t *cur_app = get_running_firmware();
  328. switch (boot_count) {
  329. case 2:
  330. ESP_LOGI(TAG, "Factory");
  331. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  332. copy_current_app_to_next_part_and_reboot();
  333. break;
  334. case 3:
  335. ESP_LOGI(TAG, "OTA0");
  336. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  337. mark_app_valid();
  338. copy_current_app_to_next_part(cur_app, get_next_update_partition());
  339. corrupt_ota_data(CORR_CRC_1_SECTOR_OTA_DATA);
  340. reboot_as_deep_sleep();
  341. break;
  342. case 4:
  343. ESP_LOGI(TAG, "Factory");
  344. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  345. erase_ota_data();
  346. break;
  347. default:
  348. erase_ota_data();
  349. TEST_FAIL_MESSAGE("Unexpected stage");
  350. break;
  351. }
  352. }
  353. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  354. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  355. // 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
  356. // 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
  357. TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
  358. static void test_flow3(void)
  359. {
  360. boot_count++;
  361. ESP_LOGI(TAG, "boot count %d", boot_count);
  362. const esp_partition_t *cur_app = get_running_firmware();
  363. switch (boot_count) {
  364. case 2:
  365. ESP_LOGI(TAG, "Factory");
  366. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  367. copy_current_app_to_next_part_and_reboot();
  368. break;
  369. case 3:
  370. ESP_LOGI(TAG, "OTA0");
  371. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  372. mark_app_valid();
  373. copy_current_app_to_next_part_and_reboot();
  374. break;
  375. case 4:
  376. ESP_LOGI(TAG, "OTA1");
  377. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
  378. mark_app_valid();
  379. copy_current_app_to_next_part(cur_app, get_next_update_partition());
  380. corrupt_ota_data(CORR_CRC_2_SECTOR_OTA_DATA);
  381. reboot_as_deep_sleep();
  382. break;
  383. case 5:
  384. ESP_LOGI(TAG, "OTA0");
  385. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  386. erase_ota_data();
  387. break;
  388. default:
  389. erase_ota_data();
  390. TEST_FAIL_MESSAGE("Unexpected stage");
  391. break;
  392. }
  393. }
  394. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  395. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  396. // 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
  397. // 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
  398. // 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
  399. TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
  400. #ifdef CONFIG_BOOTLOADER_FACTORY_RESET
  401. #define STORAGE_NAMESPACE "update_ota"
  402. static void test_flow4(void)
  403. {
  404. boot_count++;
  405. ESP_LOGI(TAG, "boot count %d", boot_count);
  406. const esp_partition_t *cur_app = get_running_firmware();
  407. nvs_handle_t handle = 0;
  408. int32_t boot_count_nvs = 0;
  409. switch (boot_count) {
  410. case 2:
  411. ESP_LOGI(TAG, "Factory");
  412. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  413. TEST_ESP_OK(nvs_flash_erase());
  414. TEST_ESP_OK(nvs_flash_init());
  415. TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
  416. TEST_ESP_OK(nvs_set_i32(handle, "boot_count", boot_count));
  417. TEST_ESP_OK(nvs_commit(handle));
  418. nvs_close(handle);
  419. nvs_flash_deinit();
  420. copy_current_app_to_next_part_and_reboot();
  421. break;
  422. case 3:
  423. ESP_LOGI(TAG, "OTA0");
  424. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  425. mark_app_valid();
  426. TEST_ESP_OK(nvs_flash_init());
  427. TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
  428. TEST_ESP_OK(nvs_get_i32(handle, "boot_count", &boot_count_nvs));
  429. TEST_ASSERT_EQUAL(boot_count_nvs + 1, boot_count);
  430. nvs_close(handle);
  431. nvs_flash_deinit();
  432. set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
  433. reboot_as_deep_sleep();
  434. break;
  435. case 4:
  436. reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
  437. ESP_LOGI(TAG, "Factory");
  438. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  439. int32_t boot_count_nvs;
  440. TEST_ESP_OK(nvs_flash_init());
  441. TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
  442. TEST_ESP_ERR(ESP_ERR_NVS_NOT_FOUND, nvs_get_i32(handle, "boot_count", &boot_count_nvs));
  443. nvs_close(handle);
  444. nvs_flash_deinit();
  445. erase_ota_data();
  446. break;
  447. default:
  448. reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET);
  449. erase_ota_data();
  450. TEST_FAIL_MESSAGE("Unexpected stage");
  451. break;
  452. }
  453. }
  454. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  455. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  456. // 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
  457. // 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
  458. TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
  459. #endif
  460. #ifdef CONFIG_BOOTLOADER_APP_TEST
  461. static void test_flow5(void)
  462. {
  463. boot_count++;
  464. ESP_LOGI(TAG, "boot count %d", boot_count);
  465. const esp_partition_t *cur_app = get_running_firmware();
  466. switch (boot_count) {
  467. case 2:
  468. ESP_LOGI(TAG, "Factory");
  469. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  470. set_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
  471. copy_partition(esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEST, NULL), cur_app);
  472. esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
  473. reboot_as_deep_sleep();
  474. break;
  475. case 3:
  476. reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
  477. ESP_LOGI(TAG, "Test");
  478. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_TEST, cur_app->subtype);
  479. reboot_as_deep_sleep();
  480. break;
  481. case 4:
  482. ESP_LOGI(TAG, "Factory");
  483. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  484. erase_ota_data();
  485. break;
  486. default:
  487. reset_output_pin(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST);
  488. erase_ota_data();
  489. TEST_FAIL_MESSAGE("Unexpected stage");
  490. break;
  491. }
  492. }
  493. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  494. // 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
  495. // 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
  496. // 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
  497. TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
  498. #endif
  499. static const esp_partition_t* app_update(void)
  500. {
  501. const esp_partition_t *cur_app = get_running_firmware();
  502. const esp_partition_t* update_partition = esp_ota_get_next_update_partition(NULL);
  503. TEST_ASSERT_NOT_NULL(update_partition);
  504. esp_ota_handle_t update_handle = 0;
  505. TEST_ESP_OK(esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle));
  506. copy_app_partition(update_handle, cur_app);
  507. TEST_ESP_OK(esp_ota_end(update_handle));
  508. TEST_ESP_OK(esp_ota_set_boot_partition(update_partition));
  509. return update_partition;
  510. }
  511. static void test_rollback1(void)
  512. {
  513. boot_count++;
  514. ESP_LOGI(TAG, "boot count %d", boot_count);
  515. const esp_partition_t *cur_app = get_running_firmware();
  516. esp_ota_img_states_t ota_state = 0x5555AAAA;
  517. const esp_partition_t* update_partition = NULL;
  518. switch (boot_count) {
  519. case 2:
  520. ESP_LOGI(TAG, "Factory");
  521. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  522. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  523. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
  524. update_partition = app_update();
  525. TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
  526. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  527. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  528. #else
  529. TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
  530. #endif
  531. reboot_as_deep_sleep();
  532. break;
  533. case 3:
  534. ESP_LOGI(TAG, "OTA0");
  535. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  536. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  537. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  538. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  539. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  540. #else
  541. TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
  542. #endif
  543. TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
  544. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  545. TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
  546. reboot_as_deep_sleep();
  547. break;
  548. case 4:
  549. ESP_LOGI(TAG, "OTA0");
  550. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  551. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  552. TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
  553. TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
  554. break;
  555. default:
  556. erase_ota_data();
  557. TEST_FAIL_MESSAGE("Unexpected stage");
  558. break;
  559. }
  560. }
  561. static void test_rollback1_1(void)
  562. {
  563. boot_count = 5;
  564. esp_ota_img_states_t ota_state = 0x5555AAAA;
  565. ESP_LOGI(TAG, "boot count %d", boot_count);
  566. const esp_partition_t *cur_app = get_running_firmware();
  567. ESP_LOGI(TAG, "Factory");
  568. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  569. const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
  570. const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
  571. TEST_ASSERT_NOT_NULL(invalid_partition);
  572. TEST_ASSERT_NOT_NULL(next_update_partition);
  573. TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
  574. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
  575. TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
  576. TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
  577. erase_ota_data();
  578. }
  579. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  580. // 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
  581. // 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
  582. // 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
  583. // 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
  584. TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
  585. static void test_rollback2(void)
  586. {
  587. boot_count++;
  588. ESP_LOGI(TAG, "boot count %d", boot_count);
  589. const esp_partition_t *cur_app = get_running_firmware();
  590. esp_ota_img_states_t ota_state = 0x5555AAAA;
  591. const esp_partition_t* update_partition = NULL;
  592. switch (boot_count) {
  593. case 2:
  594. ESP_LOGI(TAG, "Factory");
  595. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  596. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  597. TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
  598. update_partition = app_update();
  599. TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
  600. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  601. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  602. #else
  603. TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
  604. #endif
  605. reboot_as_deep_sleep();
  606. break;
  607. case 3:
  608. ESP_LOGI(TAG, "OTA0");
  609. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  610. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  611. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  612. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  613. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  614. #else
  615. TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
  616. #endif
  617. TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
  618. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  619. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  620. TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
  621. update_partition = app_update();
  622. TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
  623. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  624. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  625. #else
  626. TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
  627. #endif
  628. reboot_as_deep_sleep();
  629. break;
  630. case 4:
  631. ESP_LOGI(TAG, "OTA1");
  632. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
  633. TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
  634. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  635. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  636. TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
  637. TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
  638. #else
  639. TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
  640. reboot_as_deep_sleep();
  641. #endif
  642. break;
  643. default:
  644. erase_ota_data();
  645. TEST_FAIL_MESSAGE("Unexpected stage");
  646. break;
  647. }
  648. }
  649. static void test_rollback2_1(void)
  650. {
  651. boot_count = 5;
  652. esp_ota_img_states_t ota_state = 0x5555AAAA;
  653. ESP_LOGI(TAG, "boot count %d", boot_count);
  654. const esp_partition_t *cur_app = get_running_firmware();
  655. ESP_LOGI(TAG, "OTA0");
  656. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  657. const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
  658. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, invalid_partition->subtype);
  659. const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
  660. TEST_ASSERT_NOT_NULL(invalid_partition);
  661. TEST_ASSERT_NOT_NULL(next_update_partition);
  662. TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
  663. TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
  664. TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
  665. TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
  666. #ifndef CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE
  667. TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
  668. #else
  669. TEST_ASSERT_EQUAL(ESP_OTA_IMG_ABORTED, ota_state);
  670. #endif
  671. erase_ota_data();
  672. }
  673. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  674. // 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
  675. // 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
  676. // 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
  677. // 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
  678. TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
  679. static void test_erase_last_app_flow(void)
  680. {
  681. boot_count++;
  682. ESP_LOGI(TAG, "boot count %d", boot_count);
  683. const esp_partition_t *cur_app = get_running_firmware();
  684. switch (boot_count) {
  685. case 2:
  686. ESP_LOGI(TAG, "Factory");
  687. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  688. app_update();
  689. reboot_as_deep_sleep();
  690. break;
  691. case 3:
  692. ESP_LOGI(TAG, "OTA0");
  693. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  694. mark_app_valid();
  695. app_update();
  696. reboot_as_deep_sleep();
  697. break;
  698. case 4:
  699. ESP_LOGI(TAG, "OTA1");
  700. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
  701. TEST_ESP_OK(esp_ota_erase_last_boot_app_partition());
  702. TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
  703. reboot_as_deep_sleep();
  704. break;
  705. default:
  706. erase_ota_data();
  707. TEST_FAIL_MESSAGE("Unexpected stage");
  708. break;
  709. }
  710. }
  711. static void test_erase_last_app_rollback(void)
  712. {
  713. boot_count = 5;
  714. ESP_LOGI(TAG, "boot count %d", boot_count);
  715. const esp_partition_t *cur_app = get_running_firmware();
  716. ESP_LOGI(TAG, "erase_last_app");
  717. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  718. TEST_ESP_ERR(ESP_FAIL, esp_ota_erase_last_boot_app_partition());
  719. erase_ota_data();
  720. }
  721. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  722. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  723. // 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
  724. // 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
  725. // 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
  726. 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);
  727. static void test_flow6(void)
  728. {
  729. boot_count++;
  730. ESP_LOGI(TAG, "boot count %d", boot_count);
  731. const esp_partition_t *cur_app = get_running_firmware();
  732. switch (boot_count) {
  733. case 2:
  734. ESP_LOGI(TAG, "Factory");
  735. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
  736. copy_current_app_to_next_part_with_offset_and_reboot();
  737. break;
  738. case 3:
  739. ESP_LOGI(TAG, "OTA0");
  740. TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
  741. mark_app_valid();
  742. erase_ota_data();
  743. break;
  744. default:
  745. erase_ota_data();
  746. TEST_FAIL_MESSAGE("Unexpected stage");
  747. break;
  748. }
  749. }
  750. // 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
  751. // 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
  752. // 3 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
  753. 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);
  754. //IDF-5145
  755. TEST_CASE("Test bootloader_common_get_sha256_of_partition returns ESP_ERR_IMAGE_INVALID when image is ivalid", "[partitions]")
  756. {
  757. const esp_partition_t *cur_app = esp_ota_get_running_partition();
  758. ESP_LOGI(TAG, "copy current app to next part");
  759. const esp_partition_t *other_app = get_next_update_partition();
  760. copy_current_app_to_next_part(cur_app, other_app);
  761. erase_ota_data();
  762. uint8_t sha_256_cur_app[32];
  763. uint8_t sha_256_other_app[32];
  764. TEST_ESP_OK(bootloader_common_get_sha256_of_partition(cur_app->address, cur_app->size, cur_app->type, sha_256_cur_app));
  765. TEST_ESP_OK(bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app));
  766. TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same");
  767. uint32_t data = 0;
  768. bootloader_flash_write(other_app->address + 0x50, &data, sizeof(data), false);
  769. TEST_ESP_ERR(ESP_ERR_IMAGE_INVALID, bootloader_common_get_sha256_of_partition(other_app->address, other_app->size, other_app->type, sha_256_other_app));
  770. TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha_256_cur_app, sha_256_other_app, sizeof(sha_256_cur_app), "must be the same");
  771. }
  772. #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)