idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
partition.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
23#include <array>
24#include <cassert>
25#include <cstddef>
26#include <cstdint>
27#include <esp_partition.h>
28#include <span>
29#include <string_view>
30#include <type_traits>
31#include <vector>
32
33namespace idfxx {
34
51class partition {
52public:
54 enum class type : int {
55 app = 0x00,
56 data = 0x01,
57 bootloader = 0x02,
58 partition_table = 0x03,
59 any = 0xff,
60 };
61
63 enum class subtype : int {
64 // clang-format off
65 // Bootloader subtypes
66 bootloader_primary = 0x00,
67 bootloader_ota = 0x01,
68 bootloader_recovery = 0x02,
69
70 // Partition table subtypes
72 partition_table_ota = 0x01,
73
74 // App subtypes
75 app_factory = 0x00,
76 app_ota_0 = 0x10,
77 app_ota_1 = 0x11,
78 app_ota_2 = 0x12,
79 app_ota_3 = 0x13,
80 app_ota_4 = 0x14,
81 app_ota_5 = 0x15,
82 app_ota_6 = 0x16,
83 app_ota_7 = 0x17,
84 app_ota_8 = 0x18,
85 app_ota_9 = 0x19,
86 app_ota_10 = 0x1a,
87 app_ota_11 = 0x1b,
88 app_ota_12 = 0x1c,
89 app_ota_13 = 0x1d,
90 app_ota_14 = 0x1e,
91 app_ota_15 = 0x1f,
92 app_test = 0x20,
93
94 // Data subtypes
95 data_ota = 0x00,
96 data_phy = 0x01,
97 data_nvs = 0x02,
98 data_coredump = 0x03,
99 data_nvs_keys = 0x04,
100 data_efuse_em = 0x05,
101 data_undefined = 0x06,
102 data_esphttpd = 0x80,
103 data_fat = 0x81,
104 data_spiffs = 0x82,
105 data_littlefs = 0x83,
106
107 any = 0xff,
108 // clang-format on
109 };
110
112 enum class mmap_memory : int {
113 data = 0,
114 inst,
115 };
116
117 class mmap_handle;
118
119 // =========================================================================
120 // Discovery
121 // =========================================================================
122
123#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
136 [[nodiscard]] static partition
137 find(enum type type, enum subtype subtype = subtype::any, std::string_view label = {});
138
151 [[nodiscard]] static partition find(std::string_view label);
152#endif
153
165 try_find(enum type type, enum subtype subtype = subtype::any, std::string_view label = {});
166
177 [[nodiscard]] static result<partition> try_find(std::string_view label);
178
188 [[nodiscard]] static std::vector<partition>
189 find_all(enum type type = type::any, enum subtype subtype = subtype::any, std::string_view label = {});
190
198 [[nodiscard]] static constexpr partition from_handle(const esp_partition_t* handle) { return partition{handle}; }
199
200 // Copyable and movable
201 partition(const partition&) = default;
202 partition(partition&&) = default;
203 partition& operator=(const partition&) = default;
205
206 // =========================================================================
207 // Accessors
208 // =========================================================================
209
211 [[nodiscard]] constexpr bool operator==(const partition&) const noexcept = default;
212
214 [[nodiscard]] enum type type() const { return static_cast<enum partition::type>(_part->type); }
215
217 [[nodiscard]] enum subtype subtype() const { return static_cast<enum partition::subtype>(_part->subtype); }
218
220 [[nodiscard]] uint32_t address() const { return _part->address; }
221
223 [[nodiscard]] uint32_t size() const { return _part->size; }
224
226 [[nodiscard]] uint32_t erase_size() const { return _part->erase_size; }
227
229 [[nodiscard]] std::string_view label() const { return _part->label; }
230
232 [[nodiscard]] bool encrypted() const { return _part->encrypted; }
233
235 [[nodiscard]] bool readonly() const { return _part->readonly; }
236
238 [[nodiscard]] constexpr const esp_partition_t* idf_handle() const { return _part; }
239
240 // =========================================================================
241 // Read / Write / Erase
242 // =========================================================================
243
244#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
255 void read(size_t offset, void* dst, size_t size) const { unwrap(try_read(offset, dst, size)); }
256
266 void read(size_t offset, std::span<uint8_t> dst) const { unwrap(try_read(offset, dst)); }
267
278 void write(size_t offset, const void* src, size_t size) { unwrap(try_write(offset, src, size)); }
279
289 void write(size_t offset, std::span<const uint8_t> src) { unwrap(try_write(offset, src)); }
290
301 void read_raw(size_t offset, void* dst, size_t size) const { unwrap(try_read_raw(offset, dst, size)); }
302
312 void read_raw(size_t offset, std::span<uint8_t> dst) const { unwrap(try_read_raw(offset, dst)); }
313
324 void write_raw(size_t offset, const void* src, size_t size) { unwrap(try_write_raw(offset, src, size)); }
325
335 void write_raw(size_t offset, std::span<const uint8_t> src) { unwrap(try_write_raw(offset, src)); }
336
349
358 [[nodiscard]] std::array<uint8_t, 32> sha256() const { return unwrap(try_sha256()); }
359
373 [[nodiscard]] mmap_handle mmap(size_t offset, size_t size, enum mmap_memory memory = mmap_memory::data) const;
374#endif
375
385 [[nodiscard]] result<void> try_read(size_t offset, void* dst, size_t size) const;
386
395 [[nodiscard]] result<void> try_read(size_t offset, std::span<uint8_t> dst) const;
396
406 [[nodiscard]] result<void> try_write(size_t offset, const void* src, size_t size);
407
416 [[nodiscard]] result<void> try_write(size_t offset, std::span<const uint8_t> src);
417
427 [[nodiscard]] result<void> try_read_raw(size_t offset, void* dst, size_t size) const;
428
437 [[nodiscard]] result<void> try_read_raw(size_t offset, std::span<uint8_t> dst) const;
438
448 [[nodiscard]] result<void> try_write_raw(size_t offset, const void* src, size_t size);
449
458 [[nodiscard]] result<void> try_write_raw(size_t offset, std::span<const uint8_t> src);
459
471
478
491
499 [[nodiscard]] bool check_identity(const partition& other) const;
500
501private:
502 explicit constexpr partition(const esp_partition_t* part)
503 : _part(part) {}
504
505 const esp_partition_t* _part;
506};
507
516[[nodiscard]] constexpr enum partition::subtype app_ota(unsigned i) {
517 assert(i <= 15);
518 return static_cast<enum partition::subtype>(0x10 + i);
519}
520
535public:
537 mmap_handle() = default;
538
540
541 mmap_handle(const mmap_handle&) = delete;
543
545 mmap_handle(mmap_handle&& other) noexcept;
546
549
551 [[nodiscard]] explicit operator bool() const { return _ptr != nullptr; }
552
554 [[nodiscard]] const void* data() const { return _ptr; }
555
557 [[nodiscard]] size_t size() const { return _size; }
558
566 template<typename T>
567 [[nodiscard]] std::span<T> as_span() const {
568 static_assert(std::is_const_v<T>, "T must be const-qualified; mapped partition memory is read-only");
569 return {static_cast<T*>(_ptr), _size / sizeof(T)};
570 }
571
580
581private:
583
584 mmap_handle(const void* ptr, size_t size, esp_partition_mmap_handle_t handle);
585
586 const void* _ptr = nullptr;
587 size_t _size = 0;
588 esp_partition_mmap_handle_t _handle = 0;
589};
590
591#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
593 return unwrap(try_mmap(offset, size, memory));
594}
595#endif
596
597} // namespace idfxx
598
// end of idfxx_partition
A memory-mapped partition region.
esp_partition_mmap_handle_t release() noexcept
Releases ownership without unmapping.
std::span< T > as_span() const
Returns a typed span over the mapped memory region.
mmap_handle(mmap_handle &&other) noexcept
Move constructor.
mmap_handle(const mmap_handle &)=delete
mmap_handle & operator=(const mmap_handle &)=delete
const void * data() const
Returns a pointer to the mapped memory region.
mmap_handle & operator=(mmap_handle &&other) noexcept
Move assignment.
size_t size() const
Returns the size of the mapped region in bytes.
mmap_handle()=default
Constructs an invalid (unmapped) handle.
A flash partition.
Definition partition.hpp:51
enum subtype subtype() const
Returns the partition subtype.
static constexpr partition from_handle(const esp_partition_t *handle)
Constructs a partition from an ESP-IDF partition handle.
void read(size_t offset, void *dst, size_t size) const
Reads data from the partition with decryption if applicable.
partition(partition &&)=default
std::string_view label() const
Returns the partition label.
result< void > try_write_raw(size_t offset, const void *src, size_t size)
Writes data to the partition without encryption.
void write_raw(size_t offset, std::span< const uint8_t > src)
Writes data to the partition without encryption.
void write(size_t offset, const void *src, size_t size)
Writes data to the partition with encryption if applicable.
result< void > try_read_raw(size_t offset, void *dst, size_t size) const
Reads data from the partition without decryption.
partition(const partition &)=default
uint32_t erase_size() const
Returns the erase block size.
mmap_memory
Memory type for memory-mapped partition access.
@ inst
Map to instruction memory, allows only 4-byte-aligned access.
@ data
Map to data memory, allows byte-aligned access.
static partition find(std::string_view label)
Finds the first partition with the given label.
static partition find(enum type type, enum subtype subtype=subtype::any, std::string_view label={})
Finds the first partition matching the given criteria.
result< void > try_erase_range(size_t offset, size_t size)
Erases a range of the partition.
result< void > try_read_raw(size_t offset, std::span< uint8_t > dst) const
Reads data from the partition without decryption.
bool check_identity(const partition &other) const
Checks if two partitions have identical contents by comparing SHA-256 hashes.
void erase_range(size_t offset, size_t size)
Erases a range of the partition.
void read(size_t offset, std::span< uint8_t > dst) const
Reads data from the partition with decryption if applicable.
result< void > try_write(size_t offset, std::span< const uint8_t > src)
Writes data to the partition with encryption if applicable.
void write_raw(size_t offset, const void *src, size_t size)
Writes data to the partition without encryption.
result< void > try_write_raw(size_t offset, std::span< const uint8_t > src)
Writes data to the partition without encryption.
static std::vector< partition > find_all(enum type type=type::any, enum subtype subtype=subtype::any, std::string_view label={})
Finds all partitions matching the given criteria.
result< void > try_read(size_t offset, void *dst, size_t size) const
Reads data from the partition with decryption if applicable.
type
Partition type.
Definition partition.hpp:54
@ partition_table
Partition table.
@ any
Match any partition type (for searching)
@ bootloader
Bootloader partition.
@ data
Data partition.
@ app
Application partition.
mmap_handle mmap(size_t offset, size_t size, enum mmap_memory memory=mmap_memory::data) const
Memory-maps a region of the partition.
bool encrypted() const
Returns true if the partition is encrypted.
constexpr bool operator==(const partition &) const noexcept=default
Compares two partitions for equality.
static result< partition > try_find(std::string_view label)
Finds the first partition with the given label.
subtype
Partition subtype.
Definition partition.hpp:63
@ app_ota_5
OTA application slot 5.
@ data_nvs_keys
NVS encryption keys.
@ app_ota_0
OTA application slot 0.
@ any
Match any subtype (for searching)
@ partition_table_primary
Primary partition table.
@ app_ota_14
OTA application slot 14.
@ app_ota_10
OTA application slot 10.
@ app_ota_3
OTA application slot 3.
@ app_ota_9
OTA application slot 9.
@ app_factory
Factory application.
@ data_efuse_em
eFuse emulation data
@ data_coredump
Core dump data.
@ app_ota_4
OTA application slot 4.
@ bootloader_recovery
Recovery bootloader.
@ app_ota_13
OTA application slot 13.
@ partition_table_ota
OTA partition table.
@ data_undefined
Undefined data.
@ bootloader_primary
Primary bootloader.
@ app_ota_2
OTA application slot 2.
@ app_ota_8
OTA application slot 8.
@ data_phy
PHY init data.
@ data_esphttpd
ESPHTTPD data.
@ app_ota_6
OTA application slot 6.
@ app_test
Test application.
@ app_ota_11
OTA application slot 11.
@ app_ota_1
OTA application slot 1.
@ app_ota_15
OTA application slot 15.
@ data_littlefs
LittleFS data.
@ bootloader_ota
OTA bootloader.
@ app_ota_12
OTA application slot 12.
@ data_fat
FAT filesystem data.
@ app_ota_7
OTA application slot 7.
constexpr const esp_partition_t * idf_handle() const
Returns the underlying ESP-IDF partition handle.
result< mmap_handle > try_mmap(size_t offset, size_t size, enum mmap_memory memory=mmap_memory::data) const
Memory-maps a region of the partition.
uint32_t address() const
Returns the starting address in flash.
result< void > try_write(size_t offset, const void *src, size_t size)
Writes data to the partition with encryption if applicable.
static result< partition > try_find(enum type type, enum subtype subtype=subtype::any, std::string_view label={})
Finds the first partition matching the given criteria.
enum type type() const
Returns the partition type.
void write(size_t offset, std::span< const uint8_t > src)
Writes data to the partition with encryption if applicable.
void read_raw(size_t offset, void *dst, size_t size) const
Reads data from the partition without decryption.
void read_raw(size_t offset, std::span< uint8_t > dst) const
Reads data from the partition without decryption.
std::array< uint8_t, 32 > sha256() const
Computes the SHA-256 hash of the partition contents.
bool readonly() const
Returns true if the partition is read-only.
result< std::array< uint8_t, 32 > > try_sha256() const
Computes the SHA-256 hash of the partition contents.
result< void > try_read(size_t offset, std::span< uint8_t > dst) const
Reads data from the partition with decryption if applicable.
partition & operator=(partition &&)=default
uint32_t size() const
Returns the partition size in bytes.
partition & operator=(const partition &)=default
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120
constexpr enum partition::subtype app_ota(unsigned i)
Computes an OTA app subtype from a slot index.