From 972c531b6d27ad17bbaa8844d5ea68b85f498dfd Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Tue, 2 Aug 2022 14:24:29 +0530 Subject: [PATCH] app_update: Moved app metadata to new component `esp_app_format` --- components/app_update/CMakeLists.txt | 27 +------- components/app_update/esp_ota_app_desc.c | 21 +++++++ components/app_update/esp_ota_ops.c | 10 ++- components/app_update/include/esp_ota_ops.h | 13 +++- components/app_update/test/test_ota_ops.c | 5 +- components/esp_app_format/CMakeLists.txt | 26 ++++++++ .../Kconfig.projbuild | 0 .../esp_app_desc.c | 15 ++--- .../esp_app_format/include/esp_app_desc.h | 61 +++++++++++++++++++ components/esp_app_format/test/CMakeLists.txt | 4 ++ .../test/test_app_desc.c | 14 ++--- 11 files changed, 150 insertions(+), 46 deletions(-) create mode 100644 components/app_update/esp_ota_app_desc.c create mode 100644 components/esp_app_format/CMakeLists.txt rename components/{app_update => esp_app_format}/Kconfig.projbuild (100%) rename components/{app_update => esp_app_format}/esp_app_desc.c (88%) create mode 100644 components/esp_app_format/include/esp_app_desc.h create mode 100644 components/esp_app_format/test/CMakeLists.txt rename components/{app_update => esp_app_format}/test/test_app_desc.c (79%) diff --git a/components/app_update/CMakeLists.txt b/components/app_update/CMakeLists.txt index 789799ed7c..2fb1be8cdb 100644 --- a/components/app_update/CMakeLists.txt +++ b/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") diff --git a/components/app_update/esp_ota_app_desc.c b/components/app_update/esp_ota_app_desc.c new file mode 100644 index 0000000000..70774d50e0 --- /dev/null +++ b/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 +#include +#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); +} diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index a1bfe77cc8..eda7f97260 100644 --- a/components/app_update/esp_ota_ops.c +++ b/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 diff --git a/components/app_update/include/esp_ota_ops.h b/components/app_update/include/esp_ota_ops.h index 355c61f2f5..1058c728ae 100644 --- a/components/app_update/include/esp_ota_ops.h +++ b/components/app_update/include/esp_ota_ops.h @@ -12,7 +12,7 @@ #include #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. diff --git a/components/app_update/test/test_ota_ops.c b/components/app_update/test/test_ota_ops.c index 9b283b64ed..b72142d6e1 100644 --- a/components/app_update/test/test_ota_ops.c +++ b/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 #include #include -#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; diff --git a/components/esp_app_format/CMakeLists.txt b/components/esp_app_format/CMakeLists.txt new file mode 100644 index 0000000000..5a0d7460bb --- /dev/null +++ b/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}\"") diff --git a/components/app_update/Kconfig.projbuild b/components/esp_app_format/Kconfig.projbuild similarity index 100% rename from components/app_update/Kconfig.projbuild rename to components/esp_app_format/Kconfig.projbuild diff --git a/components/app_update/esp_app_desc.c b/components/esp_app_format/esp_app_desc.c similarity index 88% rename from components/app_update/esp_app_desc.c rename to components/esp_app_format/esp_app_desc.c index ae3325b1c3..909bb94a4c 100644 --- a/components/app_update/esp_app_desc.c +++ b/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 #include -#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; diff --git a/components/esp_app_format/include/esp_app_desc.h b/components/esp_app_format/include/esp_app_desc.h new file mode 100644 index 0000000000..8f8241ba42 --- /dev/null +++ b/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 +#include +#include +#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 diff --git a/components/esp_app_format/test/CMakeLists.txt b/components/esp_app_format/test/CMakeLists.txt new file mode 100644 index 0000000000..5f8813fa5c --- /dev/null +++ b/components/esp_app_format/test/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRC_DIRS "." + PRIV_INCLUDE_DIRS "." + PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver + ) diff --git a/components/app_update/test/test_app_desc.c b/components/esp_app_format/test/test_app_desc.c similarity index 79% rename from components/app_update/test/test_app_desc.c rename to components/esp_app_format/test/test_app_desc.c index c37fbe614b..af87a9b97f 100644 --- a/components/app_update/test/test_app_desc.c +++ b/components/esp_app_format/test/test_app_desc.c @@ -1,13 +1,13 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include -#include "esp_ota_ops.h" +#include "esp_app_desc.h" #include "unity.h" -TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]") +TEST_CASE("esp_get_app_elf_sha256 test", "[esp_app_desc]") { const int sha256_hex_len = CONFIG_APP_RETRIEVE_LEN_ELF_SHA; char dst[sha256_hex_len + 2]; @@ -16,7 +16,7 @@ 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_get_app_description(); for (int i = 0; i < sizeof(ref_sha256) / 2; ++i) { snprintf(ref_sha256 + 2*i, 3, "%02x", desc->app_elf_sha256[i]); } @@ -26,7 +26,7 @@ TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]") memset(dst, fill, sizeof(dst)); len = sizeof(dst); - res = esp_ota_get_app_elf_sha256(dst, len); + res = esp_get_app_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 +35,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_get_app_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 +44,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_get_app_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);