idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
ota.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
21#include <idfxx/error>
22#include <idfxx/partition>
23
24#include <cstddef>
25#include <cstdint>
26#include <esp_app_desc.h>
27#include <span>
28#include <string_view>
29
30typedef uint32_t esp_ota_handle_t;
31
32namespace idfxx::ota {
33
41
48
52enum class errc : esp_err_t {
53 // clang-format off
54 partition_conflict = 0x1501,
55 select_info_invalid = 0x1502,
56 validate_failed = 0x1503,
57 small_sec_ver = 0x1504,
58 rollback_failed = 0x1505,
59 rollback_invalid_state = 0x1506,
60 // clang-format on
61};
62
66class error_category : public std::error_category {
67public:
69 [[nodiscard]] const char* name() const noexcept override final;
70
72 [[nodiscard]] std::string message(int ec) const override final;
73};
74
80enum class image_state : uint32_t {
81 // clang-format off
82 new_image = 0x0U,
83 pending_verify = 0x1U,
84 valid = 0x2U,
85 invalid = 0x3U,
86 aborted = 0x4U,
87 undefined = 0xFFFFFFFFU,
88 // clang-format on
89};
90
99public:
101 [[nodiscard]] std::string_view version() const;
102
104 [[nodiscard]] std::string_view project_name() const;
105
107 [[nodiscard]] std::string_view time() const;
108
110 [[nodiscard]] std::string_view date() const;
111
113 [[nodiscard]] std::string_view idf_ver() const;
114
116 [[nodiscard]] uint32_t secure_version() const;
117
119 [[nodiscard]] std::span<const uint8_t, 32> app_elf_sha256() const;
120
122 [[nodiscard]] const esp_app_desc_t& idf_handle() const { return _desc; }
123
124private:
126
127 explicit app_description(const esp_app_desc_t& desc);
128
129 esp_app_desc_t _desc;
130};
131
150class update {
151public:
152#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
161 [[nodiscard]] explicit update(const partition& part);
162
172 [[nodiscard]] explicit update(const partition& part, size_t image_size);
173
184 [[nodiscard]] explicit update(const partition& part, sequential_erase_tag);
185
200 [[nodiscard]] static update resume(const partition& part, size_t offset);
201
217 [[nodiscard]] static update resume(const partition& part, size_t offset, size_t erase_size);
218
233 [[nodiscard]] static update resume(const partition& part, size_t offset, sequential_erase_tag);
234#endif
235
245 [[nodiscard]] static result<update> make(const partition& part);
246
258 [[nodiscard]] static result<update> make(const partition& part, size_t image_size);
259
271 [[nodiscard]] static result<update> make(const partition& part, sequential_erase_tag);
272
285 [[nodiscard]] static result<update> try_resume(const partition& part, size_t offset);
286
301 [[nodiscard]] static result<update> try_resume(const partition& part, size_t offset, size_t erase_size);
302
315 [[nodiscard]] static result<update> try_resume(const partition& part, size_t offset, sequential_erase_tag);
316
318
319 update(const update&) = delete;
320 update& operator=(const update&) = delete;
321
323 update(update&& other) noexcept;
324
326 update& operator=(update&& other) noexcept;
327
328 // =========================================================================
329 // Final partition
330 // =========================================================================
331
332#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
345 void set_final_partition(const partition& final_part, bool copy = true);
346#endif
347
359 [[nodiscard]] result<void> try_set_final_partition(const partition& final_part, bool copy = true);
360
361 // =========================================================================
362 // Write
363 // =========================================================================
364
365#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
375 void write(const void* data, size_t size);
376
385 void write(std::span<const uint8_t> data);
386
400 void write_with_offset(uint32_t offset, const void* data, size_t size);
401
414 void write_with_offset(uint32_t offset, std::span<const uint8_t> data);
415#endif
416
426 [[nodiscard]] result<void> try_write(const void* data, size_t size);
427
436 [[nodiscard]] result<void> try_write(std::span<const uint8_t> data);
437
450 [[nodiscard]] result<void> try_write_with_offset(uint32_t offset, const void* data, size_t size);
451
463 [[nodiscard]] result<void> try_write_with_offset(uint32_t offset, std::span<const uint8_t> data);
464
465 // =========================================================================
466 // End / Abort
467 // =========================================================================
468
469#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
478 void end();
479
486 void abort();
487#endif
488
497 [[nodiscard]] result<void> try_end();
498
505
506private:
507 explicit update(esp_ota_handle_t handle);
508
509 esp_ota_handle_t _handle = 0;
510};
511
512// =============================================================================
513// Free functions - Boot partition management
514// =============================================================================
515
516#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
526
535[[nodiscard]] partition boot_partition();
536
546
560[[nodiscard]] partition next_update_partition(const partition* start_from = nullptr);
561#endif
562
572
580
588
600[[nodiscard]] result<partition> try_next_update_partition(const partition* start_from = nullptr);
601
602// =============================================================================
603// Free functions - App description
604// =============================================================================
605
606#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
618#endif
619
629
630// =============================================================================
631// Free functions - State management
632// =============================================================================
633
634#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
642
651[[noreturn]] void mark_invalid_and_rollback();
652
663[[nodiscard]] image_state partition_state(const partition& part);
664#endif
665
672
682
691
692// =============================================================================
693// Free functions - Rollback checking
694// =============================================================================
695
701[[nodiscard]] bool rollback_possible();
702
703#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
715#endif
716
726
727// =============================================================================
728// Free functions - Partition maintenance
729// =============================================================================
730
731#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
741
751#endif
752
761
770
771// =============================================================================
772// Free functions - Partition count
773// =============================================================================
774
780[[nodiscard]] size_t app_partition_count();
781
787[[nodiscard]] const error_category& ota_category() noexcept;
788
793[[nodiscard]] inline std::error_code make_error_code(errc e) noexcept {
794 return {std::to_underlying(e), ota_category()};
795}
796
807[[nodiscard]] std::unexpected<std::error_code> ota_error(esp_err_t e);
808
809} // namespace idfxx::ota
810
812namespace std {
813template<>
814struct is_error_code_enum<idfxx::ota::errc> : true_type {};
815} // namespace std
// end of idfxx_ota
Application description from a firmware image.
Definition ota.hpp:98
std::string_view version() const
Returns the application version string.
uint32_t secure_version() const
Returns the secure version counter.
std::string_view date() const
Returns the compile date string.
std::span< const uint8_t, 32 > app_elf_sha256() const
Returns the SHA-256 hash of the application ELF file.
std::string_view time() const
Returns the compile time string.
const esp_app_desc_t & idf_handle() const
Returns a reference to the underlying ESP-IDF app description structure.
Definition ota.hpp:122
std::string_view project_name() const
Returns the project name.
std::string_view idf_ver() const
Returns the ESP-IDF version string used to build the image.
friend result< app_description > try_partition_description(const partition &)
Returns the application description from a partition.
Error category for OTA errors.
Definition ota.hpp:66
const char * name() const noexcept override final
Returns the name of the error category.
std::string message(int ec) const override final
Returns a human-readable message for the given error code.
RAII OTA update session.
Definition ota.hpp:150
void end()
Finalizes the OTA update and validates the written image.
static result< update > make(const partition &part, sequential_erase_tag)
Begins an OTA update with sequential (incremental) flash erase.
update(const partition &part)
Begins an OTA update, erasing the entire partition.
static update resume(const partition &part, size_t offset)
Resumes an interrupted OTA update, erasing all remaining flash.
void write_with_offset(uint32_t offset, const void *data, size_t size)
Writes data at a specific offset in the OTA partition.
result< void > try_abort()
Aborts the OTA update and frees associated resources.
void abort()
Aborts the OTA update and frees associated resources.
static result< update > try_resume(const partition &part, size_t offset, sequential_erase_tag)
Resumes an interrupted OTA update with sequential (incremental) flash erase.
result< void > try_write_with_offset(uint32_t offset, std::span< const uint8_t > data)
Writes data at a specific offset in the OTA partition.
void set_final_partition(const partition &final_part, bool copy=true)
Redirects the validated image to a different final partition.
void write(std::span< const uint8_t > data)
Writes data sequentially to the OTA partition.
update(const partition &part, size_t image_size)
Begins an OTA update, erasing space for the specified image size.
static update resume(const partition &part, size_t offset, sequential_erase_tag)
Resumes an interrupted OTA update with sequential (incremental) flash erase.
static result< update > try_resume(const partition &part, size_t offset)
Resumes an interrupted OTA update, erasing all remaining flash.
void write(const void *data, size_t size)
Writes data sequentially to the OTA partition.
update(const update &)=delete
void write_with_offset(uint32_t offset, std::span< const uint8_t > data)
Writes data at a specific offset in the OTA partition.
result< void > try_set_final_partition(const partition &final_part, bool copy=true)
Redirects the validated image to a different final partition.
update(update &&other) noexcept
Move constructor.
update & operator=(const update &)=delete
result< void > try_write_with_offset(uint32_t offset, const void *data, size_t size)
Writes data at a specific offset in the OTA partition.
result< void > try_write(const void *data, size_t size)
Writes data sequentially to the OTA partition.
static update resume(const partition &part, size_t offset, size_t erase_size)
Resumes an interrupted OTA update, erasing the specified amount of flash.
result< void > try_write(std::span< const uint8_t > data)
Writes data sequentially to the OTA partition.
update & operator=(update &&other) noexcept
Move assignment.
result< void > try_end()
Finalizes the OTA update and validates the written image.
update(const partition &part, sequential_erase_tag)
Begins an OTA update with sequential (incremental) flash erase.
static result< update > make(const partition &part, size_t image_size)
Begins an OTA update, erasing space for the specified image size.
static result< update > make(const partition &part)
Begins an OTA update, erasing the entire partition.
static result< update > try_resume(const partition &part, size_t offset, size_t erase_size)
Resumes an interrupted OTA update, erasing the specified amount of flash.
A flash partition.
Definition partition.hpp:51
int esp_err_t
Definition error.hpp:35
uint32_t esp_ota_handle_t
Definition ota.hpp:30
void invalidate_inactive_ota_data_slot()
Invalidates the OTA data slot for the last boot application partition.
void mark_valid()
Marks the running app as valid, cancelling any pending rollback.
partition boot_partition()
Returns the currently configured boot partition.
partition running_partition()
Returns the partition of the currently running application.
constexpr sequential_erase_tag sequential_erase
Tag value for sequential (incremental) flash erase mode.
Definition ota.hpp:47
result< partition > try_running_partition()
Returns the partition of the currently running application.
result< image_state > try_partition_state(const partition &part)
Returns the OTA image state for a partition.
result< void > try_mark_invalid_and_rollback()
Marks the running app as invalid and triggers a rollback with reboot.
app_description partition_description(const partition &part)
Returns the application description from a partition.
result< partition > try_last_invalid_partition()
Returns the last partition with invalid state.
image_state
OTA image state.
Definition ota.hpp:80
result< partition > try_next_update_partition(const partition *start_from=nullptr)
Returns the next OTA app partition to write an update to.
std::unexpected< std::error_code > ota_error(esp_err_t e)
Creates an unexpected error from an ESP-IDF error code, mapping to OTA error codes where possible.
size_t app_partition_count()
Returns the number of OTA app partitions in the partition table.
result< void > try_erase_last_boot_app_partition()
Erases the previous boot application partition and its OTA data.
void set_boot_partition(const partition &part)
Sets the boot partition for the next reboot.
void mark_invalid_and_rollback()
Marks the running app as invalid and triggers a rollback with reboot.
partition last_invalid_partition()
Returns the last partition with invalid state.
std::error_code make_error_code(errc e) noexcept
Creates an error code from an idfxx::ota::errc value.
Definition ota.hpp:793
errc
Error codes for OTA operations.
Definition ota.hpp:52
result< void > try_set_boot_partition(const partition &part)
Sets the boot partition for the next reboot.
bool rollback_possible()
Checks whether a rollback to a previous firmware is possible.
result< void > try_invalidate_inactive_ota_data_slot()
Invalidates the OTA data slot for the last boot application partition.
void erase_last_boot_app_partition()
Erases the previous boot application partition and its OTA data.
result< void > try_mark_valid()
Marks the running app as valid, cancelling any pending rollback.
result< partition > try_boot_partition()
Returns the currently configured boot partition.
result< app_description > try_partition_description(const partition &part)
Returns the application description from a partition.
const error_category & ota_category() noexcept
Returns a reference to the OTA error category singleton.
image_state partition_state(const partition &part)
Returns the OTA image state for a partition.
partition next_update_partition(const partition *start_from=nullptr)
Returns the next OTA app partition to write an update to.
Definition adc.hpp:48
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120
Tag type for sequential (incremental) flash erase mode.
Definition ota.hpp:40