Ver Fonte

Merge branch 'feature/app_metadata_to_esp_system' into 'master'

app_update: Moved app metadata to new component `esp_app_format`

Closes IDF-4808

See merge request espressif/esp-idf!18862
Mahavir Jain há 3 anos atrás
pai
commit
a2f028abe7
37 ficheiros alterados com 344 adições e 137 exclusões
  1. 1 0
      .gitlab/CODEOWNERS
  2. 2 25
      components/app_update/CMakeLists.txt
  3. 21 0
      components/app_update/esp_ota_app_desc.c
  4. 8 2
      components/app_update/esp_ota_ops.c
  5. 10 3
      components/app_update/include/esp_ota_ops.h
  6. 3 2
      components/app_update/test/test_ota_ops.c
  7. 11 2
      components/bootloader_support/CMakeLists.txt
  8. 0 15
      components/bootloader_support/include/bootloader_common.h
  9. 0 22
      components/bootloader_support/include/esp_app_format.h
  10. 0 24
      components/bootloader_support/src/bootloader_common_loader.c
  11. 26 0
      components/bootloader_support/src/bootloader_utility.c
  12. 26 0
      components/esp_app_format/CMakeLists.txt
  13. 0 0
      components/esp_app_format/Kconfig.projbuild
  14. 8 7
      components/esp_app_format/esp_app_desc.c
  15. 61 0
      components/esp_app_format/include/esp_app_desc.h
  16. 8 0
      components/esp_app_format/test_apps/CMakeLists.txt
  17. 2 0
      components/esp_app_format/test_apps/README.md
  18. 3 0
      components/esp_app_format/test_apps/main/CMakeLists.txt
  19. 31 8
      components/esp_app_format/test_apps/main/test_app_desc.c
  20. 11 0
      components/esp_app_format/test_apps/pytest_esp_app_format.py
  21. 11 0
      components/esp_app_format/test_apps/sdkconfig.defaults
  22. 1 1
      components/esp_https_ota/CMakeLists.txt
  23. 1 0
      components/esp_https_ota/include/esp_https_ota.h
  24. 1 1
      components/esp_system/CMakeLists.txt
  25. 6 6
      components/esp_system/panic.c
  26. 10 10
      components/esp_system/startup.c
  27. 5 1
      components/espcoredump/CMakeLists.txt
  28. 5 2
      components/espcoredump/src/core_dump_elf.c
  29. 2 1
      components/spi_flash/sim/Makefile.files
  30. 2 1
      components/spi_flash/sim/stubs/Makefile.files
  31. 46 0
      components/spi_flash/sim/stubs/esp_app_format/include/esp_app_desc.h
  32. 1 0
      docs/doxygen/Doxyfile
  33. 2 1
      docs/en/api-reference/system/misc_system_api.rst
  34. 12 0
      docs/en/migration-guides/release-5.x/system.rst
  35. 2 1
      docs/zh_CN/api-reference/system/misc_system_api.rst
  36. 1 0
      examples/system/ota/native_ota_example/main/native_ota_example.c
  37. 4 2
      tools/test_apps/system/g1_components/CMakeLists.txt

+ 1 - 0
.gitlab/CODEOWNERS

@@ -78,6 +78,7 @@
 /components/driver/                   @esp-idf-codeowners/peripherals
 /components/efuse/                    @esp-idf-codeowners/system
 /components/esp_adc/                  @esp-idf-codeowners/peripherals
+/components/esp_app_format/           @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
 /components/esp_common/               @esp-idf-codeowners/system
 /components/esp_eth/                  @esp-idf-codeowners/network
 /components/esp_event/                @esp-idf-codeowners/system

+ 2 - 25
components/app_update/CMakeLists.txt

@@ -1,31 +1,8 @@
-idf_component_register(SRCS "esp_ota_ops.c"
-                            "esp_app_desc.c"
+idf_component_register(SRCS "esp_ota_ops.c" "esp_ota_app_desc.c"
                     INCLUDE_DIRS "include"
-                    REQUIRES spi_flash partition_table bootloader_support
+                    REQUIRES spi_flash partition_table bootloader_support esp_app_format
                     PRIV_REQUIRES esptool_py efuse)
 
-# esp_app_desc structure is added as an undefined symbol because otherwise the
-# linker will ignore this structure as it has no other files depending on it.
-target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
-
-if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
-    # Ignore current PROJECT_VER (which was set in __project_get_revision()).
-    # Gets the version from the CONFIG_APP_PROJECT_VER.
-    idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
-endif()
-
-# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
-idf_build_get_property(project_ver PROJECT_VER)
-idf_build_get_property(project_name PROJECT_NAME)
-string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
-string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
-message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")
-
-set_source_files_properties(
-    SOURCE "esp_app_desc.c"
-    PROPERTIES COMPILE_DEFINITIONS
-    "PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
-
 if(NOT BOOTLOADER_BUILD)
     partition_table_get_partition_info(otadata_offset "--partition-type data --partition-subtype ota" "offset")
     partition_table_get_partition_info(otadata_size "--partition-type data --partition-subtype ota" "size")

+ 21 - 0
components/app_update/esp_ota_app_desc.c

@@ -0,0 +1,21 @@
+/*
+ * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <assert.h>
+#include <sys/param.h>
+#include "esp_ota_ops.h"
+#include "esp_attr.h"
+#include "sdkconfig.h"
+
+const esp_app_desc_t *esp_ota_get_app_description(void)
+{
+    return esp_app_get_description();
+}
+
+int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
+{
+   return esp_app_get_elf_sha256(dst, size);
+}

+ 8 - 2
components/app_update/esp_ota_ops.c

@@ -651,8 +651,14 @@ esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, es
 
 #ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
 static esp_err_t esp_ota_set_anti_rollback(void) {
-    const esp_app_desc_t *app_desc = esp_ota_get_app_description();
-    return esp_efuse_update_secure_version(app_desc->secure_version);
+    const esp_partition_t* partition = esp_ota_get_running_partition();
+    esp_app_desc_t app_desc = {0};
+
+    esp_err_t err = esp_ota_get_partition_description(partition, &app_desc);
+    if (err == ESP_OK) {
+        return esp_efuse_update_secure_version(app_desc.secure_version);
+    }
+    return err;
 }
 #endif
 

+ 10 - 3
components/app_update/include/esp_ota_ops.h

@@ -12,7 +12,7 @@
 #include <stddef.h>
 #include "esp_err.h"
 #include "esp_partition.h"
-#include "esp_image_format.h"
+#include "esp_app_desc.h"
 #include "esp_flash_partitions.h"
 #include "soc/soc_caps.h"
 
@@ -44,20 +44,27 @@ typedef uint32_t esp_ota_handle_t;
 /**
  * @brief   Return esp_app_desc structure. This structure includes app version.
  *
+ * @note This API is present for backward compatibility reasons. Alternative function
+ * with the same functionality is `esp_app_get_description`
+ *
  * Return description for running app.
  * @return Pointer to esp_app_desc structure.
  */
-const esp_app_desc_t *esp_ota_get_app_description(void);
+const esp_app_desc_t *esp_ota_get_app_description(void) __attribute__((deprecated("Please use esp_app_get_description instead")));
 
 /**
  * @brief   Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
  * If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
  * the largest possible number of bytes will be written followed by a null.
+ *
+* @note This API is present for backward compatibility reasons. Alternative function
+ * with the same functionality is `esp_app_get_elf_sha256`
+ *
  * @param dst   Destination buffer
  * @param size  Size of the buffer
  * @return      Number of bytes written to dst (including null terminator)
  */
-int esp_ota_get_app_elf_sha256(char* dst, size_t size);
+int esp_ota_get_app_elf_sha256(char* dst, size_t size) __attribute__((deprecated("Please use esp_app_get_elf_sha256 instead")));
 
 /**
  * @brief   Commence an OTA update writing to the specified partition.

+ 3 - 2
components/app_update/test/test_ota_ops.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,7 +13,6 @@
 #include <unity.h>
 #include <test_utils.h>
 #include <esp_ota_ops.h>
-#include "bootloader_common.h"
 
 /* These OTA tests currently don't assume an OTA partition exists
    on the device, so they're a bit limited
@@ -91,6 +90,8 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
 
 TEST_CASE("esp_ota_get_partition_description", "[ota]")
 {
+    extern esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
+
     const esp_partition_t *running = esp_ota_get_running_partition();
     TEST_ASSERT_NOT_NULL(running);
     esp_app_desc_t app_desc1, app_desc2;

+ 11 - 2
components/bootloader_support/CMakeLists.txt

@@ -19,7 +19,7 @@ set(srcs
 if(BOOTLOADER_BUILD)
     set(include_dirs "include" "bootloader_flash/include"
         "private_include")
-    set(priv_requires micro-ecc spi_flash efuse)
+    set(priv_requires micro-ecc spi_flash efuse esp_app_format)
     list(APPEND srcs
     "src/bootloader_init.c"
     "src/bootloader_clock_loader.c"
@@ -37,7 +37,7 @@ else()
     set(include_dirs "include" "bootloader_flash/include")
     set(priv_include_dirs "private_include")
     # heap is required for `heap_memory_layout.h` header
-    set(priv_requires spi_flash mbedtls efuse app_update heap)
+    set(priv_requires spi_flash mbedtls efuse heap esp_app_format)
 endif()
 
 if(BOOTLOADER_BUILD)
@@ -86,6 +86,15 @@ idf_component_register(SRCS "${srcs}"
                     REQUIRES "${requires}"
                     PRIV_REQUIRES "${priv_requires}")
 
+if(NOT BOOTLOADER_BUILD)
+    if(CONFIG_SECURE_SIGNED_ON_UPDATE)
+        if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR
+           CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
+            target_link_libraries(${COMPONENT_LIB} PRIVATE idf::app_update)
+        endif()
+    endif()
+endif()
+
 if(CONFIG_SECURE_SIGNED_APPS AND (CONFIG_SECURE_BOOT_V1_ENABLED OR CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME))
     if(BOOTLOADER_BUILD)
         # Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed

+ 0 - 15
components/bootloader_support/include/bootloader_common.h

@@ -7,7 +7,6 @@
 #pragma once
 #include "esp_flash_partitions.h"
 #include "esp_image_format.h"
-#include "esp_app_format.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -151,20 +150,6 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
  */
 int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);
 
-/**
- * @brief Returns esp_app_desc structure for app partition. This structure includes app version.
- *
- * Returns a description for the requested app partition.
- * @param[in] partition      App partition description.
- * @param[out] app_desc      Structure of info about app.
- * @return
- *  - ESP_OK:                Successful.
- *  - ESP_ERR_INVALID_ARG:   The arguments passed are not valid.
- *  - ESP_ERR_NOT_FOUND:     app_desc structure is not found. Magic word is incorrect.
- *  - ESP_FAIL:              mapping is fail.
- */
-esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
-
 /**
  * @brief Get chip package
  *

+ 0 - 22
components/bootloader_support/include/esp_app_format.h

@@ -106,25 +106,3 @@ typedef struct {
 } esp_image_segment_header_t;
 
 #define ESP_IMAGE_MAX_SEGMENTS 16           /*!< Max count of segments in the image. */
-
-#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432  /*!< The magic word for the esp_app_desc structure that is in DROM. */
-
-/**
- * @brief Description about application.
- */
-typedef struct {
-    uint32_t magic_word;        /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
-    uint32_t secure_version;    /*!< Secure version */
-    uint32_t reserv1[2];        /*!< reserv1 */
-    char version[32];           /*!< Application version */
-    char project_name[32];      /*!< Project name */
-    char time[16];              /*!< Compile time */
-    char date[16];              /*!< Compile date*/
-    char idf_ver[32];           /*!< Version IDF */
-    uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
-    uint32_t reserv2[20];       /*!< reserv2 */
-} esp_app_desc_t;
-
-/** @cond */
-_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
-/** @endcond */

+ 0 - 24
components/bootloader_support/src/bootloader_common_loader.c

@@ -112,30 +112,6 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
     return active_otadata;
 }
 
-esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
-{
-    if (partition == NULL || app_desc == NULL || partition->offset == 0) {
-        return ESP_ERR_INVALID_ARG;
-    }
-
-    const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
-    const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
-    const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
-    if (image == NULL) {
-        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
-        return ESP_FAIL;
-    }
-
-    memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
-    bootloader_munmap(image);
-
-    if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
-        return ESP_ERR_NOT_FOUND;
-    }
-
-    return ESP_OK;
-}
-
 #if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
 
 #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))

+ 26 - 0
components/bootloader_support/src/bootloader_utility.c

@@ -60,6 +60,7 @@
 
 #include "esp_cpu.h"
 #include "esp_image_format.h"
+#include "esp_app_desc.h"
 #include "esp_secure_boot.h"
 #include "esp_flash_encrypt.h"
 #include "esp_flash_partitions.h"
@@ -119,6 +120,31 @@ static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_selec
     return ESP_OK;
 }
 
+esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
+{
+    if (partition == NULL || app_desc == NULL || partition->offset == 0) {
+        return ESP_ERR_INVALID_ARG;
+    }
+
+    const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
+    const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
+    const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
+    if (image == NULL) {
+        ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
+        return ESP_FAIL;
+    }
+
+    memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
+    bootloader_munmap(image);
+
+    if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
+        return ESP_ERR_NOT_FOUND;
+    }
+
+    return ESP_OK;
+}
+
+
 bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
 {
     const esp_partition_info_t *partitions;

+ 26 - 0
components/esp_app_format/CMakeLists.txt

@@ -0,0 +1,26 @@
+idf_component_register(SRCS "esp_app_desc.c"
+                    INCLUDE_DIRS "include")
+
+# esp_app_desc structure is added as an undefined symbol because otherwise the
+# linker will ignore this structure as it has no other files depending on it.
+if(NOT BOOTLOADER_BUILD)
+    target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
+endif()
+
+if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
+    # Ignore current PROJECT_VER (which was set in __project_get_revision()).
+    # Gets the version from the CONFIG_APP_PROJECT_VER.
+    idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
+endif()
+
+# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
+idf_build_get_property(project_ver PROJECT_VER)
+idf_build_get_property(project_name PROJECT_NAME)
+string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
+string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
+message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")
+
+set_source_files_properties(
+    SOURCE "esp_app_desc.c"
+    PROPERTIES COMPILE_DEFINITIONS
+    "PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")

+ 0 - 0
components/app_update/Kconfig.projbuild → components/esp_app_format/Kconfig.projbuild


+ 8 - 7
components/app_update/esp_app_desc.c → components/esp_app_format/esp_app_desc.c

@@ -1,15 +1,16 @@
 /*
- * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 
 #include <assert.h>
 #include <sys/param.h>
-#include "esp_ota_ops.h"
+#include "esp_app_desc.h"
 #include "esp_attr.h"
 #include "sdkconfig.h"
 
+
 // Application version info
 const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
     .magic_word = ESP_APP_DESC_MAGIC_WORD,
@@ -50,7 +51,7 @@ _Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is long
 _Static_assert(sizeof(PROJECT_NAME) <= sizeof(esp_app_desc.project_name), "PROJECT_NAME is longer than project_name field in structure");
 #endif
 
-const esp_app_desc_t *esp_ota_get_app_description(void)
+const esp_app_desc_t *esp_app_get_description(void)
 {
     return &esp_app_desc;
 }
@@ -64,18 +65,18 @@ static inline char IRAM_ATTR to_hex_digit(unsigned val)
     return (val < 10) ? ('0' + val) : ('a' + val - 10);
 }
 
-__attribute__((constructor)) void esp_ota_init_app_elf_sha256(void)
+__attribute__((constructor)) void esp_init_app_elf_sha256(void)
 {
-    esp_ota_get_app_elf_sha256(NULL, 0);
+    esp_app_get_elf_sha256(NULL, 0);
 }
 
 /* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler during cache is disabled.
  * But because the cache is disabled the reading esp_app_desc.app_elf_sha256 is not right and
  * can lead to a complete lock-up of the CPU.
- * For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_ota_init_app_elf_sha256()
+ * For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_init_app_elf_sha256()
  * and keep it in the static s_app_elf_sha256 value.
  */
-int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
+int IRAM_ATTR esp_app_get_elf_sha256(char* dst, size_t size)
 {
     static char s_app_elf_sha256[CONFIG_APP_RETRIEVE_LEN_ELF_SHA / 2];
     static bool first_call = true;

+ 61 - 0
components/esp_app_format/include/esp_app_desc.h

@@ -0,0 +1,61 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define ESP_APP_DESC_MAGIC_WORD (0xABCD5432)  /*!< The magic word for the esp_app_desc structure that is in DROM. */
+
+/**
+ * @brief Description about application.
+ */
+typedef struct {
+    uint32_t magic_word;        /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
+    uint32_t secure_version;    /*!< Secure version */
+    uint32_t reserv1[2];        /*!< reserv1 */
+    char version[32];           /*!< Application version */
+    char project_name[32];      /*!< Project name */
+    char time[16];              /*!< Compile time */
+    char date[16];              /*!< Compile date*/
+    char idf_ver[32];           /*!< Version IDF */
+    uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
+    uint32_t reserv2[20];       /*!< reserv2 */
+} esp_app_desc_t;
+
+/** @cond */
+_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
+/** @endcond */
+
+/**
+ * @brief   Return esp_app_desc structure. This structure includes app version.
+ *
+ * Return description for running app.
+ * @return Pointer to esp_app_desc structure.
+ */
+const esp_app_desc_t *esp_app_get_description(void);
+
+/**
+ * @brief   Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
+ * If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
+ * the largest possible number of bytes will be written followed by a null.
+ * @param dst   Destination buffer
+ * @param size  Size of the buffer
+ * @return      Number of bytes written to dst (including null terminator)
+ */
+int esp_app_get_elf_sha256(char* dst, size_t size);
+
+#ifdef __cplusplus
+}
+#endif

+ 8 - 0
components/esp_app_format/test_apps/CMakeLists.txt

@@ -0,0 +1,8 @@
+# This is the project CMakeLists.txt file for the test subproject
+cmake_minimum_required(VERSION 3.16)
+
+# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
+set(COMPONENTS main)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(esp_app_format_test)

+ 2 - 0
components/esp_app_format/test_apps/README.md

@@ -0,0 +1,2 @@
+| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
+| ----------------- | ----- | -------- | -------- | -------- | -------- |

+ 3 - 0
components/esp_app_format/test_apps/main/CMakeLists.txt

@@ -0,0 +1,3 @@
+idf_component_register(SRCS "test_app_desc.c"
+                       PRIV_INCLUDE_DIRS .
+                       PRIV_REQUIRES esp_app_format unity)

+ 31 - 8
components/app_update/test/test_app_desc.c → components/esp_app_format/test_apps/main/test_app_desc.c

@@ -1,13 +1,26 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
+#include <stdio.h>
 #include <string.h>
-#include "esp_ota_ops.h"
+
+#include "esp_app_desc.h"
 #include "unity.h"
+#include "unity_fixture.h"
+
+TEST_GROUP(esp_app_format);
+
+TEST_SETUP(esp_app_format)
+{
+}
+
+TEST_TEAR_DOWN(esp_app_format)
+{
+}
 
-TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
+TEST(esp_app_format, esp_app_get_elf_sha256_test)
 {
     const int sha256_hex_len = CONFIG_APP_RETRIEVE_LEN_ELF_SHA;
     char dst[sha256_hex_len + 2];
@@ -16,17 +29,17 @@ TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
     size_t len;
 
     char ref_sha256[sha256_hex_len + 1];
-    const esp_app_desc_t* desc = esp_ota_get_app_description();
+    const esp_app_desc_t* desc = esp_app_get_description();
     for (int i = 0; i < sizeof(ref_sha256) / 2; ++i) {
         snprintf(ref_sha256 + 2*i, 3, "%02x", desc->app_elf_sha256[i]);
     }
     ref_sha256[sha256_hex_len] = 0;
 
-    printf("Ref: %s\n", ref_sha256);
+    printf("\nRef: %s\n", ref_sha256);
 
     memset(dst, fill, sizeof(dst));
     len = sizeof(dst);
-    res = esp_ota_get_app_elf_sha256(dst, len);
+    res = esp_app_get_elf_sha256(dst, len);
     printf("%d: %s (%d)\n", len, dst, res);
     TEST_ASSERT_EQUAL(sha256_hex_len + 1, res);
     TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
@@ -35,7 +48,7 @@ TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
 
     memset(dst, fill, sizeof(dst));
     len = 9;
-    res = esp_ota_get_app_elf_sha256(dst, len);
+    res = esp_app_get_elf_sha256(dst, len);
     printf("%d: %s (%d)\n", len, dst, res);
     TEST_ASSERT_EQUAL(9, res);
     TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
@@ -44,7 +57,7 @@ TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
 
     memset(dst, fill, sizeof(dst));
     len = 8;
-    res = esp_ota_get_app_elf_sha256(dst, len);
+    res = esp_app_get_elf_sha256(dst, len);
     printf("%d: %s (%d)\n", len, dst, res);
     // should output even number of characters plus '\0'
     TEST_ASSERT_EQUAL(7, res);
@@ -53,3 +66,13 @@ TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
     TEST_ASSERT_EQUAL_HEX(fill, dst[7]);
     TEST_ASSERT_EQUAL_HEX(fill, dst[8]);
 }
+
+TEST_GROUP_RUNNER(esp_app_format)
+{
+    RUN_TEST_CASE(esp_app_format, esp_app_get_elf_sha256_test)
+}
+
+void app_main(void)
+{
+    UNITY_MAIN(esp_app_format);
+}

+ 11 - 0
components/esp_app_format/test_apps/pytest_esp_app_format.py

@@ -0,0 +1,11 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+# SPDX-License-Identifier: CC0-1.0
+
+import pytest
+from pytest_embedded import Dut
+
+
+@pytest.mark.supported_targets
+@pytest.mark.generic
+def test_esp_app_format(dut: Dut) -> None:
+    dut.expect_unity_test_output()

+ 11 - 0
components/esp_app_format/test_apps/sdkconfig.defaults

@@ -0,0 +1,11 @@
+# General options for additional checks
+CONFIG_HEAP_POISONING_COMPREHENSIVE=y
+CONFIG_COMPILER_WARN_WRITE_STRINGS=y
+CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
+CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
+CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
+CONFIG_COMPILER_STACK_CHECK=y
+
+# Enable Unity fixture support
+CONFIG_UNITY_ENABLE_FIXTURE=y
+CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=n

+ 1 - 1
components/esp_https_ota/CMakeLists.txt

@@ -1,6 +1,6 @@
 idf_component_register(SRCS "src/esp_https_ota.c"
                     INCLUDE_DIRS "include"
-                    REQUIRES esp_http_client bootloader_support
+                    REQUIRES esp_http_client bootloader_support esp_app_format
                     PRIV_REQUIRES log app_update)
 
 target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

+ 1 - 0
components/esp_https_ota/include/esp_https_ota.h

@@ -8,6 +8,7 @@
 
 #include <esp_http_client.h>
 #include <bootloader_common.h>
+#include "esp_app_desc.h"
 #include <sdkconfig.h>
 
 #ifdef __cplusplus

+ 1 - 1
components/esp_system/CMakeLists.txt

@@ -85,7 +85,7 @@ endif()
 # need to introduce panic "event" concept to remove this dependency (IDF-2194)
 idf_component_optional_requires(PRIVATE esp_gdbstub)
 
-idf_component_optional_requires(PRIVATE app_update)
+idf_component_optional_requires(PRIVATE esp_app_format)
 
 if(CONFIG_PM_ENABLE)
     idf_component_optional_requires(PRIVATE pm)

+ 6 - 6
components/esp_system/panic.c

@@ -24,9 +24,9 @@
 
 #include "sdkconfig.h"
 
-#if __has_include("esp_ota_ops.h")
-#include "esp_ota_ops.h"
-#define HAS_ESP_OTA 1
+#if __has_include("esp_app_desc.h")
+#define WITH_ELF_SHA256
+#include "esp_app_desc.h"
 #endif
 
 #if CONFIG_ESP_COREDUMP_ENABLE
@@ -312,13 +312,13 @@ void esp_panic_handler(panic_info_t *info)
     PANIC_INFO_DUMP(info, state);
     panic_print_str("\r\n");
 
-#if HAS_ESP_OTA
+#ifdef WITH_ELF_SHA256
     panic_print_str("\r\nELF file SHA256: ");
     char sha256_buf[65];
-    esp_ota_get_app_elf_sha256(sha256_buf, sizeof(sha256_buf));
+    esp_app_get_elf_sha256(sha256_buf, sizeof(sha256_buf));
     panic_print_str(sha256_buf);
     panic_print_str("\r\n");
-#endif //HAS_ESP_OTA
+#endif
 
     panic_print_str("\r\n");
 

+ 10 - 10
components/esp_system/startup.c

@@ -20,8 +20,6 @@
 #include "hal/uart_types.h"
 #include "hal/uart_ll.h"
 
-#include "esp_system.h"
-#include "esp_log.h"
 #include "esp_heap_caps_init.h"
 #include "spi_flash_mmap.h"
 #include "esp_flash_internal.h"
@@ -33,10 +31,7 @@
 #include "esp_xt_wdt.h"
 #include "esp_cpu.h"
 
-#if __has_include("esp_ota_ops.h")
-#include "esp_ota_ops.h"
-#define HAS_ESP_OTA 1
-#endif
+#include "esp_partition.h"
 
 /***********************************************/
 // Headers for other components init functions
@@ -44,6 +39,11 @@
 #include "esp_coexist_internal.h"
 #endif
 
+#if __has_include("esp_app_desc.h")
+#define WITH_APP_IMAGE_INFO
+#include "esp_app_desc.h"
+#endif
+
 #if CONFIG_ESP_COREDUMP_ENABLE
 #include "esp_core_dump.h"
 #endif
@@ -408,10 +408,10 @@ static void start_cpu0_default(void)
     int cpu_freq = esp_clk_cpu_freq();
     ESP_EARLY_LOGI(TAG, "cpu freq: %d Hz", cpu_freq);
 
-#if HAS_ESP_OTA // [refactor-todo] find a better way to handle this.
+#ifdef WITH_APP_IMAGE_INFO
     // Display information about the current running image.
     if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
-        const esp_app_desc_t *app_desc = esp_ota_get_app_description();
+        const esp_app_desc_t *app_desc = esp_app_get_description();
         ESP_EARLY_LOGI(TAG, "Application information:");
 #ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
         ESP_EARLY_LOGI(TAG, "Project name:     %s", app_desc->project_name);
@@ -426,11 +426,11 @@ static void start_cpu0_default(void)
         ESP_EARLY_LOGI(TAG, "Compile time:     %s %s", app_desc->date, app_desc->time);
 #endif
         char buf[17];
-        esp_ota_get_app_elf_sha256(buf, sizeof(buf));
+        esp_app_get_elf_sha256(buf, sizeof(buf));
         ESP_EARLY_LOGI(TAG, "ELF file SHA256:  %s...", buf);
         ESP_EARLY_LOGI(TAG, "ESP-IDF:          %s", app_desc->idf_ver);
     }
-#endif //HAS_ESP_OTA
+#endif
 
     // Initialize core components and services.
     do_core_init();

+ 5 - 1
components/espcoredump/CMakeLists.txt

@@ -24,4 +24,8 @@ idf_component_register(SRCS ${srcs}
                     INCLUDE_DIRS ${includes}
                     PRIV_INCLUDE_DIRS ${priv_includes}
                     LDFRAGMENTS linker.lf
-                    PRIV_REQUIRES spi_flash app_update mbedtls esp_rom soc driver)
+                    PRIV_REQUIRES spi_flash bootloader_support mbedtls esp_rom soc esp_system driver)
+
+if(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
+  target_link_libraries(${COMPONENT_LIB} PRIVATE idf::esp_app_format)
+endif()

+ 5 - 2
components/espcoredump/src/core_dump_elf.c

@@ -6,7 +6,6 @@
 #include <string.h>
 #include "esp_attr.h"
 #include "esp_partition.h"
-#include "esp_ota_ops.h"
 #include "spi_flash_mmap.h"
 #include "esp_flash_encrypt.h"
 #include "sdkconfig.h"
@@ -16,6 +15,10 @@
 #include "esp_core_dump_port_impl.h"
 #include "esp_core_dump_common.h"
 
+#ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF
+#include "esp_app_desc.h"
+#endif
+
 #define ELF_CLASS ELFCLASS32
 
 #include "elf.h"                    // for ELF file types
@@ -496,7 +499,7 @@ static int elf_write_core_dump_info(core_dump_elf_t *self)
 
     ESP_COREDUMP_LOG_PROCESS("================ Processing coredump info ================");
     int data_len = (int)sizeof(self->elf_version_info.app_elf_sha256);
-    data_len = esp_ota_get_app_elf_sha256((char*)self->elf_version_info.app_elf_sha256, (size_t)data_len);
+    data_len = esp_app_get_elf_sha256((char*)self->elf_version_info.app_elf_sha256, (size_t)data_len);
     ESP_COREDUMP_LOG_PROCESS("Application SHA256='%s', length=%d.",
                                 self->elf_version_info.app_elf_sha256, data_len);
     self->elf_version_info.version = esp_core_dump_elf_version();

+ 2 - 1
components/spi_flash/sim/Makefile.files

@@ -18,6 +18,7 @@ INCLUDE_DIRS := \
     app_update/include \
     bsd/include \
     driver/include \
+    esp_app_format/include \
     esp_timer/include \
     freertos/include \
     log/include \
@@ -34,7 +35,7 @@ INCLUDE_DIRS := \
     xtensa/include \
     xtensa/esp32/include \
     soc/esp32/include \
-        heap/include \
+    heap/include \
     soc/include \
     esp32/include \
     esp_timer/include \

+ 2 - 1
components/spi_flash/sim/stubs/Makefile.files

@@ -14,6 +14,7 @@ INCLUDE_DIRS := \
 	app_update/include \
 	bsd/include \
 	driver/include \
+	esp_app_format/include \
 	esp_timer/include \
 	freertos/include \
 	log/include \
@@ -26,7 +27,7 @@ INCLUDE_DIRS := \
 	esp_hw_support/include/soc \
 	esp_system/include \
 	soc/esp32/include \
-        heap/include \
+	heap/include \
 	soc/include \
 	xtensa/include \
 	xtensa/esp32/include \

+ 46 - 0
components/spi_flash/sim/stubs/esp_app_format/include/esp_app_desc.h

@@ -0,0 +1,46 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * This is a STUB FILE used when compiling ESP-IDF to run tests on the host system.
+ * The source file used normally for ESP-IDF has the same name but is located elsewhere.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define ESP_APP_DESC_MAGIC_WORD (0xABCD5432)  /*!< The magic word for the esp_app_desc structure that is in DROM. */
+
+/**
+ * @brief Description about application.
+ */
+typedef struct {
+    uint32_t magic_word;        /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
+    uint32_t secure_version;    /*!< Secure version */
+    uint32_t reserv1[2];        /*!< reserv1 */
+    char version[32];           /*!< Application version */
+    char project_name[32];      /*!< Project name */
+    char time[16];              /*!< Compile time */
+    char date[16];              /*!< Compile date*/
+    char idf_ver[32];           /*!< Version IDF */
+    uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
+    uint32_t reserv2[20];       /*!< reserv2 */
+} esp_app_desc_t;
+
+/** @cond */
+_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif

+ 1 - 0
docs/doxygen/Doxyfile

@@ -86,6 +86,7 @@ INPUT = \
     $(PROJECT_PATH)/components/esp_adc/include/esp_adc/adc_cali.h \
     $(PROJECT_PATH)/components/esp_adc/include/esp_adc/adc_continuous.h \
     $(PROJECT_PATH)/components/esp_adc/include/esp_adc/adc_oneshot.h \
+    $(PROJECT_PATH)/components/esp_app_format/include/esp_app_desc.h \
     $(PROJECT_PATH)/components/esp_common/include/esp_check.h \
     $(PROJECT_PATH)/components/esp_common/include/esp_err.h \
     $(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \

+ 2 - 1
docs/en/api-reference/system/misc_system_api.rst

@@ -211,7 +211,7 @@ The application version is stored in :cpp:class:`esp_app_desc_t` structure. It i
 
 To set the version in your project manually, you need to set the ``PROJECT_VER`` variable in the ``CMakeLists.txt`` of your project. In application ``CMakeLists.txt``, put ``set(PROJECT_VER "0.1.0.1")`` before including ``project.cmake``.
 
-If the :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise, if the ``PROJECT_VER`` variable is not set in the project, it will be retrieved either from the ``$(PROJECT_PATH)/version.txt`` file (if present) or using git command ``git describe``. If neither is available, ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions.
+If the :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise, if the ``PROJECT_VER`` variable is not set in the project, it will be retrieved either from the ``$(PROJECT_PATH)/version.txt`` file (if present) or using git command ``git describe``. If neither is available, ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_app_get_description` or :cpp:func:`esp_ota_get_partition_description` functions.
 
 API Reference
 -------------
@@ -221,3 +221,4 @@ API Reference
 .. include-build-file:: inc/esp_mac.inc
 .. include-build-file:: inc/esp_chip_info.inc
 .. include-build-file:: inc/esp_cpu.inc
+.. include-build-file:: inc/esp_app_desc.inc

+ 12 - 0
docs/en/migration-guides/release-5.x/system.rst

@@ -149,3 +149,15 @@ The file ``portmacro_deprecated.h`` which was added to maintain backward compati
 - ``vPortCPUAcquireMutex()`` is removed. Users should use the ``spinlock_acquire()`` function instead.
 - ``vPortCPUAcquireMutexTimeout()`` is removed. Users should use the ``spinlock_acquire()`` function instead.
 - ``vPortCPUReleaseMutex()`` is removed. Users should use the ``spinlock_release()`` function instead.
+
+App Update
+----------
+
+- The functions :cpp:func:`esp_ota_get_app_description` and :cpp:func:`esp_ota_get_app_elf_sha256` have been termed as deprecated. Please use the alternative functions :cpp:func:`esp_app_get_description` and :cpp:func:`esp_app_get_elf_sha256` respectively. These functions have now been moved to a new component :component:`esp_app_format`. (Refer header file :component_file:`esp_app_desc.h <esp_app_format/include/esp_app_desc.h>`)
+
+Bootloader Support
+------------------
+
+- The :cpp:type:`esp_app_desc_t` structure, which used to be declared in :component_file:`esp_app_format.h <bootloader_support/include/esp_app_format.h>`, is now declared in :component_file:`esp_app_desc.h <esp_app_format/include/esp_app_desc.h>`.
+
+- The function :cpp:func:`bootloader_common_get_partition_description` has now been made private. Please use the alternative function :cpp:func:`esp_ota_get_partition_description`. Note that this function takes :cpp:type:`esp_partition_t` as its first argument instead of :cpp:type:`esp_partition_pos_t`.

+ 2 - 1
docs/zh_CN/api-reference/system/misc_system_api.rst

@@ -211,7 +211,7 @@ SDK 版本
 
 若需手动设置版本,需要在项目的 ``CMakeLists.txt`` 文件中设置 ``PROJECT_VER`` 变量,即在 ``CMakeLists.txt`` 文件中,在包含 ``project.cmake`` 之前添加 ``set(PROJECT_VER "0.1.0.1")``。
 
-如果设置了 :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` 选项,则将使用 :ref:`CONFIG_APP_PROJECT_VER` 的值。否则,如果在项目中未设置 ``PROJECT_VER`` 变量,则该变量将从 ``$(PROJECT_PATH)/version.txt`` 文件(若有)中检索,或使用 git 命令 ``git describe`` 检索。如果两者都不可用,则 ``PROJECT_VER`` 将被设置为 “1”。应用程序可通过调用 :cpp:func:`esp_ota_get_app_description` 或 :cpp:func:`esp_ota_get_partition_description` 函数来获取应用程序的版本信息。
+如果设置了 :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` 选项,则将使用 :ref:`CONFIG_APP_PROJECT_VER` 的值。否则,如果在项目中未设置 ``PROJECT_VER`` 变量,则该变量将从 ``$(PROJECT_PATH)/version.txt`` 文件(若有)中检索,或使用 git 命令 ``git describe`` 检索。如果两者都不可用,则 ``PROJECT_VER`` 将被设置为 “1”。应用程序可通过调用 :cpp:func:`esp_app_get_description` 或 :cpp:func:`esp_ota_get_partition_description` 函数来获取应用程序的版本信息。
 
 API 参考
 -------------
@@ -221,3 +221,4 @@ API 参考
 .. include-build-file:: inc/esp_mac.inc
 .. include-build-file:: inc/esp_chip_info.inc
 .. include-build-file:: inc/esp_cpu.inc
+.. include-build-file:: inc/esp_app_desc.inc

+ 1 - 0
examples/system/ota/native_ota_example/main/native_ota_example.c

@@ -13,6 +13,7 @@
 #include "esp_event.h"
 #include "esp_log.h"
 #include "esp_ota_ops.h"
+#include "esp_app_format.h"
 #include "esp_http_client.h"
 #include "esp_flash_partitions.h"
 #include "esp_partition.h"

+ 4 - 2
tools/test_apps/system/g1_components/CMakeLists.txt

@@ -21,8 +21,8 @@ set(extra_allowed_components
 # These components are currently included into "G1" build, but shouldn't.
 # After removing the extra dependencies, remove the components from this list as well.
 set(extra_components_which_shouldnt_be_included
-    # app_update gets added because of bootloader_support, spi_flash, espcoredump.
-    #   bootloader_support, spi_flash, espcoredump should be removed from dependencies;
+    # app_update gets added because of spi_flash.
+    # spi_flash should be removed from dependencies;
     app_update
     # of G1 components, bootloader is only included from spi_flash
     #   [refactor-todo]: see if this dependency from spi_flash can be made weak
@@ -36,6 +36,8 @@ set(extra_components_which_shouldnt_be_included
     # [refactor-todo]: driver is a dependency of esp_pm, esp_timer, spi_flash, vfs, esp_wifi, ${IDF_TARGET}
     #   all of these should be removed from G1 except for spi_flash.
     driver
+    # esp_app_format is dependency of bootloader_support, app_update
+    esp_app_format
     # [refactor-todo]: efuse is a dependency of esp_hw_support, esp_system.
     #   Figure out if these components can exist without a dependency on efuse.
     #   If not, see if esp_hw_support can provide minimal efuse component replacement in G1 build.