test_switch_ota.c 30 KB

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